当项目上用了 request.getInputStream以流的方式读取请求,而实际项目中通常会用到一些拦截器,作一些校验,发现只能读取一次,真正到Controller里,发现是不能用的。前端
好比,前端请求时以json方式提交 ,后台用用@RequestBody或者用流 作json到对象的解析,这时这个json串里有个参数要放在拦截器里校验一下java
在拦截器里以流的形式读取了,后台这就取不到参数spring
解决办法,网上好多人是加了个过滤器,把请求包装一下,apache
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获取参数json
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":""
}
app