解决springboot只能获取一次post请求的body数据

5 篇文章 0 订阅
1 篇文章 0 订阅

解决springboot只能获取一次post请求的body数据

自定义一个类继承 HttpServletRequestWrapper

HttpServletRequestWrapper 类可以用来做关键字过滤器,因为post提交的请求是以流的形式存放,所以获取也需要以流方式获取,但是如果在拦截器中直接获取,那么在controller中将无法在获取第二次,因为流的指针无法回到最初的位置。所以使用此类就可以解决此类问题。原理是将内容以流的形式获取后,在将内容以流的形式存放进request请求中。

import com.jgmes.base.utils.JgmesFilterSpecialCharUtil;
import org.apache.commons.lang.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.List;

/**
 * @author Zh
 * @version v1.0
 * @description:
 * @date 2020/8/6 19:07
 */
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {

    private final byte[] body;

    public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        String sessStr = getBody(request);
        this.body = sessStr.getBytes(Charset.forName("UTF-8"));
    }

    /**
     * 获取body
     * @param request
     * @return
     * @throws IOException
     */
        public String getBody(HttpServletRequest request) throws IOException {
        StringBuffer stringBuffer = new StringBuffer();
        InputStream inputStream = request.getInputStream();
        BufferedReader reader = null;

        String line = "";
        while ((line = reader.readLine()) != null){
            stringBuffer.append(line);
        }
        try{
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
        }catch (Exception e){
            throw e;
        }finally {
            reader.close();
        }
        String param = stringBuffer.toString();
        filterIllegal(param);
        return param;
    }

    /**
     * 过滤特殊字符 自定义方法
     * @param param
     */
    public void filterIllegal(String param){
        List<String> illegalStrings = JgmesFilterSpecialCharUtil.existsSpecialChar(param);
        if(illegalStrings != null && illegalStrings.size() > 0){
            String illegalString = StringUtils.join(illegalStrings.toArray(), ",");
            throw new RuntimeException("非法字符被拦截:"+ illegalString);
        }
    }
    
     /**
     * 输出流
     * @return
     * @throws IOException
     */
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    /**
     * 重写 输入流
     * @return
     */
    @Override
    public ServletInputStream getInputStream(){
        final ByteArrayInputStream inputStream = new ByteArrayInputStream(body);
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return inputStream.available() == 0;
            }

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

            @Override
            public void setReadListener(ReadListener readListener) {

            }

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

创建一个拦截器

import com.alibaba.fastjson.JSONObject;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;

/**
 * @author Zh
 * @version v1.0
 * @description:
 * @date 2020/8/5 16:21
 */
@WebFilter(filterName = "specialCharFilter", urlPatterns = {"/base-form-template-data/*", "/base-form-template/*", "/base-table/*"})
public class specialCharFilter implements Filter {

    private BodyReaderHttpServletRequestWrapper wrapper;

    /**
     * 初始化拦截器
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化过滤器");
    }

    /**
     * 进行拦截操作
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        // 在wrapper中过滤post请求
        wrapper = new BodyReaderHttpServletRequestWrapper(request);
        // 过滤get请求
        filterGetSpace(request);
        filterChain.doFilter(wrapper, servletResponse);
    }

    /**
     * 过滤get请求
     * @param request
     */
    public void filterGetSpace(HttpServletRequest request){
        Map param = request.getParameterMap();
        String paramStr = JSONObject.toJSONString(param);
        wrapper.filterIllegal(paramStr);
    }

    /**
     * 拦截器销毁
     */
    @Override
    public void destroy() {

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值