• JAVA数据流再传递


           有一个filter类,在请求进入的时候读取了URL信息,并且读取了requestBod中的参数信息,那么在请求到达实际的控制层时,入参信息是拿不到的,对这种情况就需要数据流做再传递处理。

          处理原理:使用HttpServletRequestWrapper装饰类,重新定义获取流数据的方式。

          自定义filter的实现:

         

    package com.quyiyuan.openplatform.filter;
    
    import java.io.IOException;
    import java.util.UUID;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.web.context.WebApplicationContext;
    
    import com.quyiyuan.openplatform.service.MonitorService;
    
    /**
     * <pre>
     * 任务:
     * 描述:(存储用户请求信息,过滤器类)
     * 作者:
     * 时间:2015年11月5日下午12:03:33
     * 类名: SaveRequestInfoFilter 
     * </pre>
     */
    public class SaveRequestInfoFilter implements Filter{
        
        private ServletContext servletContext;
        
        @Override
        public void destroy() {
            
        }
    
        @Override
        public void doFilter(ServletRequest sreq, ServletResponse srsp,
                FilterChain fc) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) sreq;
            String method = request.getMethod();
            StringBuffer URL = request.getRequestURL();
            if(URL.toString().contains("ROPcloudtest.html") || URL.toString().contains("ROPtest.html")
                    || URL.toString().contains("ROP/css") || URL.toString().contains("ROP/js")
                    || URL.toString().contains("YYSK.html")){
                fc.doFilter(sreq, srsp);
            }else{
                String URI = "";
                String urlParame = "";
                String jsonParame = "";
                String token = request.getParameter("token");
                String userSource = request.getParameter("userSource");
                String publicServiceType = request.getParameter("publicServiceType");
                //request 作用域中添加UUID,标记当前请求
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                request.setAttribute("UUID", uuid);
                
                if (method.equals("POST")) {
                    URI = request.getRequestURI();
                    urlParame = request.getQueryString();
                    // 获取自定义装饰类对象
                    BodyReaderHttpServletRequestWrapper bodyWrapper = new BodyReaderHttpServletRequestWrapper(request);
                    jsonParame = HttpHelper.getBodyString(bodyWrapper);
                    saveReqInfo(URI, urlParame, jsonParame, token, userSource, publicServiceType, uuid);
                    // 使用自定义装饰类对象执行下一个过滤器
                    fc.doFilter(bodyWrapper, srsp);
                } else {
                    URI = request.getRequestURI();
                    urlParame = request.getQueryString();
                    saveReqInfo(URI, urlParame, jsonParame, token, userSource, publicServiceType, uuid);
                    fc.doFilter(request, srsp);
                }
            }
        }
        
        @Override
        public void init(FilterConfig config) throws ServletException {
            servletContext =config.getServletContext();
        }
        
        /**
         * <pre>
         * 任务: 
         * 描述: 调用业务类保存请求信息
         * 作者:
         * 时间:2015年11月5日下午12:04:09
         * @param URI
         * @param urlParame
         * @param jsonParame
         * returnType:void
         * </pre>
         * @param publicServiceType 
         * @param userSource 
         * @param token
         * @param uuid
         */
        private void saveReqInfo(final String URI, final String urlParame, final String jsonParame, final String token,
                final String userSource, final String publicServiceType, final String uuid) {
            Thread saveReqInfo = new Thread() {
                public void run() {
                    //获取容器对象
                    WebApplicationContext context = (WebApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
                    //获取MonitorService对象
                    MonitorService monitorService = (MonitorService) context.getBean("monitorService");
                    monitorService.saveRequestInfo(URI, urlParame, jsonParame, token, userSource, publicServiceType, uuid);
                }
            };
            saveReqInfo.start();
        }
    }

    自定义装饰类的实现BodyReaderHttpServletRequestWrapper:

    package com.quyiyuan.openplatform.filter;
    
    import javax.servlet.ServletInputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    import net.sf.json.JSONObject;
    
    import java.io.BufferedReader;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.nio.charset.Charset;
     
    /**
     * 
     * <pre>
     * 任务:
     * 描述:(实现IO流再传递)
     * 作者:
     * 时间:2015年11月5日下午5:34:04
     * 类名: BodyReaderHttpServletRequestWrapper 
     * </pre>
     */
    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();
                }
            };
        }
    }

    读取ServletRequest的body信息工具类:

    package com.quyiyuan.openplatform.filter;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.nio.charset.Charset;
    
    import javax.servlet.ServletRequest;
    
    /**
     * 
     * <pre>
     * 任务:
     * 描述:(读取ServletRequest的body信息)
     * 作者:
     * 时间:2015年11月5日下午5:34:58
     * 类名: HttpHelper 
     * </pre>
     */
    public class HttpHelper {
        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();
        }
    }
  • 相关阅读:
    sqlserver 表操作 SQL篇
    C#知识点汇总
    DDL
    sqlserver2008简介
    面向对象继承
    IO文件流
    【帅刺猬课堂】Winform中使用WPF的UserControl
    KS Gantt甘特图控件通过递归加载无限层级的数据
    Office 每次打开需要重新配置的问题修复方法
    扩展方法
  • 原文地址:https://www.cnblogs.com/cymiao/p/7576524.html
Copyright © 2020-2023  润新知