2009-04-29 13 views
19

Diciamo che ho un modulo per modificare le proprietà di un Pony e nella mia applicazione web ci sono più posti in cui è possibile scegliere di modificare un Pony. Ad esempio, in un elenco di pony potrebbe esserci un link "modifica" accanto a ciascun pony, e quando l'utente sta visualizzando un pony, potrebbe esserci anche un link "modifica" in quella vista.Il controller Spring-MVC reindirizza alla pagina "precedente"?

Quando un utente clicca su "invia" dopo la modifica di un pony, vorrei tornare l'utente alla pagina che lui o lei era quando si fa clic sul link "modifica".

Come faccio a scrivere il mio controller per reindirizzare l'utente torna sui propri passi? Certamente posso farlo passando un parametro al controller, ma sembra un po 'sciocco. Sto pensando a tutto ciò che è sbagliato o è più o meno quello che dovrò fare?

risposta

4

Una possibilità, naturalmente, sarebbe quello di aprire il modulo di modifica in una nuova finestra, quindi l'utente deve fare è vicino e sono tornati dove erano.

Ci sono alcuni posti in mia domanda attuale, in cui ho bisogno di fare qualcosa di complicato, quindi passare l'utente a un modulo e quindi li hanno tornare al punto di partenza. In questi casi, memorizzo il punto di partenza nella sessione prima di passarli fuori. Probabilmente è eccessivo per quello che stai facendo.

Altre opzioni: 1) è possibile memorizzare l'intestazione "referer" e l'uso che, ma che potrebbe non essere affidabile; non tutti i browser impostano quell'intestazione. 2) potresti avere javascript sulla pagina di conferma dopo l'invio del modulo che chiama "history.go(-2)".

43

Ecco come farlo ragazzi (Nota: questo è RESTful Spring 3 sintassi MVC, ma lavorerà in controllori di primavera più anziani):

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

Assolutamente bello, ma potrebbe non essere affidabile: http://en.wikipedia.org/wiki/HTTP_referrer#Referrer_hiding – wheleph

+6

Questo non funzionerà se c'è stato un errore di convalida durante la modifica del pony e l'utente è tornato alla pagina di modifica del pony. Perché ora il referente indicherà la pagina di modifica del pony. – priomsrb

1

un altra opzione sarebbe quella di progettare gli URL in modo che rivelano la contesto di quello che stai facendo, e per convenzione, ti permetterebbe di "sapere" dove si trovava l'inizio di un'operazione.

Ad esempio, si potrebbe avere gli URL in questo modo

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

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

entrambi tali URL consentire la modifica e la cancellazione di pony. Per tornare all'inizio per entrambi, devi semplicemente "salire" 2 cartelle. Questo può essere fatto tramite una funzione javascript che guarda l'url corrente, e sale solo su 2 cartelle, o potresti calcolarlo sul lato server 2, e fare un reindirizzamento come quello.

+0

Questa soluzione non è di tornare indietro alla pagina precedente ma ottima per il flusso del sito. – Hlex

1

È inoltre possibile tenere traccia del ModelAndView (o solo la vista) che sono stati lo scorso presentati all'utente con un intercettore. Questo esempio tiene traccia solo dell'ultimo modello e della vista, ma è possibile utilizzare un elenco per tornare indietro di più livelli.

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 configurazione XML Primavera:

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

e quindi utilizzare il seguente codice per tornare a quella vista in un controllore:

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

La mia risposta è simile a Sam Brodkins' s (lo raccomandavo anche).Ma avere nel conteggio che il valore "Referer" potrebbe non essere disponibile ho fatto questa funzione per usarla nei miei controllori

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

Quindi nel tuo funzione di regolatore del chiamante si dovrebbe restituire qualcosa del genere:

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