spring boot 对request使用inputstream后,获取不到请求参数处理

背景,这边有一个需求,前端跟后端之间有一个网闸,网闸只接收Post请求,json格式的数据,而且不能转发cookie跟headers,这就只能把token放在路径上或者是请求体中,我这里是把token放在请求体中,我在后端request里使用它的inputstream,后发现spring在对参数进行解析的时候再获取时,取不到请求参数。这个原因就是inputstream是只能读一次。处理方法:通过request增加器,复制请求的方式,这是网上找到的方法,可以解决这个问题,再这里记录一下。

/**
 * desc 请求参数增强器
 * date 2022/9/6 9:34
 * @author fmk
 */
public class RequestBodyWrapper extends HttpServletRequestWrapper {
    
    
 
    /**
     * 定义字节数组, 缓存请体信息
     */
    private final byte[] requestBody;
 
    public RequestBodyWrapper(HttpServletRequest request) throws IOException {
    
    
        super(request);
        // 复制请求体
        requestBody = StreamUtils.copyToByteArray(request.getInputStream());
    }
 
    /**
     * desc 重写获取request请求的输入流方法, 从复制的字节数组中获取
     * date 2022/9/6 9:40
     * @author fmk
     * @return {@link ServletInputStream}
     */
    @Override
    public ServletInputStream getInputStream(){
    
    
 
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody);
 
        return new ServletInputStream() {
    
    
 
            @Override
            public int read(){
    
    
                return byteArrayInputStream.read();
            }
 
            @Override
            public boolean isFinished() {
    
    
                return false;
            }
 
            @Override
            public boolean isReady() {
    
    
                return false;
            }
 
            @Override
            public void setReadListener(ReadListener readListener) {
    
    
 
            }
        };
    }
 
    /**
     * desc 重写获取缓冲字符输入流的方法, 从复制的字节数组中获取
     * date 2022/9/6 9:40
     * @author fmk
     * @return {@link BufferedReader}
     */
    @Override
    public BufferedReader getReader(){
    
    
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
}

过滤器如下:

package com.example.appspringboot.cache;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

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

@Component
@Order(1)
public class RequestBodyFilter implements Filter {
    
    
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        if(servletRequest instanceof HttpServletRequest){
    
    
            filterChain.doFilter(new RequestBodyWrapper((HttpServletRequest) servletRequest), servletResponse);
        }else {
    
    
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
}

操作这两步可以了。

猜你喜欢

转载自blog.csdn.net/u013326684/article/details/130695211