Spring Cloud Zuul現在對於上傳檔案有兩種處理方式,一種是用spring mvc,另一種是zuulServlet。spring mvc對檔案處理不是很好,會導致亂碼問題,zuulServlet則不會。
那麼怎麼樣讓檔案使用zuulServlet方式上傳呢?現在普遍的解決方案是給url加上 /zuul的字首,這確實是正確的,因為加了之後過濾器會使用zuulServlet。
關於過濾器的知識,下面這個連結解釋的挺詳細了
http://blog.didispace.com/spr…
在過濾器中,有一個pre的過濾器 ServletDetectionFilter,他的執行順序是-3,也是最先執行的過濾器,在這個過濾器中,有這麼一段程式碼:
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
if (!(request instanceof HttpServletRequestWrapper)
&& isDispatcherServletRequest(request)) {
ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, true);
} else {
ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, false);
}
return null;
}
在這個方法中,IS_DISPATCHER_SERVLET_REQUEST_KEY為false就會用ZuulServlet處理。如果沒加/zuul字首,IS_DISPATCHER_SERVLET_REQUEST_KEY就會置為true,就會用spring mvc上傳。會出現亂碼問題。
那麼我們的一個解決方案是在在進入下一個過濾器之前我們就把我們的檔案上傳的請求用ZuulServlet處理,所以我們可以重寫這個方法,根據contentType判斷請求如果是multipart就將IS_DISPATCHER_SERVLET_REQUEST_KEY置為false,那麼它就會用ZuulServlet處理。
到這裡還沒有結束,還有一個很坑的地方,在最後以前pre過濾器中,他會對url進行處理。如果該請求是ZuulServlet處理的,那麼他會把url的前面幾位用的zuulServletPath替代,zuulServletPath預設就是剛才我們替代的字首 /zuul。那麼如果你不處理的話,你的請求路徑將會變化。所以在這裡我們將這個預設的zuulServletPath改成空值,就不會替換啦。在配置檔案裡面加上:
zuul.servletPath:
後面的值不填。
到這裡,問題算是結束了,最後把我們重寫的那個方法注入到spring。