RequestBodyAdvice
在进入Controller之前对请求做一些处理
请求顺序
supports
HttpInputMessage// 在请求体未读取(转换)时调用
supports
afterBodyRead// 在请求体完成读取后调用
Controller
handleEmptyBody// 当请求体为空时调用
通过RequestBodyAdvice,拦截Controller对request解密,签名验证处理
@ControllerAdvice
public class RequestAdvisor implements RequestBodyAdvice {
//先进入supports方法,如果返回false则不执行下面的方法,返回true则执行
@Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
//排除解密注解--包含@ExcludeHttpBodyDecrypt 返回false不执行
boolean methodHasExcludeHttpBodyDecrypt = methodParameter.hasMethodAnnotation(ExcludeHttpBodyDecrypt.class);
if (methodHasExcludeHttpBodyDecrypt) {
return false;
}
//解密注解--包含@HttpBodyDecrypt 返回true 需要执行
boolean methodHasHttpBodyDecrypt = methodParameter.hasMethodAnnotation(HttpBodyDecrypt.class);
if (methodHasHttpBodyDecrypt) {
return true;
}
//排除解密注解--声明类是否包含@ExcludeHttpBodyDecrypt 返回false不执行
boolean classHasExcludeHttpBodyDecrypt = methodParameter.getDeclaringClass().getAnnotation(ExcludeHttpBodyDecrypt.class) != null;
if (classHasExcludeHttpBodyDecrypt) {
return false;
}
boolean classHasHttpBodyDecrypt = methodParameter.getDeclaringClass().getAnnotation(HttpBodyDecrypt.class) != null;
if (classHasHttpBodyDecrypt) {
return true;
}
return false;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
if (inputMessage.getBody().available() <= 0) {
return inputMessage;
}
byte[] requestDataByte = new byte[inputMessage.getBody().available()];
inputMessage.getBody().read(requestDataByte);
byte[] requestDataByteNew = null;
try {
// 解密
requestDataByteNew = AESUtils.decryptHandler(requestDataByte);
} catch (Exception e) {
e.printStackTrace();
}
// 使用解密后的数据,构造新的读取流
InputStream rawInputStream = new ByteArrayInputStream(requestDataByteNew);
return new HttpInputMessage() {
@Override
public HttpHeaders getHeaders() {
return inputMessage.getHeaders();
}
@Override
public InputStream getBody() throws IOException {
return rawInputStream;
}
};
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
System.out.println("afterBodyRead");
return body;
}
@Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
System.out.println("handleEmptyBody");
return null;
}
}
ResponseBodyAdvice
返回数据之前进行一些处理
通过ResponseBodyAdvice,拦截Controller对Response封装,统一返回对象
@ControllerAdvice(basePackages = "...controller")
public class WrapRespAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
RespJson methodAnnotation = methodParameter.getMethodAnnotation(RespJson.class);
RespJson annotation = methodParameter.getDeclaringClass().getAnnotation(RespJson.class);
return methodAnnotation != null || annotation != null;
}
@Override
public Object beforeBodyWrite(Object resp, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if (methodParameter.getParameterType().equals(String.class)) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.writeValueAsString(Resp.success(resp));
} catch (JsonProcessingException e) {
throw new RuntimeException("String类型返回值异常");
}
}
return Resp.success(resp);
}
}