2009-04-29 4 views
19

Disons que j'ai un formulaire pour éditer les propriétés d'un poney, et dans mon application web il y a plusieurs endroits où vous pouvez choisir d'éditer un poney. Par exemple, dans une liste de poneys, il peut y avoir un lien «modifier» à côté de chaque poney, et lorsque l'utilisateur consulte un poney, il peut également y avoir un lien «modifier» dans cette vue.Le contrôleur Spring-MVC redirige vers la page "précédente"?

Lorsqu'un utilisateur clique sur "envoyer" après avoir modifié un poney, je voudrais retourner l'utilisateur à la page qu'il ou elle était en cliquant sur le lien "modifier".

Comment écrire mon contrôleur pour rediriger l'utilisateur vers l'endroit où il a démarré? Certes, je peux le faire en passant un paramètre au contrôleur, mais cela semble un peu loufoque. Suis-je en train de penser à tout faux ou est-ce à peu près ce que je vais devoir faire?

Répondre

4

Une option, bien sûr, serait d'ouvrir le formulaire d'édition dans une nouvelle fenêtre, donc tout ce que l'utilisateur a à faire est de le fermer et ils sont de retour là où ils se trouvaient.

Il ya quelques endroits dans mon application actuelle où je dois faire quelque chose de compliqué, puis passer l'utilisateur à un formulaire, puis les faire revenir au point de départ. Dans ces cas, je stocke le point de départ dans la session avant de les transmettre. C'est probablement exagéré pour ce que vous faites.

Autres options: 1) vous pouvez stocker l'en-tête "Referer" et l'utiliser, mais cela peut ne pas être fiable; tous les navigateurs ne définissent pas cet en-tête. 2) vous pouvez avoir javascript sur la page de confirmation après la soumission du formulaire qui appelle "history.go(-2)".

43

Voici comment faire les garçons (Notez ceci est RESTful Spring 3 syntaxe MVC mais il fonctionnera dans les anciens contrôleurs de printemps)

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

Absolument cool mais peut-être pas fiable: http://en.wikipedia.org/wiki/HTTP_referrer#Referrer_hiding – wheleph

+6

Cela ne fonctionnera pas s'il y avait une erreur de validation lors de la modification du poney et l'utilisateur est retourné à la page d'édition poney. Parce que maintenant le referer pointera vers la page d'édition poney. – priomsrb

1

une autre option serait de concevoir vos urls afin qu'ils révèlent la contexte de ce que vous faites, et par convention, vous permettrait de «savoir» où le début d'une opération était.

Par exemple, vous pourriez avoir urls comme si

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

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

Ces deux urls permettent le montage de poney et la suppression. Pour revenir au début pour les deux, vous deviez simplement "monter" 2 dossiers. Cela pourrait être fait via une fonction javascript qui regarde l'URL actuelle, et monte seulement 2 dossiers, ou vous pouvez le comprendre sur le côté serveur 2, et faire une redirection comme ça aussi bien.

+0

Cette solution n'est pas de retourner à la page précédente mais bien pour le flux du site. – Hlex

1

Vous pouvez également garder une trace du ModelAndView (ou simplement de la vue) qui a été présenté à l'utilisateur avec un intercepteur. Cet exemple conserve uniquement le dernier modèle et la dernière vue, mais vous pouvez utiliser une liste pour revenir à plusieurs niveaux.

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); 
    } 

} 

Avec configuration XML Spring:

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

Et puis utilisez le code suivant pour revenir à ce point de vue dans un contrôleur:

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

Ma réponse est semblable à Sam Brodkins' s (je l'ai recommandé aussi).Mais ayant en nombre que la valeur « Referer » peut ne pas être disponible je l'ai fait cette fonction pour l'utiliser dans mes contrôleurs

/** 
* 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); 
} 

Donc, dans votre fonction de l'appelant contrôleur, vous devez retourner quelque chose comme ceci:

@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 
} 
Questions connexes