当项目上用了 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":""
}