解决拦截器中获取了requestbody之后在controller中获取不到requestbody的问题
@requestbody使用的是流获取获取输出的参数。而在拦截器中获取的方式也是流
在spring的框架里面获取参数只能调用一次
于是自定义了一个过滤器将流先在过滤器里面获取到,然后再写进去就行了,这样的话就可以一直获取了
import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.filter.OncePerRequestFilter; public class RequserAgainFilter extends OncePerRequestFilter{ @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 防止流读取一次后就没有了, 所以需要将流继续写出去 HttpServletRequest httpServletRequest = (HttpServletRequest) request; ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest);
//最终的塞的操作 filterChain.doFilter(requestWrapper, response); } }
import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper{ private final byte[] body; public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); String sessionStream = getBodyString(request); body = sessionStream.getBytes(Charset.forName("UTF-8")); } /** * 获取请求Body * * @param request * @return */ public String getBodyString(final ServletRequest request) { StringBuilder sb = new StringBuilder(); InputStream inputStream = null; BufferedReader reader = null; try { inputStream = cloneInputStream(request.getInputStream());//将获取到的请求参数重新塞入request里面去 reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8"))); String line = ""; while ((line = reader.readLine()) != null) { sb.append(line); } } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return sb.toString(); } /** * Description: 复制输入流</br> * * @param inputStream * @return</br> */ public InputStream cloneInputStream(ServletInputStream inputStream) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; try { while ((len = inputStream.read(buffer)) > -1) { byteArrayOutputStream.write(buffer, 0, len); } byteArrayOutputStream.flush(); } catch (IOException e) { e.printStackTrace(); } InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); return byteArrayInputStream; } @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 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) { } }; } }
web.xml的配置
<filter>
<filter-name>RequserAgainFilter</filter-name>
<filter-class>com.loan.api.filter.RequserAgainFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RequserAgainFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
拦截器获取数据
private String getRequestBody(HttpServletRequest request) { String parameterMap = ""; try { parameterMap = new BodyReaderHttpServletRequestWrapper(request).getBodyString(request); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } return parameterMap; }