• spring 处理request.getInputStream()输入流只能读取一次问题


    一般我们会在InterceptorAdapter拦截器中对请求进行验证

    正常普通接口请求,request.getParameter()可以获取,能多次读取

    如果我们的接口是用@RequestBody来接受数据,那么我们在拦截器中

    需要读取request的输入流  ,因为 ServletRequest中getReader()和getInputStream()只能调用一次

    这样就会导致controller 无法拿到数据。

    解决方法 :

    1、自定义一个类 BodyReaderHttpServletRequestWrapper.java 

    import java.io.BufferedReader;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    import javax.servlet.ReadListener;
    import javax.servlet.ServletInputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    import org.springframework.util.StreamUtils;
    
    /**
     * @author WBG
     * @date 2020/6/22 10:42
     * @describe
     */
    public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper{
    
        private byte[] requestBody = null;//用于将流保存下来
    
        public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
            super(request);
            requestBody = StreamUtils.copyToByteArray(request.getInputStream());
    
        }
    
        @Override
        public ServletInputStream getInputStream() throws IOException {
    
            final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);
    
            return new ServletInputStream() {
    
                @Override
                public int read() throws IOException {
                    return bais.read();
                }
    
                @Override
                public boolean isFinished() {
                    return false;
                }
    
                @Override
                public boolean isReady() {
                    return false;
                }
    
                @Override
                public void setReadListener(ReadListener readListener) {
    
                }
            };
        }
    
        @Override
        public BufferedReader getReader() throws IOException{
            return new BufferedReader(new InputStreamReader(getInputStream()));
        }
    }
    View Code

    2、自定义 MyFilter  继承Filter

    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import java.io.BufferedReader;
    import java.io.IOException;
    
    /**
     * @author WBG
     * @date 2020/6/22 14:32
     * @describe
     */
    public class MyFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("开始");
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            ServletRequest requestWrapper=null;
            if(request instanceof HttpServletRequest) {
                requestWrapper=new BodyReaderHttpServletRequestWrapper((HttpServletRequest)request);
            }
            if(requestWrapper==null) {
                chain.doFilter(request, response);
            }else {
                System.out.println("------------------------------请求报文----------------------------------");
                System.out.println(getParamsFromRequestBody((HttpServletRequest) requestWrapper));
                System.out.println("------------------------------请求报文----------------------------------");
                chain.doFilter(requestWrapper, response);
            }
    
        }
        /* *
         * 获取请求体内容
         * @return
         * @throws IOException
         */
    
        private String getParamsFromRequestBody(HttpServletRequest request) throws IOException {
            BufferedReader br = null;
            String listString = "";
            try {
                br = request.getReader();
    
                String str = "";
    
                while ((str = br.readLine()) != null) {
                    listString += str;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return listString;
        }
    
        @Override
        public void destroy() {
            System.out.println("destroy");
        }
    }
    View Code

    3、web.xm配置过滤器

      <!--定义过滤器-->
        <filter>
            <!--定义过滤器拦截URL地址-->
            <filter-name>test2</filter-name>
            <!--过滤器的文件-->
            <filter-class>com.zhhy.hy2000interface.utils.filter.MyFilter</filter-class>
        </filter>
        <filter-mapping>
            <!--过滤器的名称-->
            <filter-name>test2</filter-name>
            <!--过滤器负责拦截的URL-->
            <!-- /* 会把所有的请求拦截下来 -->
            <url-pattern>/*</url-pattern>
    
        </filter-mapping>
    View Code

    (如果是Springboot,使用注解即可)

  • 相关阅读:
    蓝凌OA 后台URL跳转(鸡肋0day)
    蓝凌后台注入分析
    蓝凌ssrf+xmldecoder
    shiro550反序列化复现
    BCEL ClassLoader加载字节码
    TemplatesImple链加载字节码
    ysoserial Commons Collections3反序列化研究
    Xstream远程代码执行(CVE-2020-26217)复现分析
    Java安全之命令执行(二)
    Java安全之命令执行(一)
  • 原文地址:https://www.cnblogs.com/weibanggang/p/13180469.html
Copyright © 2020-2023  润新知