假设我有一个用于编辑Pony属性的表单,在我的Web应用程序中有多个地方可供您选择编辑Pony。例如,在小马列表中,每个小马旁边可能有一个“编辑”链接,当用户正在查看小马时,该视图中可能还有一个“编辑”链接。
当用户在编辑Pony后点击“提交”时,我想将用户返回到他/她点击“编辑”链接时的页面。
如何编写控制器以将用户重定向回他们开始的位置?当然我可以通过将参数传递给控制器来做到这一点,但这似乎有点傻。我是否认为这一切都是错的,或者这就是我必须要做的事情?
答案 0 :(得分:51)
以下是如何做到男孩(注意这是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 :(得分:5)
当然,一个选项是在新窗口中打开编辑表单,因此用户所要做的就是关闭它并将它们带回原位。
我目前的应用程序中有一些地方需要做一些复杂的事情,然后将用户传递给表单,然后让它们返回起点。在这些情况下,我将起始点存储在会话中,然后再将它们关闭。对你正在做的事情来说,这可能有点过分了。
其他选项:1)您可以存储“Referer”标题并使用它,但这可能不可靠;并非所有浏览器都设置该标头。 2)在表单提交后,您可以在确认页面上使用javascript调用“history.go(-2)
”。
答案 2 :(得分:3)
我的答案与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
}
答案 3 :(得分:1)
是的我认为雅各布在新窗口中提出表格的想法可能是一个不错的选择。 或者在隐藏的div中。就像一个道场对话。 http://dojocampus.org/explorer/#Dijit_Dialog_Basic
答案 4 :(得分:1)
另一个选择是设计您的网址,以便他们揭示您正在做的事情的背景,并按照惯例,允许您“知道”操作开始的位置。
例如,您可以使用这样的网址
site/section1/pony/edit
site/section1/pony/delete
site/somewhere/else/entirely/pony/edit
site/somewhere/else/entirely/pony/delete
这两个网址都允许小马编辑和删除。要回到他们两个开始,你只需要“向上”2个文件夹。这可以通过查看当前网址的javascript函数完成,只需要上传2个文件夹,或者你可以在服务器端2上找到它,并进行类似的重定向。
答案 5 :(得分: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;
答案 6 :(得分:0)
response.sendRedirect(request.getHeader("Referer"));