• interceptor or controller 获取流异常


      最近做一个拦截器获取参数的需求 (还有一个在 controller 获取 request 的流的时候也出现了同样的问题。),本来运行的好好的,可是迭代了几个版本之后,发现所有获取流的方法都出现了问题。经过排查发现是加了几个拦截器。而 request.getInputStream() 只可以读一次。所以导致后续从request获取数据全部是空,才出现的异常。所以我们可以通过 filter 将request存起来,这样用的时候就不会出异常了。

    1. 工具类

    import javax.servlet.http.HttpServletRequest;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.nio.charset.Charset;
    
    public class HttpHelper {
        public static String getBodyString(HttpServletRequest request) throws IOException {
            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();
        }
    }

    2. 包装类处理流

    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.Charset;
    
    public class RequestReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
    
        private final byte[] body;
    
        public RequestReaderHttpServletRequestWrapper(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) {
    
                }
            };
        }
    }

    3. 添加过滤器

    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    
    
    public class HttpServletRequestReplacedFilter implements Filter {
        @Override
        public void destroy() {
    
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                             FilterChain chain) throws IOException, ServletException {
            ServletRequest requestWrapper = null;
            if(request instanceof HttpServletRequest) {
                requestWrapper = new RequestReaderHttpServletRequestWrapper((HttpServletRequest) request);
            }
            //获取请求中的流如何,将取出来的字符串,再次转换成流,然后把它放入到新request对象中。
            // 在chain.doFiler方法中传递新的request对象
            if(requestWrapper == null) {
                chain.doFilter(request, response);
            } else {
                chain.doFilter(requestWrapper, response);
            }
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
    
        }
    }

    4. 注册过滤器

    @Configuration
    public class RpcAuthenticationConfiguration {
    
        @Bean
        public FilterRegistrationBean httpServletRequestReplacedRegistration() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(new HttpServletRequestReplacedFilter());
            registration.addUrlPatterns("/*");
            registration.setName("httpServletRequestReplacedFilter");
            registration.setOrder(1);
            return registration;
        }
    }

  • 相关阅读:
    OC面向对象—封装
    设计模式之类关系
    理性:中国别一厢情愿救俄罗斯(转)
    Mockito--完整功能介绍(转)
    从陌陌上市看BAT的移动保卫战(转)
    This exception may occur if matchers are combined with raw values
    RepositoryClassLoader.java
    搭建你的持续集成server
    mysql中怎样查看和删除唯一索引
    Android中Context具体解释 ---- 你所不知道的Context
  • 原文地址:https://www.cnblogs.com/wlwl/p/15821037.html
Copyright © 2020-2023  润新知