欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot项目实战经验之@ControllerAdvice+RequestBodyAdvice实现请求体全局统一处理

程序员文章站 2022-07-03 19:59:11
在实际项目开发中,经常需要对前台发来的请求body进行处理,例如参数过滤,参数校验,不合法参数拦截,参数解密等等。Spring中提供了 @ControllerAdvice+RequestBodyAdvice 的解决方案 对请求进行全局统一处理,可以避免在controller层对业务代码入侵。注意:该方法只对使用了@RequestBody注解的参数生效,本质上是AOP,获取的是在请求头中的属性,如果通过GET请求方式,例如http://localhost:8080/xx?id=1 此种方法,是无法获得i....

在实际项目开发中,经常需要对前台发来的请求body进行处理,例如参数过滤,参数校验,不合法参数拦截,参数解密等等。Spring中提供了 @ControllerAdvice+RequestBodyAdvice 的解决方案 对请求进行全局统一处理,可以避免在controller层对业务代码入侵。

注意:该方法只对使用了@RequestBody注解的参数生效,本质上是AOP,获取的是在请求头中的属性,如果通过GET请求方式,例如http://localhost:8080/xx?id=1 此种方法,是无法获得id参数的,此处下面将用代码证明。

代码示例

/**
 * @Author zhangting
 * @Desc 请求body全局统一处理
 * @Date 2020/07/29
 **/
@Slf4j
@ControllerAdvice(basePackages = "com.example.demo.controller2")
public class GlobalRequestBodyAdvice implements RequestBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        // 此处true代表执行当前advice的业务,false代表不执行
        return true;
    }

    /**
     * 读取参数前执行
     *
     * @param httpInputMessage
     * @param methodParameter
     * @param type
     * @param aClass
     * @return
     * @throws IOException
     */
    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        log.info("-----beforeBodyRead-----");
        return httpInputMessage;
    }

    /**
     * 读取参数后执行
     *
     * @param o
     * @param httpInputMessage
     * @param methodParameter
     * @param type
     * @param aClass
     * @return
     */
    @Override
    public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        log.info("-----afterBodyRead-----");
        log.info("class name is {}",methodParameter.getDeclaringClass().getSimpleName());
        log.info("method name is {}",methodParameter.getMethod().getName());
        log.info("request parameter is {}",o.toString());
        return o;
    }

    /**
     * 无请求时的处理
     *
     * @param o
     * @param httpInputMessage
     * @param methodParameter
     * @param type
     * @param aClass
     * @return
     */
    @Override
    public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        log.info("-----handleEmptyBody-----");
        return o;
    }
}

@ControllerAdvice可以指定当前Advice生效的包路径,不指定默认全局生效。

测试类

/**
* @Author zhangting
* @Desc 测试
* @Date 2020/07/29
**/
@RestController
@RequestMapping("/v2")
@Slf4j
public class TestController2 {

   @RequestMapping(method = RequestMethod.GET, value = "/get")
   public ResponseEntity<?> get(@RequestParam String id) {
       log.info("id is {}", id);
       Map<String,String> rsp = new HashMap<>();
       rsp.put("code","200");
       rsp.put("msg","success");
       return new ResponseEntity<>(rsp, HttpStatus.OK);
   }

   @RequestMapping(method = RequestMethod.POST, value = "/post")
   public ResponseEntity<?> post(@RequestBody Map<String, String> map) {
       log.info("begin /v2/post");
       Map<String,String> rsp = new HashMap<>();
       rsp.put("code","200");
       rsp.put("msg","success");
       log.info("end /v2/post");
       return new ResponseEntity<>(rsp, HttpStatus.OK);
   }
}

测试类*包含两个api:
1、/v2/get , 请求方式为GET
2、/v2/post ,请求方式为POST
通过postman测试:

测试POST方式:

SpringBoot项目实战经验之@ControllerAdvice+RequestBodyAdvice实现请求体全局统一处理
SpringBoot项目实战经验之@ControllerAdvice+RequestBodyAdvice实现请求体全局统一处理
结论:RequestBodyAdvice对POST方式+@RequestBody注解生效,成功获取请求的类名、方法名及参数,我们就可以对参数进行具体的业务处理。

测试GET方式:

SpringBoot项目实战经验之@ControllerAdvice+RequestBodyAdvice实现请求体全局统一处理
SpringBoot项目实战经验之@ControllerAdvice+RequestBodyAdvice实现请求体全局统一处理
结论:RequestAdvice未对GET方法生效。

本文地址:https://blog.csdn.net/King__Cheung/article/details/107662888