request.getInputStream()只能调用一次解决
request.getInputStream()只能调用一次解决
起因:业务需要拦截器进行签名校验,拦截器中获取参数之后,导致@RequestBody注解报错(因为request.getInputStream()调用一次后失效)导致异常。这样就会导致controller 无法拿到数据。
解决方案
自定义一个类 BodyReaderHttpServletRequestWrapper.java
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
//用于将流保存下来
private byte[] requestBody = null;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
requestBody = StreamUtils.copyToByteArray(request.getInputStream());
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
自定义 Filter 继承Filter
@WebFilter(filterName = "requestFilter", urlPatterns = "/*")
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 BodyReaderHttpServletRequestWrapper((HttpServletRequest) request);
}
if (requestWrapper == null) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
}
}
@Override
public void destroy() {
}
}
启动类上增加注解
@ServletComponentScan("com.**.filter")

浙公网安备 33010602011771号