【发布时间】:2016-01-19 16:50:59
【问题描述】:
首先,我知道关于“使用 Post/Redirect/Get 模式保留模型状态”有类似的问题,但这些都没有我非常具体的问题:
背景:
我的代码在企业 CMS 软件中运行,该软件可以做很多事情。其中之一是 URL 重写:每当我生成指向控制器的链接时,取决于环境,链接会缩短 - 这是 SEO 的事情,无法讨论。
即如果我的控制器 URL 是 /webapp/servlet/myController/doSomething,则生成的 URL 将是 /myController/doSomething。我们必须使用一些 LinkProcessing 功能。
当apache使用mod_rewrite调用tomcat上的对应代码时,apache重写规则会将这个短url扩展为/webapp/servlet/myController/doSomething:
RewriteCond %{REQUEST_URI} ^/myController/(.*)
RewriteRule ^/myController/(.*) /webapp/servlet/myController/$1 [PT,L]
问题:
我正在尝试使用 Spring 3.1.2 实现 Post/Redirect/Get 模式。我正在生成一个表单并将其发布到控制器,控制器使用 GET 验证并重定向到成功或错误页面(Post/Redirect/Get 模式)。
(高度简化)代码:
@RequestMapping()
public class MyController {
@RequestMapping(value = "/doDispatch", method = RequestMethod.POST)
public RedirectView handleDispatch(RedirectAttributes redirectAttributes,
@Validated @ModelAttribute FormBean formBean,
BindingResult binding) {
if (binding.hasErrors()) {
redirectAttributes.addFlashAttribute(formBean);
redirectAttributes.addFlashAttribute(BindingResult.MODEL_KEY_PREFIX+"formBean", binding);
return new RedirectView(generateLink("/error"));
} else {
redirectAttributes.addFlashAttribute(formBean);
redirectAttributes.addFlashAttribute(BindingResult.MODEL_KEY_PREFIX+"formBean", binding);
return new RedirectView(generateLink("/success"));
}
}
@RequestMapping(value = "/success")
public ModelAndView handleSuccess(@ModelAttribute FormBean formBean) {
// do stuff (save things in the DB)
// ...
final ModelAndView modelAndView = createModelAndView(formBean);
modelAndView.addObject("success", true);
return modelAndView;
}
@RequestMapping(value = "/error")
public ModelAndView handleError(@Validated @ModelAttribute FormBean formBean,
BindingResult binding) {
final ModelAndView modelAndView = createModelAndView(formBean);
modelAndView.addObject("binding", binding);
modelAndView.addObject("formBean", formBean);
return modelAndView;
}
}
问题在于此 generateLink() 方法将生成以/webapp/servlet 开头的链接或不生成链接 - 取决于环境/成功。这就是整个 Enterprice CMS 的运作方式。 (这是不能讨论的部分)
另一方面,Spring Flash-Attributes 与返回的 URL 协同工作,并将 URL 存储为 FlashMap 的一部分:
为减少出现此类问题的可能性,
RedirectView自动使用目标重定向 URL 的路径和查询参数“标记”FlashMap实例。反过来,在查找“输入”FlashMap时,默认的FlashMapManager会将该信息与传入的请求相匹配。
由于下一个请求(假设我遇到错误并返回“/myController/error”)将扩展为/webapp/servlet/myController/error,因此 FlashMap 将不适用于此请求,因为 URL 不匹配。
负责的代码是这里(AbstractFlashMapManager.java:157ff):
protected boolean isFlashMapForRequest(FlashMap flashMap, HttpServletRequest request) {
if (flashMap.getTargetRequestPath() != null) {
String requestUri = this.urlPathHelper.getOriginatingRequestUri(request);
if (!requestUri.equals(flashMap.getTargetRequestPath())
&& !requestUri.equals(flashMap.getTargetRequestPath() + "/")) {
return false;
}
}
// ...
}
问题:
您知道一方面我仍然可以生成短 URL,但将 FlashAttributes 传递给以下 GET 请求的方法吗?
最好的问候和提前感谢您的帮助, 亚历山大
【问题讨论】:
标签: java spring spring-mvc mod-rewrite post-redirect-get