最近在搞一套日志系统 ,里边有个模块就是记录一下用户操作记录,需要拿到请求params,返回的result,还有就是requestbody中的内容, 然后在取body的时候发现取不到,这边文章记录一下!

报错内容

getInputStream() has already been called for this request

原因
ServletRequest的getReader()和getInputStream()两个方法只能被调用一次,而且不能两个都调用。那么如果Filter中调用了一次,在Controller里面就不能再调用了

解决办法
先将 Request Body 保存,然后通过 Servlet 自带的 HttpServletRequestWrapper 类覆盖 getReader () 和getInputStream () 方法,使流从保存的 body 读取。然后再 Filter 中将 ServletRequest 替换为 MyRequestWrapper。

添加配置类

RequestWrapper.java

package top.fate.config;

import org.apache.poi.util.IOUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @auther:Wangxl
 * @Emile:18335844494@163.com
 * @Time:2022/6/30 16:24
 */
public class RequestWrapper extends HttpServletRequestWrapper {

    private final byte[] body;

    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        body = IOUtils.toByteArray(request.getInputStream());
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
        return 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 bais.read();
            }
        };
    }
}

HttpServletRequestReplacedFilter.java

package top.fate.config;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * @auther:Wangxl
 * @Emile:18335844494@163.com
 * @Time:2022/6/30 16:35
 */
public class HttpServletRequestReplacedFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        ServletRequest servletWrapper = null;
        if (servletRequest instanceof HttpServletRequest) {
            servletWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
        }
        if (servletRequest == null) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            try {
                filterChain.doFilter(servletWrapper, servletResponse);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ServletException e) {
                e.printStackTrace();
            }
        }
    }
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐