项目上因为有需要需要在拦截器里面获取请求体里面的数据进行数据验证,因为自己定义的controller里面对使用了@RequestBody注解,导致项目报错了报错的内容是:java.lang.IllegalStateException: getReader() has already been called for this request,查阅资料发现request里面的的getReader 和getInputStream因为是以流的方式获取的,读取一次后,后续就不能再用了,解决思路是:,第一步:定义一个过滤器,过滤器里面传入自己定义的request,自己定义的request要继承HttpServletRequestWrapper这个包装类,并重写里面的getInputStream和getReader方法,
@RequestMapping(value = "/test", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") public Result detail(@RequestBody JSONObject json) { String ip = json.getString("ip"); System.out.println("ip="+ip); Camera camera=new Camera(); camera.setCameraId("xxx"); camera.setCameraUrl("rtmp://xxx.com/tocc-demo/11020400001310214877?auth_key=1608275482-0-0-26e08c0032607786eeb16acd96cef398"); return ResultGenerator.genSuccessResult(camera); }
访问异常
项目上因为有需要需要在拦截器里面获取请求体里面的数据进行数据验证,因为自己定义的controller里面对使用了@RequestBody注解,导致项目报错了报错的内容是:java.lang.IllegalStateException: getReader() has already been called for this request
查阅资料发现request里面的的getReader 和getInputStream因为是以流的方式获取的,读取一次后,后续就不能再用了,解决思路是:
第一步:定义一个过滤器,过滤器里面传入自己定义的request,自己定义的request要继承HttpServletRequestWrapper这个包装类,并重写里面的getInputStream和getReader方法
@WebFilter(filterName = "logFilter", urlPatterns = { "/*","/image/*", "/app/*", "/edgeapp/*", "/edge/*", "/node/*", "/cluster/upload/breakInit", "/cluster/upload/breakAbort", "/cluster/upload/breakMerge", "/cluster/upload/delete", "/monitor/*"}) @Slf4j public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { ServletRequest myHttpServletRequestWrapper = null; if (servletRequest instanceof HttpServletRequest) { myHttpServletRequestWrapper = new MyHttpServletRequestWrapper((HttpServletRequest) servletRequest); } if (myHttpServletRequestWrapper == null) { filterChain.doFilter(servletRequest, servletResponse); } else { filterChain.doFilter(myHttpServletRequestWrapper, servletResponse); } } @Override public void destroy() { } }
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { private byte[] body; public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); body = StreamUtil.readBytes(request.getInputStream()); } @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 boolean isFinished() { return bais.available() == 0; } @Override public boolean isReady() { return true; } @Override public void setReadListener(ReadListener readListener) { } @Override public int read() throws IOException { return bais.read(); } }; } public byte[] getBody() { return body; } },访问异常
项目上因为有需要需要在拦截器里面获取请求体里面的数据进行数据验证,因为自己定义的controller里面对使用了@RequestBody注解,导致项目报错了报错的内容是:java.lang.IllegalStateException: getReader() has already been called for this request