在实际项目开发中,经常需要对前台发来的请求body进行处理,例如参数过滤,参数校验,不合法参数拦截,参数解密等等。Spring中提供了 @ControllerAdvice+RequestBodyAdvice 的解决方案 对请求进行全局统一处理,可以避免在controller层对业务代码入侵。
注意:该方法只对使用了@RequestBody注解的参数生效,本质上是AOP,获取的是在请求头中的属性,如果通过GET请求方式,例如http://localhost:8080/xx?id=1 此种方法,是无法获得id参数的,此处下面将用代码证明。
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
@Slf4j @ControllerAdvice(basePackages = "com.example.demo.controller2") public class GlobalRequestBodyAdvice implements RequestBodyAdvice { @Override public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) { return true; }
@Override public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException { log.info("-----beforeBodyRead-----"); return httpInputMessage; }
@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; }
@Override public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) { log.info("-----handleEmptyBody-----"); return o; } }
|
@ControllerAdvice可以指定当前Advice生效的包路径,不指定默认全局生效。
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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方式:
结论:RequestBodyAdvice对POST方式+@RequestBody注解生效,成功获取请求的类名、方法名及参数,我们就可以对参数进行具体的业务处理。
测试GET方式:
结论:RequestAdvice未对GET方法生效。