springmvc在拦截器操作请求体requestBody

springmvc在拦截器操作请求体requestBody

    • 一.环境
    • 二.POST请求
    • 三. 写到最后:

一般需要在springmvc中获取请求体中的内容.对请求体中的内容记录或操作后传给下游,springmvc项目中请求体中的内容只能获取一次,在下游无法获取,在下游获取将报如下错误(Required request body is missing: ),需要处理后在下游可获取.

一.环境

  1. 项目环境
    springboot的项目
   			
  	 org.springframework.boot
  	spring-boot-starter-web
  	2.1.5.RELEASE 		
 
  1. 请求数据样例
    –data-raw中的部分是请求体RequestBody中的数据内容即POST请求传的json数据部分
curl 'http://localhost:9104/sys/loginAction/login'   
-H 'Connection: keep-alive'   
-H 'Accept: application/json, text/plain, */*'  
-H 'Content-Type: application/json'   
-H 'Origin: http://dipc.data-pivot.com:81'  
-H 'Referer: http://dipc.data-pivot.com:81/'  
-H 'Accept-Language: zh-CN,zh;q=0.9'  
--data-raw '{"userCode":"zhangsanl","userPassword":"23","platform":1}'  -v

二.POST请求

获取请求内容并操作,一般requestBody中的请求内容消费一次后无法在下游进行二次消费,此时需要在消费后重新设置,即可在Controller中的方法参数@RequestBody
SysUserReqeust userReq中获取到.

  1. springmvc中的HandlerInterceptor前置拦截器
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            String clientIp = null;
            BufferedReader br = request.getReader();
            char[] bys = new char[2048];
            int length = 0;
            String body = null;
            CharArrayWriter caw = null;
            try {
                caw = new CharArrayWriter();
                while ((length = br.read(bys,0,bys.length)) != -1){
                    caw.write(bys,0,length);
                }
                body = new String(caw.toCharArray());
            } finally {
                if(caw != null)
                    caw.close();
                if(br != null)
                    br.close();
            }
            if(request instanceof RequestFacade){
                // 1.获取RequestFacade中的字段request
                Field req = request.getClass().getDeclaredField("request");
                req.setAccessible(true);
                Request newReq = (Request)req.get(request);
                // 2.获取RequestFacade中的字段usingInputStream并设置为false
                Field usingInputStream = newReq.getClass().getDeclaredField("usingInputStream");
                usingInputStream.setAccessible(true);
                usingInputStream.set(newReq,false);
                // 3.获取RequestFacade中的字段usingReader并设置为false
                Field usingReader = newReq.getClass().getDeclaredField("usingReader");
                usingReader.setAccessible(true);
                usingReader.set(newReq,false);
                // 4.获取RequestFacade中的字段inputStream
                Field inputStream = newReq.getClass().getDeclaredField("inputStream");
                inputStream.setAccessible(true);
                CoyoteInputStream cis = (CoyoteInputStream)inputStream.get(newReq);
                // 4-1.获取RequestFacade中的字段inputStream的lib字段
                Field ib = cis.getClass().getDeclaredField("ib");
                ib.setAccessible(true);

                // 4-2.新建InputBuffer并设置ByteBuffer和request(该request是RequestFacade中request字段的coyoteRequest字段值)
                InputBuffer inputBuffer = new InputBuffer();
                inputBuffer.setByteBuffer(ByteBuffer.wrap(body.getBytes("UTF-8")));

                Field coyoteRequest = newReq.getClass().getDeclaredField("coyoteRequest");
                coyoteRequest.setAccessible(true);
                org.apache.coyote.Request cr = (org.apache.coyote.Request)coyoteRequest.get(newReq);
                inputBuffer.setRequest(cr);
                // 4-3.设置RequestFacade中的字段inputStream的lib字段为新建inputBuffer
                ib.set(cis,inputBuffer);

                request.setAttribute("loginBody",body);
                SysUserReqeust user = JSON.parseObject(body, SysUserReqeust.class);
                clientIp = user.getUserCode();
            }
            return true;
        }

  1. controller中的相关方法
    @PostMapping("login")
    public ReturnMsg login(HttpServletRequest request,
                           @RequestBody
                           @Validated({ValidateGroup.UsernameAndPwd.class}) SysUserReqeust user,
                           HttpServletResponse response) throws Exception {
        SysUser sysUser = BeanUtil.copyEvalueToT(user, SysUser.class);
        ReturnMsg returnMsg = userService.validateUser(user.getPlatform(),sysUser);
        return returnMsg;
    }


三. 写到最后:

各位看官如果支持博文请点个小爱心支持下博主,博主将在您的支持下继续编写更多的博文进行交流。如有问题也可联系博主进行交流学习,博主QQ:676621871

你可能感兴趣的:(java,java,restful,spring,boot)