2009-04-29 18 views
19

Angenommen, ich habe ein Formular zum Bearbeiten der Eigenschaften eines Pony, und in meiner Webanwendung gibt es mehrere Orte, an denen Sie ein Pony bearbeiten können. Zum Beispiel könnte es in einer Liste von Ponys einen "Edit" -Link neben jedem Pony geben, und wenn der Benutzer ein Pony anzeigt, könnte es auch einen "Edit" -Link in dieser Ansicht geben.Spring-MVC Controller Redirect auf "vorherige" Seite?

Wenn ein Benutzer nach dem Bearbeiten eines Ponys auf "Senden" klickt, möchte ich den Benutzer auf die Seite zurückversetzen, die er oder sie war, als er auf den Link "Bearbeiten" klickte.

Wie schreibe ich meinen Controller, um den Benutzer dorthin zurückzuleiten, wo er angefangen hat? Natürlich kann ich dies tun, indem ich einen Parameter an den Controller übergebe, aber das scheint etwas albern zu sein. Denke ich darüber alles falsch oder ist das ziemlich viel, was ich tun muss?

Antwort

4

Eine Option wäre natürlich, das Bearbeitungsformular in einem neuen Fenster zu öffnen, so dass der Benutzer es nur schließen muss und sie wieder da sind, wo sie waren.

Es gibt ein paar Stellen in meiner aktuellen Anwendung, wo ich etwas kompliziertes tun muss, dann übergeben Sie den Benutzer an ein Formular, und dann müssen sie zum Ausgangspunkt zurückkehren. In diesen Fällen speichere ich den Startpunkt in der Sitzung, bevor ich sie ablege. Das ist wahrscheinlich zu viel für das, was du tust.

Andere Optionen: 1) Sie können die "Referer" Header speichern und verwenden, aber das kann nicht zuverlässig sein; nicht alle Browser setzen diese Überschrift. 2) Sie könnten Javascript auf der Bestätigungsseite nach der Formularübermittlung haben, die "history.go(-2)" aufruft.

43

Hier ist, wie es Jungen tun (Hinweis: Dies ist RESTful Frühling 3 MVC-Syntax, aber es wird in älteren Frühjahr Controller arbeiten):

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

Absolut cool, aber möglicherweise nicht zuverlässig: http://en.wikipedia.org/wiki/HTTP_referrer#Referrer_hiding – wheleph

+6

Dies funktioniert nicht, wenn beim Bearbeiten des Ponys ein Validierungsfehler aufgetreten ist und der Benutzer auf die Bearbeiten-Pony-Seite zurückkehrt. Denn jetzt zeigt der Referer auf die Edit-Pony-Seite. – priomsrb

1

eine andere Option wäre Ihre Urls zu gestalten, so dass sie die Laibung Kontext dessen, was Sie tun, und durch Konvention, würde Ihnen erlauben zu wissen, wo der Beginn einer Operation war.

Zum Beispiel könnten Sie Urls haben wie so

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

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

beide URLS Pony Bearbeiten und Löschen ermöglichen. Um für beide zurück zum Start zu gehen, gehen Sie einfach zwei Ordner hoch. Dies könnte über eine Javascript-Funktion geschehen, die die aktuelle URL betrachtet, und geht einfach um 2 Ordner, oder Sie könnten es auf der Server-Seite 2 herausfinden, und tun Sie eine Redirect wie diese auch.

+0

Diese Lösung besteht nicht darin, auf die vorherige Seite zurückzugehen, sondern für den Site-Flow. – Hlex

1

Sie können auch die ModelAndView (oder nur die Ansicht) verfolgen, die dem Benutzer zuletzt mit einem Interzeptor angezeigt wurde. In diesem Beispiel werden nur das letzte Modell und die letzte Ansicht verfolgt. Sie können jedoch eine Liste verwenden, um mehr Ebenen zurück zu navigieren.

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

} 

Mit Spring-XML-Konfiguration:

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

Und dann den folgenden Code verwenden in einem Controller zu dieser Ansicht zu kommen:

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

Meine Antwort ist ähnlich zu Sam Brodkins' s (ich empfahl es auch).Aber in Zahl aufweist, die der „Referer“ Wert möglicherweise nicht zur Verfügung ich diese Funktion gemacht, es zu benutzen in meinem Controller

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

So in Ihrer Controller CLIP-Funktion sollten Sie etwas wie folgt zurück:

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