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();
    }
}

 

posted @ 2017-09-22 18:54  时间足迹  阅读(1381)  评论(0编辑  收藏  举报