2016-01-19 44 views
0

首先,我知道有關於「使用Post/Redirect/Get模式保留模型狀態」的類似問題,但沒有一個具有我非常特定的問題:使用Post/Redirect保留模型狀態/獲取模式和URL重寫

背景

我的代碼是在一個企業CMS軟件,它做了很多事情工作。其中之一是URL重寫:每當我生成鏈接到我的控制器,依賴於環境,鏈接縮短 - 這是一個搜索引擎優化的事情,不能討論。

I.e.如果我的控制器URL是/webapp/servlet/myController/doSomething,則生成的URL將是/myController/doSomething。有一些我們必須使用的LinkProcessing功能。

一個Apache重寫規則會再展開這個短網址/webapp/servlet/myController/doSomething當Apache使用mod_rewrite來呼籲Tomcat上corresponsing代碼:

RewriteCond %{REQUEST_URI} ^/myController/(.*) 
RewriteRule ^/myController/(.*) /webapp/servlet/myController/$1 [PT,L] 

問題

我想使用Spring 3.1.2實現Post/Redirect/Get模式。我正在生成表單並將其張貼到控制器,該控制器驗證並使用GET重定向到成功或錯誤頁面(Post/Redirect /獲取模式)。

(高度簡化)代碼

@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; 
    } 
} 

問題IST這generateLink()方法將或者產生開始/webapp/servlet或不鏈接 - 這取決於環境/成功。這就是整個Enterprice CMS的工作原理。 (這是不能討論的​​一部分)

,另一方面工作手

春Flash的屬性在手與返回和存儲URL作爲FlashMap的部分網址:

報價從http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-flash-attributes

爲了減少此類問題發生的可能性,RedirectView會自動「戳」FlashMap實例與目標重定向URL的路徑和查詢參數。當查找「輸入」FlashMap時,默認FlashMapManager將該信息與傳入請求進行匹配。

自下一個請求(假設我有一個錯誤,返回「/ myController的/錯誤」)將擴大到/webapp/servlet/myController/error,該FlashMap將不適用這一要求,由於網址不匹配

,負責該代碼會在這裏(AbstractFlashMapManager.java:157 FF):

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; 
     } 
    } 
    // ... 
    } 

問題

你知道一種方法,我怎麼還產生,一方面短網址,但將FlashAttributes傳遞給以下GET請求?

最好的問候,並感謝您的幫助提前, 亞歷山大

回答

0

我已經找到了最好的解決方案到目前爲止是使用Interceptor通過前綴/<webappPath>/<servletPath>那些FlashMaps從RequestContextUtils.getOutputFlashMap(request)是缺少此信息更新targetRequestPathBTW:這隻能在afterCompletion方法中完成,否則在使用RedirectView時根本不會設置targetRequestPath

任何其他更好的解決方案?