request.getInputStream以流的方式讀取請求只能讀取一次
阿新 • • 發佈:2018-12-07
當專案上用了 request.getInputStream以流的方式讀取請求,而實際專案中一般會用到一些攔截器,做一些校驗,發現只能讀取一次,真正到Controller裡,發現是不能用的。
比如,前端請求時以json方式提交 ,後臺用用@RequestBody或者用流 做json到物件的解析,這時這個json串裡有個引數要放在攔截器裡校驗一下
在攔截器裡以流的形式讀取了,後臺這就取不到引數
解決辦法,網上好多人是加了個過濾器,把請求包裝一下,
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; public class RequestFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ServletRequest requestWrapper = null; if (request instanceof HttpServletRequest) { requestWrapper = new SdHttpServletWrapper((HttpServletRequest) request); } if (null == requestWrapper) { chain.doFilter(request, response); } else { chain.doFilter(requestWrapper, response); } } @Override public void destroy() { } }
import org.apache.commons.lang.StringUtils; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.Charset; public class SdHttpServletWrapper extends HttpServletRequestWrapper { private final byte[] body; public SdHttpServletWrapper(HttpServletRequest request) throws IOException { super(request); body = readBytes(request.getReader(), "utf-8"); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } }; } /** * 通過BufferedReader和字元編碼集轉換成byte陣列 * * @param br * @param encoding * @return * @throws IOException */ private byte[] readBytes(BufferedReader br, String encoding) throws IOException { String str = null, retStr = ""; while ((str = br.readLine()) != null) { retStr += str; } if (StringUtils.isNotBlank(retStr)) { return retStr.getBytes(Charset.forName(encoding)); } return null; } }
<filter> <filter-name>springFilter</filter-name> <filter-class> com.XXXXX.RequestFilter</filter-class> </filter> <filter-mapping> <filter-name>springFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
還有一種辦法就是前端請求時,把要校驗的引數,拼到url後面,這樣後臺這可以同時用@RequestBody 和request.getparametere獲取引數
POST /srs/manage/sysparam/query?token=dsfdsfsdfsdfs HTTP/1.1
Host: srs.xxx.com
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: a52c36d2-d42d-4fc5-3132-8ad03dd65a08
{"classCode":"srs.txn.type",
"code":"P",
"name":""
}