本文 隻講使用不過多闡述原理(因為我也沒太深究),希望有熟知原理的朋友不吝分享 下面開始。
------------------------------------------------------------------------------ 無聊的前言 但是還是得說 ------------------------------------------------------------------------------------------------------------------------
前端時間處理上傳檔案時遇到了一些問題 multipart/form-data 方式送出的請求 在無法用Filter 中用 ServletRequest.getParameter 方法取不到一并送出上來的 參數,網上說 需要使用 ServletRequest.getReader() 方法 來擷取請求資訊(RequestPayload), 然後在解析字元串來擷取想要的參數。 但是! ServletRequest.getReader() 隻能擷取一次,如果在攔截其中 取出了requestPayload ,那麼在spring的 controller 中 你将取不到參數和檔案了!!!!!
摸索到了這裡我發現這是走了彎路, 既然 springMVC 的接口中可以擷取到 參數,那說明 spring 已經很好的解決了這個問題 咱們就不要自己造輪子了;
!!!!!!!!!!幹貨來了
通過檢視mvc的源碼 果然 發現了兩個類,
1.1.實作了、 ServletRequest的 org.springframework.web.multipart.MultipartHttpServletRequest.java 類 (這個類的 getParameter 方法可以擷取到 multipart/form-data 和 非multipart/form-data 方法上傳的 參數)
1.2.用于建立 MultipartHttpServletRequest.java 的 org.springframework.web.multipart.MultipartResolver.java 類
使用方法
2.1 首先在你的spring配置檔案中 配置 MultipartHttpServletRequest
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
p:defaultEncoding="UTF-8">
<property name="maxUploadSize">
<value>104857600</value>
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
</bean>
2.2 在你的攔截其中 注入 MultipartHttpServletRequest
// 用于建立MultipartHttpServletRequest
private MultipartResolver multipartResolver = null;
@Override
public void init(FilterConfig arg0) throws ServletException {
// 注入bean
multipartResolver = ((MultipartResolver)ApplicationContextUtil.getContext().getBean("multipartResolver", MultipartResolver.class));
}
2.3 在你的最頂層的 攔截器中 把你的 ServletRequest 替換成 MultipartHttpServletRequest
/**
* 擷取 request
* @param req
* @return
*/
private ServletRequest getRequest(ServletRequest req){
String enctype = req.getContentType();
if (StringUtils.isNotBlank(enctype) && enctype.contains("multipart/form-data"))
// 傳回 MultipartHttpServletRequest 用于擷取 multipart/form-data 方式送出的請求中 上傳的參數
return multipartResolver.resolveMultipart((HttpServletRequest) req);
else
return req;
}
2.4 把 用上面 2.3的 getRequest(req) 擷取到的 MultipartHttpServletRequest 交給 chain.doFilter(MultipartHttpServletRequest, resp); 讓請求繼續執行。 之後的所有攔截器和controller都能繼續get參數了
2.5 沒了