For the project, it is necessary to obtain the data in the request body in the interceptor for data verification, because the @ requestbody annotation is used in the self-defined controller, resulting in an error in the project. The content of the error is: Java. Lang. IllegalStateException: getreader() has already been called for this request
After consulting the data, it is found that the getReader and getinputstream in the request are obtained by stream. After reading once, they can’t be used again. The solution is:
Step 1: define a filter in which a self-defined request is passed in. The self-defined request inherits the wrapper class httpservletrequestwrapper and rewrites the getinputstream and getReader methods
the filter code is as follows:
package com.chinastock.filter;
import com.chinastock.util.CustomHttpServletRequestWrapper;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author zhoule
* @description: handle request
*/
public class IMTAFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if(servletRequest instanceof HttpServletRequest) {
requestWrapper = new CustomHttpServletRequestWrapper((HttpServletRequest) servletRequest);
}
if(requestWrapper == null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
filterChain.doFilter(requestWrapper, servletResponse);
}
}
}
The custom request code is as follows:
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.StandardCharsets;
/**
* @author zhoule
* @description: Custom request wrapper for processing messages in the request body
*/
public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] body;
public CustomHttpServletRequestWrapper(HttpServletRequest request) throws IOException
{
super(request);
BufferedReader reader = request.getReader();
try (StringWriter writer = new StringWriter()) {
int read;
char[] buf = new char[1024 * 8];
while ((read = reader.read(buf)) != -1) {
writer.write(buf, 0, read);
}
this.body = writer.getBuffer().toString().getBytes();
}
}
public String getBody(){
return new String(body, StandardCharsets.UTF_8);
}
@Override
public ServletInputStream getInputStream() throws IOException
{
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
return new ServletInputStream()
{
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
public int read() throws IOException
{
return byteArrayInputStream.read();
}
};
}
@Override
public BufferedReader getReader() throws IOException
{
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}
The second step is to write the interceptor of the project. Some codes of the interceptor are as follows:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
CustomHttpServletRequestWrapper wrapper = (CustomHttpServletRequestWrapper) request;
String body = wrapper.getBody();
System.out.println(body);
return true;
}