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

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

    结果:

  • 相关阅读:
    hihocoder-1014 Trie树
    51Nod-1265 四点共面
    cf466B Wonder Room
    2014.9.13模拟赛【数位和乘积】
    2014.9.13模拟赛【环上的游戏】
    bzoj2719[Violet 4]银河之星
    wikioi1450 xth的旅行
    poj2352 stars
    2014.9.6模拟赛【藏妹子之处】
    2014.9.6模拟赛【工资】
  • 原文地址:https://www.cnblogs.com/a393060727/p/6141295.html
Copyright © 2020-2023  润新知