龙空技术网

拦截器获取body数据流导致controller数据为空

island猿 149

前言:

眼前我们对“controller接收参数为null”大约比较重视,朋友们都想要剖析一些“controller接收参数为null”的相关资讯。那么小编同时在网摘上汇集了一些有关“controller接收参数为null””的相关文章,希望姐妹们能喜欢,大家一起来学习一下吧!

一、产生问题的原因

产生问题前提:使用拦截器获取body数据(例如:接口参数校验,签名校验等)

request流数据只能获取一次,拦截器获取流数据之后。controller无法获取数据。数据为空

二、解决思路

流数据只能获取一次,那么考虑是否能把留保留下来,重新给到request。

二、解决过程(附代码)

重写HttpServletRequestWrapper 保存request。通过filter填充

1.新建RequestWrapper 继承 HttpServletRequestWrapper 代码如下

/** * @author yuqi9 * @since 2019/5/23 */public class RequestWrapper extends HttpServletRequestWrapper { private final String body; public RequestWrapper(HttpServletRequest request) { super(request); StringBuilder stringBuilder = new StringBuilder(); BufferedReader bufferedReader = null; InputStream inputStream = null; try { inputStream = request.getInputStream(); if (inputStream != null) { bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); char[] charBuffer = new char[128]; int bytesRead = -1; while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { stringBuilder.append(charBuffer, 0, bytesRead); } } else { stringBuilder.append(""); } } catch (IOException ex) { } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } } body = stringBuilder.toString(); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); ServletInputStream servletInputStream = new ServletInputStream() { @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } @Override public int read() throws IOException { return byteArrayInputStream.read(); } }; return servletInputStream; } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(this.getInputStream())); } public String getBody() { return this.body; }}
2. 新建filter ReReadFilter 加入WebMvcConfiguration
@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { ServletRequest requestWrapper = null; if(servletRequest instanceof HttpServletRequest) { requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest); } if(requestWrapper == null) { filterChain.doFilter(servletRequest, servletResponse); } else { filterChain.doFilter(requestWrapper, servletResponse); }}

3.拦截器使用RequestWrapper获取流

@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { RequestWrapper requestWrapper = new RequestWrapper(request); String jsonBody = requestWrapper.getBody();}

到此则处理完成拦截器获取流导致controller数据为空。如有不足,还请斧正

标签: #controller接收参数为null