El controlador Spring-MVC redirige a & # 8220; anterior & # 8221; ¿página?

StackOverflow https://stackoverflow.com/questions/804581

  •  03-07-2019
  •  | 
  •  

Pregunta

Digamos que tengo un formulario para editar las propiedades de un Pony, y en mi aplicación web hay varios lugares donde puedes elegir editar un Pony. Por ejemplo, en una lista de ponis podría haber una " editar " enlace al lado de cada Pony, y cuando el usuario está viendo un Pony, también puede haber una " editar " enlace en esa vista.

Cuando un usuario hace clic en " enviar " después de editar un Pony, me gustaría devolver al usuario a la página que tenía cuando hizo clic en " editar " enlace.

¿Cómo escribo mi controlador para redirigir al usuario a donde comenzaron? Ciertamente, puedo hacer esto pasando un parámetro al controlador, pero eso parece un poco tonto. ¿Estoy pensando en todo esto mal o es más o menos lo que tendré que hacer?

¿Fue útil?

Solución

Una opción, por supuesto, sería abrir el formulario de edición en una nueva ventana, por lo que todo lo que el usuario tiene que hacer es cerrarlo y volver a estar donde estaban.

Hay algunos lugares en mi aplicación actual en los que necesito hacer algo complicado, luego pasar al usuario a un formulario y luego hacer que vuelvan al punto de inicio. En esos casos, almaceno el punto de inicio en la sesión antes de pasarlos. Probablemente eso sea excesivo por lo que estás haciendo.

Otras opciones: 1) puede almacenar el " Referer " Encabezar y usar eso, pero eso puede no ser confiable; no todos los navegadores establecen ese encabezado. 2) podría tener javascript en la página de confirmación después del envío del formulario que llama a " history.go (-2) " ;.

Otros consejos

Aquí se explica cómo hacerlo, muchachos (tenga en cuenta que esta es la sintaxis de RESTful Spring 3 MVC, pero funcionará en los controladores Spring más antiguos):

@RequestMapping(value = "/rate", method = RequestMethod.POST)
public String rateHandler(HttpServletRequest request) {
    //your controller code
    String referer = request.getHeader("Referer");
    return "redirect:"+ referer;
}

Mi respuesta es similar a la de Sam Brodkins (también lo recomendé). Pero teniendo en cuenta que el " Referente " el valor puede no estar disponible. Hice esta función para usarla en mis controladores

/**
* Returns the viewName to return for coming back to the sender url
*
* @param request Instance of {@link HttpServletRequest} or use an injected instance
* @return Optional with the view name. Recomended to use an alternativa url with
* {@link Optional#orElse(java.lang.Object)}
*/
protected Optional<String> getPreviousPageByRequest(HttpServletRequest request)
{
   return Optional.ofNullable(request.getHeader("Referer")).map(requestUrl -> "redirect:" + requestUrl);
}

Entonces, en la función de llamador de tu controlador, deberías devolver algo como esto:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody
String testRedirection(HttpServletRequest request)
{
      //Logic....
      //Returns to the sender url
      return getPreviousPageByRequest(request).orElse("/"); //else go to home page
}

Sí, creo que la idea de Jacob para el formulario en una nueva ventana puede ser una buena opción. O en un div oculto. Como un diálogo de dojo. http://dojocampus.org/explorer/#Dijit_Dialog_Basic

otra opción sería diseñar tus URL para que revelen el contexto de lo que estás haciendo y, por convención, te permitiría " saber " donde estaba el inicio de una operación.

Por ejemplo, podría tener urls así

site/section1/pony/edit
site/section1/pony/delete

site/somewhere/else/entirely/pony/edit
site/somewhere/else/entirely/pony/delete

ambas direcciones URL permiten editar y eliminar pony. Para volver al inicio para ambos, simplemente subes " arriba " 2 carpetas. Esto se puede hacer a través de una función javascript que mira la url actual, y solo sube 2 carpetas, o puede descifrarlo en el lado del servidor 2, y hacer una redirección como esa también.

También puede realizar un seguimiento del ModelAndView (o solo la vista) que se presentó por última vez al usuario con un interceptor. Este ejemplo solo hace un seguimiento del último modelo y la vista, pero puede usar una lista para navegar más niveles.

package com.sample;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LastModelAndViewInterceptor extends HandlerInterceptorAdapter {

    public static final String LAST_MODEL_VIEW_ATTRIBUTE = LastModelAndViewInterceptor.class.getName() + ".lastModelAndView";

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        request.getSession(true).setAttribute(LAST_MODEL_VIEW_ATTRIBUTE, modelAndView);
        super.postHandle(request, response, handler, modelAndView);
    }

}

Con la configuración XML de Spring:

<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
        <bean class="com.sample.LastModelAndViewInterceptor"/>
    </property>
</bean>

Y luego use el siguiente código para volver a esa vista en un controlador:

ModelAndView mv = (ModelAndView)request.getSession().getAttribute(LastModelAndViewInterceptor.LAST_MODEL_VIEW_ATTRIBUTE);
return mv;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top