zoukankan      html  css  js  c++  java
  • Java 复制HttpServletRequest InputStream的方法 只需2步轻松搞定

    你可能很疑惑,为什么request对象中的InputStream或者Reader只能使用一次?

    原理很简单,可以把流比喻成水,request里面的inputStream就好比杯子中的水。试问杯子中的水倒掉之后还能继续倒吗?当然不能滴!InputStream里面有做指针和同步处理,一旦指针到了末尾是不会回来的。那么我们怎么拷贝request body里面的数据呢,当然我们得找一种可以复制的存储方式了,比如String,可以先把request 的inputStream转成String,然后又把String转成byte[] 存回去就是了,String对象我们可以无限使用。

    好了,废话不多说,上代码:

    1. 先定义一个过滤器,过滤器自己先配置好哈,然后我们在过滤器的doFilter方法中做以下操作:

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        try {
            MyHttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper((HttpServletRequest) servletRequest);
            System.out.println("RequestBody:" + requestWrapper.getBodyString());
            filterChain.doFilter(requestWrapper, servletResponse);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    2. 这是MyHttpServletRequestWrapper类,主要是储存body string,和给request对象塞byte[]:

    public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {
    
        private final byte[] body;
    
        private String bodyString;
    
        public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
            super(request);
            this.bodyString = StreamUtils.copyToString(request.getInputStream(), Charset.forName("UTF-8"));
            body = bodyString.getBytes("UTF-8");
        }
    
        public String getBodyString() {
            return this.bodyString;
        }
    
        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(getInputStream()));
        }
    
        @Override
        public ServletInputStream getInputStream() throws IOException {
    
            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() throws IOException {
                    return bais.read();
                }
            };
        }
    
    }

    OK, 简单吧,你可以尝试一下了。

  • 相关阅读:
    硬盘SSD、HDD和SSHD都是什么意思?哪种类型硬盘最好?
    记录vlookup的小问题
    找到两个字符串中相同的部分| 对字符串list后的奇妙发现
    jiayan:Cannot read model 'jiayan.klm' (utilfile.cc:74 in util::OpenReadOrThrow threw ErrnoException because `-1 == (ret = _open(name,
    windows下装kenlm
    每日一题力扣98 验证二叉搜索树
    每日一题力扣230 二叉搜索树中的第K小的元素
    每日一题力扣538 把二叉搜索树转换为累加树
    每日一题力扣530 二叉搜索树的最小绝对查
    每日一题力扣700 二叉搜索树中的搜索
  • 原文地址:https://www.cnblogs.com/cnsec/p/13407178.html
Copyright © 2011-2022 走看看