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<Object> {
//是否请求,包含了包装,注解,标记,没有就直接返回,不要重写返回体
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> 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<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
// log.info("进入返回体 重写格式 处理中 --------------------------");
return Result.success(body);
}
}
网友评论