在实际项目开发中,经常需要对向前台返回的响应体进行处理,例如包装为通用返回类型等。Spring中提供了 @ControllerAdvice+ResponseBodyAdvice 的解决方案 对响应体进行全局统一处理,可以避免在controller层对业务代码入侵。
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
@Slf4j @ControllerAdvice(basePackages = "com.example.demo.controller") public class GlobalResponseBodyAdvice implements ResponseBodyAdvice { @Override public boolean supports(MethodParameter methodParameter, Class aClass) { return true; }
@Override public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { log.info("-----beforeBodyWrite-----"); log.info("response parameter is {}", o.toString()); if (o instanceof Map) { ((Map) o).put("test", "test"); } return o; } }
|
@ControllerAdvice可以指定当前Advice生效的包路径,不指定默认全局生效。
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Slf4j @RestController @RequestMapping("/v1") public class TestController {
@RequestMapping(method = RequestMethod.POST, value = "/post") public ResponseEntity<?> post(@RequestBody Map<String, String> map) { log.info("begin /v1/post"); Map<String,String> rsp = new HashMap<>(); rsp.put("code","200"); rsp.put("msg","success"); log.info("end /v1/post"); return new ResponseEntity<>(rsp, HttpStatus.OK); }
}
|
测试结果
通过postman测试:
从返回的json数据中我们可以看到在GlobalResponseBodyAdvice.java的beforeBodyWrite()方法中对响应体多塞了一个test参数成功的返回到了前台。
结论:@ControllerAdvice+ResponseBodyAdvice可以全局对返回体进行拦截,进而可以帮助我们实现业务逻辑。