2009-04-29 137 views
19

假設我已經有了一張表格來編輯小馬的屬性,並且在我的web應用程序中有多個可以選擇編輯小馬的地方。例如,在小馬的列表中,每個小馬旁邊可能存在「編輯」鏈接,並且當用戶正在查看小馬時,在該視圖中可能還存在「編輯」鏈接。Spring-MVC控制器重定向到「上一頁」?

當用戶在編輯小馬後點擊「提交」,我想將用戶返回到他或她點擊「編輯」鏈接時的頁面。

如何編寫我的控制器以將用戶重定向到他們開始的位置?當然,我可以通過向控制器傳遞一個參數來做到這一點,但這似乎有點愚蠢。我是在想這些都是錯誤的還是我所要做的事情?

回答

4

當然,一個選擇是在新窗口中打開編輯窗體,因此用戶所要做的就是關閉它,然後它們又回到原來的位置。

在我當前的應用程序中有幾個地方需要做一些複雜的事情,然後將用戶傳遞給表單,然後讓它們返回到起點。在這些情況下,我將會話的起點存儲在會話中,然後再將它們傳遞出去。這可能矯枉過正,你在做什麼。

其他選項:1)您可以存儲「Referer」標題並使用它,但這可能不可靠;並非所有瀏覽器都設置了該標題。 2)在表單提交後,您可以在確認頁上使用JavaScript,名爲「history.go(-2)」。

43

這裏是如何做到這一點的男孩(請注意,這是REST風格的春季3 MVC的語法,但它會在老年春控制器工作):

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

絕對酷但可能不可靠:http://en.wikipedia.org/wiki/HTTP_referrer#Referrer_hiding – wheleph 2011-10-06 18:32:33

+6

如果在編輯小馬時出現驗證錯誤,並且用戶返回到編輯小馬頁,這將不起作用。因爲現在引用者將指向編輯小馬頁面。 – priomsrb 2013-03-11 22:13:23

1

另外一個選擇是讓他們露出來設計你的網址你正在做什麼以及按照慣例的上下文可以讓你「知道」操作開始的位置。

例如,你可以有網址,像這樣

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

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

這兩個網址,讓小馬編輯和刪除。要回到他們倆的開始,你只需要「上」2個文件夾。這可以通過查看當前url的javascript函數完成,並且只需要上傳2個文件夾,或者您可以在服務器端2找出它,然後重做這樣的重定向。

1

您還可以跟蹤最後通過攔截器呈現給用戶的ModelAndView(或只是視圖)。此示例只跟蹤最後一個模型和視圖,但您可以使用列表導航回更多級別。

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

} 

使用Spring XML配置:

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

然後用下面的代碼回到該視圖控制器中的:

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

我的回答是一樣山姆Brodkins' (我也推薦它)。但具有計數的「引薦」值可能不可用我做了這個功能,使用它在我的控制器

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

所以在您的控制器調用函數,你應該返回是這樣的:

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