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
  • 相关阅读:
    Python列表和元组知识点
    Python 字符串操作常用知识点
    ng-alain的sf如何自定义部件
    Spring-手写Spring注解版本事务,Spring事物的七大传播行为
    Spring-SpringAOP原理,手写Spring事务框架
    JVM性能优化--类加载器,手动实现类的热加载
    JVM性能优化--字节码技术
    JVM性能优化--JVM参数配置,使用JMeter简单测试配合说明参数调优
    JVM性能优化--Java的垃圾回收机制
    设计模式之原型模式、策略模式、观察者模式
  • 原文地址:https://www.cnblogs.com/xuhai/p/15466424.html
Copyright © 2011-2022 走看看