zoukankan      html  css  js  c++  java
  • 解决request.getInputStream()只能读取一次的问题

    参考文章:http://dditblog.com/itshare_529.html

    代码需要获取入参里面URL后面的参数,还有POST请求里面BODY的数据;

    1、直接获取URL后面的数据

    直接使用 request.getParameter("appKey"); 就可以完成

    2、获取BODY里面的JSON数据

    无法直接获取request,直接获取getInputStream()里面入参情况,遍历的时候会提示stream close()的错误;

    造成原因:

    request在Spring里面已经获取了一次,流只能读一次、 读了就没有了、为了后面的代码还能够取得流;

    解决办法:

    /**
     * 获取请求Body
     *
     * @param request
     * @return
     */
    public static String getBodyString(ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
    HttpHelper.java
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
                
        // 防止流读取一次后就没有了, 所以需要将流继续写出去
        ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
        String json = HttpHelper.getBodyString(requestWrapper);
                
        System.out.println(json);
    
        filterChain.doFilter(requestWrapper, response);
    }
    Filter.Java
    public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
    
        private final byte[] body;
    
        public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
            super(request);
            body = HttpHelper.getBodyString(request).getBytes(Charset.forName("UTF-8"));
        }
    
        @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 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) {
    
                }
            };
        }
    
    }
    BodyReaderHttpServletRequestWrapper.java
  • 相关阅读:
    Redis缓存穿透
    如何应对缓存穿透和缓存雪崩问题
    Redis缓存雪崩
    redis缓存机制
    C# LINQ学习笔记三:LINQ to OBJECT之操作字符串
    C# LINQ学习笔记二:LINQ标准查询操作概述
    C# LINQ学习笔记一:走进LINQ的世界
    C# Lambda表达式学习笔记
    C#委托与事件学习笔记
    C#泛型学习笔记
  • 原文地址:https://www.cnblogs.com/xuhai/p/15466424.html
Copyright © 2011-2022 走看看