多次读取HttpServletRequest的inputstream方法 问题解决

原因:我要收集所有来自前台请求的参数信息,无论在任何地方的。当前请求参数都是json格式,都写在httpservlet的body中。这个只能通过流进行获取。然后问题来了,HttpServletRequest的inputstream只能读取一次。。。。

解决:重写request的inputstream方法。。然后在需要部署应用中加上过滤器,在过滤器中加上这个重写的request的方法,问题解决。

1、读取流信息的工具类:HttpUtil.java

/**获取请求Body
     * 
     * @param request
     * @return
     * @author : chewneixian 陈惟鲜
     * @create_date 2016年12月6日 下午12:54:07
     */
    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();
    }

 

2、重写httpservlet的inputstream类:BodyReaderHttpServletRequestWrapper

 1 import javax.servlet.ServletInputStream;
 2 import javax.servlet.http.HttpServletRequest;
 3 import javax.servlet.http.HttpServletRequestWrapper;
 4 
 5 import com.iafclub.baseTools.util.HttpUtil;
 6 
 7 import java.io.BufferedReader;
 8 import java.io.ByteArrayInputStream;
 9 import java.io.IOException;
10 import java.io.InputStreamReader;
11 import java.nio.charset.Charset;
12 
13 /**重写HttpServletRequestWrapper
14  * 
15  * @author 陈惟鲜
16  * @date 2016年12月7日 下午3:06:52
17  *
18  */
19 public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
20 
21     private final byte[] body;
22 
23     public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
24         super(request);
25         body = HttpUtil.getBodyString(request).getBytes(Charset.forName("UTF-8"));
26     }
27 
28     @Override
29     public BufferedReader getReader() throws IOException {
30         return new BufferedReader(new InputStreamReader(getInputStream()));
31     }
32 
33     @Override
34     public ServletInputStream getInputStream() throws IOException {
35 
36         final ByteArrayInputStream bais = new ByteArrayInputStream(body);
37 
38         return new ServletInputStream() {
39 
40             @Override
41             public int read() throws IOException {
42                 return bais.read();
43             }
44         };
45     }
46 }

3、过滤器中加上重写方法:AccessFilter

 1 import java.io.IOException;
 2 import java.util.regex.Pattern;
 3 
 4 import javax.servlet.Filter;
 5 import javax.servlet.FilterChain;
 6 import javax.servlet.FilterConfig;
 7 import javax.servlet.ServletContext;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.annotation.WebFilter;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 
15 import org.apache.log4j.Logger;
16 
17 import com.iafclub.baseTools.util.HttpUtil;
18 import com.iafclub.demo.aop.BodyReaderHttpServletRequestWrapper;
19 /**访问过滤器
20  * 
21  * @author chenweixian
22  *
23  */
24 @WebFilter(filterName="accessFilter", urlPatterns={
25         "*.do",
26 //        "*.jsp",
27 //        "/*",
28 //        "/layout/*",
29 //        "/apply/*",
30 //        "/audit/*",
31 //        "/authority/*",
32 //        "/commonWare/*",
33 //        "/contract/*",
34 //        "/marketing/*",
35 //        "/product/*",
36 //        "/project/*",
37 //        "/system/*",
38 //        "/user/*"
39         })
40 public class AccessFilter implements Filter {
41     //     日志对象
42     private static Logger logger = Logger.getLogger(AccessFilter.class);
43 
44     public void init(FilterConfig filterConfig) throws ServletException {
45 //        ServletContext context = filterConfig.getServletContext();  
46     }
47     
48     public void destroy() {
49     }
50 
51     public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
52         HttpServletRequest request = (HttpServletRequest) req;
53         System.out.println("=====+" + req.hashCode());
54         HttpServletResponse response = (HttpServletResponse) res;        
55         if ("POST".equalsIgnoreCase(request.getMethod())) {
56             
57             ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
58             System.out.println("===filter==+" + requestWrapper.hashCode());
59 
60             String body = HttpUtil.getBodyString(requestWrapper);
61             System.out.println("AccessFilter="+body);
62             chain.doFilter(requestWrapper, response);
63             return ;
64         }
65         
66         chain.doFilter(req, res);
67     }
68 }

4、拦截器:ControllerAopInterceptor(其实我们这里根本用到这个东西,加载这里的目的是想说,过滤器访问在aop切面之前,过滤器修改request,其他访问的request都被修改)

 1 import javax.servlet.http.HttpServletRequest;
 2 
 3 import org.apache.log4j.Logger;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5 import org.aspectj.lang.annotation.After;
 6 import org.aspectj.lang.annotation.AfterReturning;
 7 import org.aspectj.lang.annotation.AfterThrowing;
 8 import org.aspectj.lang.annotation.Around;
 9 import org.aspectj.lang.annotation.Aspect;
10 import org.aspectj.lang.annotation.Before;
11 import org.aspectj.lang.annotation.Pointcut;
12 import org.springframework.stereotype.Service;
13 import org.springframework.web.context.request.RequestAttributes;
14 import org.springframework.web.context.request.RequestContextHolder;
15 import org.springframework.web.context.request.ServletRequestAttributes;
16 
17 import com.iafclub.baseTools.util.HttpUtil;
18 import com.iafclub.baseTools.util.MyCollectionUtil;
19 
20 /**切面  
21  * 
22  * @author chenweixian
23  *
24  */
25 @Aspect
26 @Service
27 public class ControllerAopInterceptor {
28     
29     private Logger logger = Logger.getLogger(ControllerAopInterceptor.class);
30     
31     @Pointcut("execution(* com.iafclub.demo.web.controller..*(..))")  
32     private void anyMethod(){}//定义一个切入点  
33       
34     @Before("anyMethod() && args(request)") 
35     public void doAccessCheck(Object request){
36         logger.info(request);  
37         logger.info("前置通知");  
38     }  
39       
40     @AfterReturning("anyMethod() && args(request)")  
41     public void doAfter(Object request){  
42         logger.info(request);  
43         logger.info("后置通知");  
44     }  
45     
46     @Around("anyMethod()")  
47     public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
48         RequestAttributes ra = RequestContextHolder.getRequestAttributes();
49         ServletRequestAttributes sra = (ServletRequestAttributes) ra;
50         HttpServletRequest request = sra.getRequest();
51         
52         String url = request.getRequestURL().toString();
53         String method = request.getMethod();
54         String uri = request.getRequestURI();
55         String queryString = request.getQueryString();
56         Object[] requestObject = pjp.getArgs();
57         
58         String body = HttpUtil.getBodyString(request);
59         System.out.println("====aop=+" + request.hashCode());
60 
61         System.out.println("ControllerAopInterceptor="+body);
62         logger.info("请求开始, 各个参数, url: {"+url+"}, method: {"+method+"}, uri: {"+uri+"}, params: {"+queryString+"},requestObject{"+requestObject+"}");
63         // result的值就是被拦截方法的返回值
64         Object result = pjp.proceed();
65         logger.info("请求结束,controller的返回值是 " + MyCollectionUtil.objectToMapAll(result));
66         return result;
67     }
68       
69     @After("anyMethod()")  
70     public void after(){  
71         logger.info("最终通知");  
72     }  
73       
74     @AfterThrowing("anyMethod()")  
75     public void doAfterThrow(){  
76         logger.info("例外通知");  
77     }  
78     
79 }

5、真正处理的类也不会受到影响:

/**测试首页
 * 
 * @author chenweixian
 *
 */
@Controller
public class IndexController {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private DictionaryService dictionaryService;
    /**
     * 首页
     * @throws IOException 
     * */
    @RequestMapping("index.do")
    public String index(Model model, HttpServletRequest request) throws IOException{

        String body = HttpUtil.getBodyString(request);
        System.out.println("==index===+" + request.hashCode());

        System.out.println("IndexController="+body);
        return "index";
    }
}

哈哈。。。。。。。。。。。

结果:

 

posted on 2016-12-07 15:17  陈惟鲜的博客  阅读(6217)  评论(0编辑  收藏  举报

导航