首頁>技術>

@RestControllerAdvice是組合註解,它組合了@ControllerAdvice和@ResponseBody,它的功能和@ControllerAdvice一致,主要使用於對RESTful的請求體和返回體進行定製處理。

2.4.1 先處理請求體與後處理返回體

對請求體定製處理實現RequestBodyAdvice介面,它會在請求體進入控制器方法之前對請求體進行先處理;對返回體進行定製處理ResponseBodyAdvice,它會在控制器方法返回值確定之後對返回值進行後處理。他們和@RestControllerAdvice一起使用。

我們定義個註解,這個註解作為使用我們的定製功能的標記。

@Target({ElementType.PARAMETER, ElementType.METHOD}) //支援註解在方法引數和方法上@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ProcessTag {}

定製請求體的建言:

@RestControllerAdvicepublic class CustomRequestBodyAdvice implements RequestBodyAdvice {    @Override    public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {       return methodParameter.getParameterAnnotation(ProcessTag.class) != null; //1    }    @Override    public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {        return inputMessage; //2    }    @Override    public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {        if (body instanceof Person) {            Person person = (Person) body;            String upperCaseName = person.getName().toUpperCase();            return new Person(person.getId(), upperCaseName, person.getAge());        }        return body; //3    }    @Override    public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {        if(Person.class.isAssignableFrom((Class<?>) targetType)){            return new Person(new Random().nextLong(),"Nobody",-1);        }        return body; //4    }}
該請求體建言起效的條件,本例是請求體引數是否標記了@ProcessTag註解;在請求體讀取前,未做任何處理;在請求體讀取後,如果請求體型別是Person,將name轉為大寫;若不是Person保持不變;在處理請求體為空時,如果請求體型別是Person,建一個物件,否則保持不變。

定製的返回體處理建言:

@RestControllerAdvicepublic class CustomResponseBodyAdvice implements ResponseBodyAdvice {    @Override    public boolean supports(MethodParameter returnType, Class converterType) {        return returnType.hasMethodAnnotation(ProcessTag.class); //1    }    @Override    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {        if (body instanceof Person){            Map<String, Object> map = new HashMap<>();            map.put("person", body);            map.put("extra-response-body", "demo-body");            return map;        }        return body; //2    }}
該返回體建言起效的條件,本例是控制器方法上標記了@ProcessTag註解;在寫返回體前,我們將額外的資訊和body封裝到map裡返回;若不是Person型別則保持不變。

我們在控制裡驗證這兩個建言:

@GetMapping("/modifyBodies")@ProcessTag //標記定製返回體public Person modifyRequestBody(@ProcessTag @RequestBody Person person){ //標記定製請求體    return person;}

我們請求體不為空時請求:

我們請求體為空時請求:

6
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Web前端增強現實(AR)開發框架推薦大彙總 | 建議收藏