Spring-MVC控制器重定向到“上一页”?

假设我有一个用于编辑Pony属性的表单,在我的Web应用程序中,有多个地方可以选择编辑Pony。 例如,在Ponies列表中,每个Pony旁边可能有一个“编辑”链接,当用户正在查看Pony时,该视图中可能还有一个“编辑”链接。

当用户在编辑Pony后单击“提交”时,我想将用户返回到他或她在单击“编辑”链接时所在的页面。

如何编写控制器以将用户重定向回到他们开始的位置? 当然我可以通过将参数传递给控制器​​来做到这一点,但这似乎有点傻。 我是否认为这一切都错了,或者我真的要做什么呢?

当然,一个选项是在新窗口中打开编辑表单,因此用户所要做的就是关闭它,然后它们就会回到原来的位置。

在我当前的应用程序中有一些地方我需要做一些复杂的事情,然后将用户传递给表单,然后让它们返回到起点。 在这些情况下,我将起始点存储在会话中,然后再将它们关闭。 对你正在做的事情来说,这可能有些过分。

其他选项:1)您可以存储“Referer”标头并使用它,但这可能不可靠; 并非所有浏览器都设置该标头。 2)在表单提交后,您可以在确认页面上使用javascript调用“ history.go(-2) ”。

这是如何做到男孩(注意这是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; } 

我的答案与Sam Brodkins的答案相似(我也推荐它)。 但是,如果计算出“Referer”值可能不可用,我将此function用于我的控制器中

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

是的,我认为Jacob在新窗口中对表单的想法可能是一个不错的选择。 或者在隐藏的div中。 就像一个道场对话。 http://dojocampus.org/explorer/#Dijit_Dialog_Basic

另一个选择是设计你的url,以便他们揭示你正在做的事情的背景,并按照惯例,允许你“知道”操作开始的位置。

例如,您可以拥有这样的url

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

这两个url都允许小马编辑和删除。 要回到他们两个开始,你只需要“向上”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配置:

      

然后使用以下代码返回控制器中的该视图:

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