多次讀取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";
    }
}

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

結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM