美文网首页
request.getReader() 和 request.ge

request.getReader() 和 request.ge

作者: 催化剂 | 来源:发表于2022-06-02 08:34 被阅读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

    相关文章

      网友评论

          本文标题:request.getReader() 和 request.ge

          本文链接:https://www.haomeiwen.com/subject/ahxfmrtx.html