问题描述:
请求在SpringBoot拦截器中执行后,在Controller层不执行,前端错误码400
原因分析:
ServletRequest 中通过流获取参数(getInputStream())只能读取一次,而@RequestBody注解也是根据流的形式获取参数。所以拦截器中 request 使用流获取参数后,Controller中获取不到参数
解决方案:
// 拦截器中获取请求
RequestWrapper myRequestWrapper = new RequestWrapper(request);
String JSONData = myRequestWrapper.getBody();
public class RequestWrapper extends HttpServletRequestWrapper {
/**
* 存储请求数据
*/
private String body;
public RequestWrapper(HttpServletRequest request) {
super(request);
renewBody(request);
}
/**
* 重写getInputStream方法
* @return
*/
@Override
public ServletInputStream getInputStream() {
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() {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
/**
* 重写getReader方法
* @return
*/
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
/**
* 读取body的值
* @param request
*/
private void renewBody(HttpServletRequest request) {
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream 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);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
body = stringBuilder.toString();
}
public String getBody() {
return body;
}
}
@Component
public class HttpServletFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if (servletRequest instanceof HttpServletRequest) {
requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
System.out.println(((RequestWrapper) requestWrapper).getBody());
// do something
}
if (requestWrapper == null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
filterChain.doFilter(requestWrapper, servletResponse);
}
}
@Override
public void destroy() {
}
}