例如filter中获取一次请求以后body,我们在controller想再次获取请求body。request.getInputStream()返回的是ServletInputStream,此方法没有实现流的mark/reset方法,我们在filter中读取以后无法对流进行复位
*BodyReaderHttpServletRequestWrapper .java
代码实现如下:
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] body;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
try {
body = StreamUtils.getByteByStream(request.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return bais.read();
}
};
}
}
public class StreamUtils {
public static byte[] getByteByStream(InputStream is) throws Exception {
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = is.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.flush();
return bos.toByteArray();
}
}
public class MyFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) arg0;
ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
//测试在filter中获取一次
InputStream is = requestWrapper.getInputStream();
String body = IOUtils.toString(inp);
// 关闭文件输入流
is.close();
// 关闭输出流
out.close();
chain.doFilter(requestWrapper, response);
}
public void init(FilterConfig arg0) throws ServletException {
}
}
@RequestMapping(value="/test",method=RequestMethod.POST) public void downloadsql(HttpServletRequest request, HttpServletResponse response){
//正常使用即可
}
public class PreRequest extends ZuulFilter {
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return FORM_BODY_WRAPPER_FILTER_ORDER +1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext.getCurrentContext().setRequest(new BodyReaderHttpServletRequestWrapper( RequestContext.getCurrentContext().getRequest()) );
return null;
}
}