假设我有一个用于编辑 Pony 属性的表单,并且在我的 Web 应用程序中,有多个位置可以选择编辑 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;
}

我的回答与萨姆·布罗德金斯的回答相似(我也推荐了它)。但考虑到“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
}

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

另一种选择是设计您的网址,以便它们揭示您正在做的事情的上下文,并且按照惯例,可以让您“知道”操作的开始位置。

例如,您可以有这样的网址

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

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

这两个网址都允许小马编辑和删除。要返回到这两个文件夹的开头,您只需“向上”2 个文件夹即可。这可以通过一个 JavaScript 函数来完成,该函数查看当前的 url,然后只向上移动 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;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top