自定义返回体封装之annotation+reflection+interceptor+@ControllerAdvice+ResponseBodyAdvice练习

通过springboot+自定义注解+反射+拦截器(或切面)+@ControllerAdvice+ResponseBodyAdvice对返回结果进行封装ResponseResult返回给前端。
代码示例:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResponseResult {
}
@Component
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private ResponseInterceptor responseInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(responseInterceptor).addPathPatterns("/**");
    }
}
@Component
public class ResponseInterceptor extends HandlerInterceptorAdapter {
    public static final String RESPONSE_RESULT_ANNOTATION = "RESPONSE_RESULT_ANNOTATION";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //请求的方法
        if (handler instanceof HandlerMethod) {
            final HandlerMethod handlerMethod = (HandlerMethod) handler;
            final Class<?> clazz = handlerMethod.getBeanType();
            final Method method = handlerMethod.getMethod();
            //判断是否在类对象或方法上面加了注解
            if (clazz.isAnnotationPresent(ResponseResult.class)) {//对象上面是否有注解
                //设置此请求返回体,需要包装,往下传递,在ResponseBodyAdvice接口进行判断
                request.setAttribute(RESPONSE_RESULT_ANNOTATION,clazz.getAnnotation(ResponseResult.class));
            } else if (method.isAnnotationPresent(ResponseResult.class)) {//方法体上是否有注解
                //设置此请求返回体,需要包装,往下传递,在ResponseBodyAdvice接口进行判断
                request.setAttribute(RESPONSE_RESULT_ANNOTATION,method.getAnnotation(ResponseResult.class));
            }
        }
        return true;
    }
}
@ControllerAdvice
//@RestControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {
    //标记名称
    public static final String RESPONSE_RESULT_ANNOTATION = "RESPONSE_RESULT_ANNOTATION";

    //是否请求了包含了包装注解标记,没有则直接返回,不需要重写返回体
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterType) {
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = sra.getRequest();
        //判断请求是否有包装标记
        ResponseResult responseResult = (ResponseResult) request.getAttribute(RESPONSE_RESULT_ANNOTATION);
        return responseResult == null ? false : true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType mediaType, Class<? extends HttpMessageConverter<?>> converterType, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        System.out.println("进入返回体,包装处理中...");
        return com.ldc.springboot_response.response.ResponseResult.success(body);
    }
}
public class ResponseResult<T> {

    private Boolean status = true; //状态
    private Integer code = 200; //响应吗
    private String message;//消息
    private T data;//返回的数据

    public ResponseResult() {
        super();
    }

    public ResponseResult(T data) {
        super();
        this.data = data;
    }

    public ResponseResult(T data, String message) {
        super();
        this.data = data;
        this.message=message;
    }

    public static ResponseResult success(Object data) {
        return new ResponseResult(data);
    }

    public static ResponseResult success(Object data, String message) {
        return new ResponseResult(data,message);
    }

    public static ResponseResult fail(String message) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setStatus(false);
        responseResult.setCode(400);
        responseResult.setMessage(message);
        responseResult.setData(null);
        return responseResult;
    }

    public static ResponseResult fail(String message, int code) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setStatus(false);
        responseResult.setCode(code);
        responseResult.setMessage(message);
        responseResult.setData(null);
        return responseResult;
    }

    public Boolean getStatus() {
        return status;
    }

    public void setStatus(Boolean status) {
        this.status = status;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

}

@com.ldc.springboot_response.annotation.ResponseResult
    @RequestMapping(value = "/get1", method = RequestMethod.POST)
    public ResponseResult get1(@RequestBody User user) {
        Long id = user.getId();
        String name = user.getName();
        Integer age = user.getAge();
        Date time = user.getTime();
        return ResponseResult.success(user);
    }

    //post请求
    @com.ldc.springboot_response.annotation.ResponseResult
    @RequestMapping(value = "/get2", method = RequestMethod.POST)
    public Object get2(@RequestBody  User user) {
        Long id = user.getId();
        String name = user.getName();
        Integer age = user.getAge();
        Date time = user.getTime();
        return user;
    }

执行结果如下:

{
    "status": true,
    "code": 200,
    "message": null,
    "data": {
        "id": 1,
        "name": "曹操",
        "age": 11,
        "time": null
    }
}

或使用切面进行返回体封装
代码示例:

@Component
@Aspect
public class ResponseResultAspect {

    @Around("@annotation(com.ldc.springboot_response.annotation.ResponseResult)")
    public Object doSetFieldValue(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //前置增强
        System.out.println("前置增强操作");
        Object result = proceedingJoinPoint.proceed();
        //后置增强
        System.out.println("后置增强操作");
        return ResponseResult.success(result);
        //return result;
    }

}

执行结果同上。
深刻理解其设计模式及加强练习使用方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值