request.getReader() 和 request.ge

2022-06-02  本文已影响0人  催化剂

在 Filter 中对 request 中的 body 进行参数签名校验, 会报如下错误:

getReader() has already been called for this request

原因是 request.getReader() 和 request.getInputStream() 都是只能调用一次

并且 getReader() 方法底层也是调用 getInputStream() 来实现的.

所以我们要使用 HttpServletRequestWrapper 来实现自定义的 CustomHttpServletRequestWrapper, 把 body 保存在 CustomHttpServletRequestWrapper 中, 并且重写 getInputStream() 方法

重写  HttpServletRequestWrapper

package com.fosung.pb.village.config;

import org.apache.commons.fileupload.servlet.ServletFileUpload;

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;

import java.nio.charset.StandardCharsets;

public class MyRequestWrapper extends HttpServletRequestWrapper {

    private byte[] body;

    public MyRequestWrapper(HttpServletRequest request) throws IOException {

        super(request);

        if(ServletFileUpload.isMultipartContent(request)){

            return;

        }

        StringBuilder sb = new StringBuilder();

        String line;

        BufferedReader reader = request.getReader();

        while ((line = reader.readLine()) != null) {

            sb.append(line);

        }

        String body = sb.toString();

        this.body = body.getBytes(StandardCharsets.UTF_8);

    }

    public String getBody() {

        return new String(this.body , StandardCharsets.UTF_8) ;

    }

    @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();

            }

        };

    }

    @Override

    public BufferedReader getReader(){

        return new BufferedReader(new InputStreamReader(this.getInputStream()));

    }

}

package com.fosung.pb.village.config;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Component;

import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

/**

* @author lanx

* @date 2022/4/11

*/

@Slf4j

@Component

@WebFilter(filterName = "AntiSqlInjectionfilter", urlPatterns = "/*")

public class AntiSqlInjectionfilter implements Filter {

    public void destroy() {

        // TODO Auto-generated method stub

    }

    public void init(FilterConfig arg0) throws ServletException {

        // TODO Auto-generated method stub

    }

    public void doFilter(ServletRequest request, ServletResponse response,

                        FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;

        HttpServletResponse res = (HttpServletResponse) response;

        MyRequestWrapper myRequestWrapper = null;

        // 获取请求body

        try {

            myRequestWrapper = new MyRequestWrapper(req);

        } catch (IOException e) {

            log.error("get request body exception", e);

            throw new RuntimeException(e);

        }

        if ("POST".equalsIgnoreCase(req.getMethod())) {

            String param = myRequestWrapper.getBody();

            chain.doFilter(myRequestWrapper, response);

        } else {

            chain.doFilter(myRequestWrapper, response);

        }

    }

}

原因是 request.getReader() 和 request.getInputStream() 都是只能调用一次。

原文链接:https://blog.csdn.net/woaiwojialanxi/article/details/124111799

上一篇下一篇

猜你喜欢

热点阅读