2009-04-29 47 views
19

Digamos que tengo un formulario para editar las propiedades de un Pony, y en mi aplicación web hay varios lugares donde puede elegir editar un Pony. Por ejemplo, en una lista de Potros puede haber un enlace de "edición" al lado de cada Pony, y cuando el usuario está viendo un Pony, también puede haber un enlace de "edición" en esa vista.¿El controlador Spring-MVC redirige a la página "anterior"?

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

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

Respuesta

4

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 donde estaban.

Hay algunos lugares en mi aplicación actual en los que necesito hacer algo complicado, paso el usuario a un formulario y luego los devuelvo al punto de partida. En esos casos, almaceno el punto de inicio en la sesión antes de pasarlos. Eso es probablemente demasiado para lo que estás haciendo.

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

43

Aquí es cómo hacerlo chicos (Tenga en cuenta que esto es primavera REST 3 sintaxis MVC pero funcionará en los controladores de la primavera de edad avanzada):

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

Absolutamente genial, pero puede no ser confiable: http://en.wikipedia.org/wiki/HTTP_referrer#Referrer_hiding – wheleph

+6

Esto no funcionará si hubo un error de validación al editar el pony y el usuario regresa a la página de edición de pony. Porque ahora el referer apuntará a la página Editar pony. – priomsrb

1

otra opción sería diseñar sus URL para que revelan la El contexto de lo que está haciendo, y por convención, le permitiría "saber" dónde estaba el inicio de una operación.

Por ejemplo, usted podría tener URLs como así

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

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

tanto las direcciones URL permiten la edición de caballo y eliminar. Para volver al inicio para ambos, simplemente ir a "subir" 2 carpetas. Esto se puede hacer a través de una función de JavaScript que mira la url actual, y solo sube 2 carpetas, o puede averiguarlo en el lado del servidor 2, y hacer un redireccionamiento de esa manera también.

+0

Esta solución no es para volver a la página anterior, pero es excelente para el flujo del sitio. – Hlex

1

También puede realizar un seguimiento de ModelAndView (o simplemente la vista) que se han presentado por última vez al usuario con un interceptor. Este ejemplo realiza un seguimiento de solo el último modelo y 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 a continuación, utilizar el código siguiente para volver a ese punto de vista en un controlador:

ModelAndView mv = (ModelAndView)request.getSession().getAttribute(LastModelAndViewInterceptor.LAST_MODEL_VIEW_ATTRIBUTE); 
return mv; 
1

Mi respuesta es igual a Sam Brodkins' s (lo recomendé también).Sin embargo, tener en cuenta de que el valor "Referer" puede no estar disponible hice esta función para utilizarla 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); 
} 

Así que en su función de controlador de llamada debe 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 
} 
Cuestiones relacionadas