解决HttpServletRequest调用getInputStream()方法读取参数只能获取一次问题

1、问题描述

由于后端接口获取前端传过的参数是通过HttpServletRequest接收获取的。现有一需求需要在接口调用之前拦截接口进行业务处理。在拦截类中调用getInputStream()获取参数之后,在接口方法里获取参数为空。

2、解决方法

自定义一个过滤器过滤所有请求,使用HttpServletRequestWrapper将发送请求的流有容器储存起来,就可以多次调用了。
首先定义一个包装类RequestWrapper继承HttpServletRequestWrapper

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StreamUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Map;

@Slf4j
public class RequestWrapper extends HttpServletRequestWrapper {
    /**
     * 存储body数据的容器
     */
    private final byte[] body;

    //private Map<String, String[]> parameterMap;

//    @Override
//    public String[] getParameterValues(String name) {
//        if(!CollectionUtils.isEmpty(parameterMap)) {
//            return parameterMap.get(name);
//        }
//        return null;
//    }

    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        //parameterMap = request.getParameterMap();
        // 将body数据存储起来
        body = StreamUtils.copyToByteArray(request.getInputStream());
    }

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

    @Override
    public ServletInputStream getInputStream() throws IOException {

        final ByteArrayInputStream inputStream = new ByteArrayInputStream(body);

        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return inputStream.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }
        };
    }
}

编写过滤器:

import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;


@Slf4j
@WebFilter(filterName = "streamFilter",urlPatterns = "/*")
public class RequestStreamFilter implements Filter {

    @Override
    public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
        log.info("StreamFilter init...");

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ServletRequest requestWrapper = new RequestWrapper((HttpServletRequest) request);
        chain.doFilter(requestWrapper, response);
    }

    @Override
    public void destroy() {
        log.info("StreamFilter  destroy...");
    }
}
posted @ 2024-02-28 13:13  sowler  阅读(326)  评论(0编辑  收藏  举报