簡體   English   中英

Spring-MVC 控制器重定向到“上一個”頁面?

[英]Spring-MVC controller redirect to "previous" page?

假設我有一個用於編輯 Pony 屬性的表單,在我的 Web 應用程序中有多個位置可以選擇編輯 Pony。 例如,在小馬列表中,每個小馬旁邊可能有一個“編輯”鏈接,當用戶查看小馬時,該視圖中也可能有一個“編輯”鏈接。

當用戶在編輯 Pony 后單擊“提交”時,我想將用戶返回到他或她單擊“編輯”鏈接時所在的頁面。

如何編寫我的控制器以將用戶重定向回他們開始的地方? 當然,我可以通過將參數傳遞給控制器​​來做到這一點,但這似乎有點愚蠢。 我在想這一切是錯誤的還是我必須要做的?

這是如何做到的男孩(請注意,這是 RESTful Spring 3 MVC 語法,但它可以在較舊的 Spring 控制器中使用):

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

當然,一種選擇是在新窗口中打開編輯表單,這樣用戶所要做的就是關閉它,他們就會回到原來的位置。

在我當前的應用程序中有幾個地方需要做一些復雜的事情,然后將用戶傳遞給表單,然后讓他們返回起點。 在這些情況下,我在傳遞它們之前將起點存儲在會話中。 這對於你正在做的事情來說可能有點矯枉過正。

其他選項:1)您可以存儲“Referer”標頭並使用它,但這可能不可靠; 並非所有瀏覽器都設置該標頭。 2)您可以在調用“ history.go(-2) ”的表單提交后在確認頁面上使用javascript。

我的回答與 Sam Brodkins 的相似(我也推薦過)。 但是考慮到“Referer”值可能不可用,我將此功能用於在我的控制器中使用它

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

另一種選擇是設計您的網址,以便它們顯示您正在執行的操作的上下文,並且按照慣例,可以讓您“知道”操作的開始位置。

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

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 上找到它,並進行類似的重定向。

您還可以使用攔截器跟蹤最后呈現給用戶的 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;

是的,我認為雅各布關於在新窗口中創建表單的想法可能是一個不錯的選擇。 或者在一個隱藏的 div 中。 就像一個道場對話框。 http://dojocampus.org/explorer/#Dijit_Dialog_Basic

response.sendRedirect(request.getHeader("Referer"));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM