自定义注解

  • 定义注解类
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * 自定义统一返回值注解
 */
@Retention(RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
public @interface ResponseResult {
}

  • 拦截标记
/**
 * 公共的静态常量类
 */
public class CommonFinal {
    //由于处理统一返回值时打标记
    public static final String RESPONSE_RESULT_ANN="RESPONSE-RESULT-ANN";
}

  • 拦截器打标记

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

//请求拦截器
@Slf4j
@Component
public class ResponseResultInterceptor implements HandlerInterceptor {




//    代码核心思想,就是获取此请求,是否需要返回值包装,设置一个属性标记。
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        log.info("-------------进入拦截器打标记------");
        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(CommonFinal.RESPONSE_RESULT_ANN,clazz.getAnnotation(ResponseResult.class));
            }
            //判断方法上是否有注释
            else if(method.isAnnotationPresent(ResponseResult.class)){
                //设置此请求返回体,需要包装,往下传递,在ResponseBodyAdvice接口进行判断
                request.setAttribute(CommonFinal.RESPONSE_RESULT_ANN,method.getAnnotation(ResponseResult.class));
            }

        }
        return true;
    }

}

  • 判断

import lombok.extern.slf4j.Slf4j;
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.ControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * 上面代码就是判断是否需要返回值包装,如果需要就直接包装。这里我们只处理了正常成功的包装,如果方法体报异常怎么办?处理异常也比较简单,只要判断body是否为异常类。
 */
@Slf4j
@ControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice {



    //是否请求,包含了包装,注解,标记,没有就直接返回,不要重写返回体
    @Override
    public boolean supports(MethodParameter methodParameter, Class> aClass) {
//        log.info("判断是否打有标记 --------------------------");
        ServletRequestAttributes sra= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request=sra.getRequest();
        //判断请求是否包含标记
        ResponseResult responseResult= (ResponseResult) request.getAttribute(CommonFinal.RESPONSE_RESULT_ANN);
        return responseResult==null?false:true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
//        log.info("进入返回体 重写格式 处理中 --------------------------");
        return Result.success(body);
    }



}







你可能感兴趣的:(自定义注解)