直接上代码
package com.XX.edu.advice;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.XX.edu.annotation.NotControllerResponseAdvice;
import com.XX.edu.common.bean.ResultTO;
import com.XX.edu.exception.APIException;
import com.XX.edu.exception.AppCode;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
* @description:对返回进行封装(response是ResultTO类型,或者注释了NotControllerResponseAdvice都不进行包装) 使用 @ControllerAdvice 和 实现ResponseBodyAdvice接口, 拦截Controller方法默认返回参数,统一处理返回值/响应体
* @author:
* @date: 2022/7/15 15:23
* @param: null
* @return:
**/
@RestControllerAdvice(basePackages = {"com.XX.edu"})
public class ControllerResponseAdvice implements ResponseBodyAdvice<Object> {
//supports对你需要进行拦截的response进行判断筛选,返回true则进行拦截反之放行
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
// response是ResultTO类型,或者注释了NotControllerResponseAdvice都不进行包装
return !(methodParameter.getParameterType().isAssignableFrom(ResultTO.class) || methodParameter.hasMethodAnnotation(NotControllerResponseAdvice.class));
}
//beforeBodyWrite对supports进行拦截的response进行处理,封装你需要的类型参数,加密等等
@Override
public Object beforeBodyWrite(Object data, MethodParameter returnType, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest request, ServerHttpResponse response) {
// String类型不能直接包装
if (returnType.getGenericParameterType().equals(String.class)) {
ObjectMapper objectMapper = new ObjectMapper();
try {
// 将数据包装在ResultTO里后转换为json串进行返回
return objectMapper.writeValueAsString(ResultTO.OK(data));
} catch (JsonProcessingException e) {
throw new APIException(AppCode.VALIDATE_ERROR, e.getMessage());
}
}
// 否则直接包装成ResultVo返回
return ResultTO.OK(data);
}
}
对于不想封装的返回如何处理??
自定义注解:
package com.XX.edu.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NotControllerResponseAdvice {
}
ControllerResponseAdvice实现ResponseBodyAdvice<Object>接口
在supports方法中处理,凡是有注解的都跳过封装,不进入beforeBodyWrite方法。
完成收工~~!!