场景
过滤器中需要对Controller中接口请求参数处理,getInputStream()方法只能调用一次,所以需要自定义HttpServletRequest
使用继承 HttpServletRequestWrapper 类的方法,读取body内容并存储,在Filter中将使用自定义的HttpServletRequestWrapper替换。
问题:
application/json格式没有问题,form-data的时候,使用@RequestParam获取的参数会提示 参数xx不存在
解决
form-data解析参数时,会判断有没有调用过getInputStream, 如果先调用了不会再重复获取。
在包装类中,调用getInputStream之前调用一下request.getParameterMap(); 会先解析body内容并将处理结果缓存起来,再调用自己的getInputStream方法
伪代码如下:
public class MockHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final byte[] body;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
// 不用存储结果
request.getParameterMap();
// form-data时, 返回空字符串, 如果使用时需处理
body = StreamUtils.copyToByteArray(request.getInputStream());
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream in = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return in.read();
}
@Override
public boolean isFinished() {
try {
return bais.available() == 0;
} catch (Exception e) {
// log here
}
return false;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
}
end
写法有误call call call 我