关于用ResponseBodyAdvice对象解决无法获取ResponseBody返回数据的问题
在javaWeb中若Controller中返回的是ResponseBody则无法通过Interceptor拦截器的post方法对其返回数据进行处理。这里可以通过@ControllerAdvice & ResponseBodyAdvice 的方式对Response的body数据进行处理。具体使用见注解。
package com.dbh123.interceptor;
import cn.itcast.haoke.dubbo.api.controller.GraphQLController;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.time.Duration;
@ControllerAdvice
public class MyResponseBodyAdvice implements ResponseBodyAdvice {
@Autowired
private RedisTemplate<String, String> redisTemplate;
private ObjectMapper mapper = new ObjectMapper();
/**
* 通过返回值判断是否对结果进行拦截处理
* @param returnType 返回类型相关操作
* @param converterType
* @return true:拦截 false:不拦截
*/
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
//若返回的是Get请求则拦截
if (returnType.hasMethodAnnotation(GetMapping.class)){
return true;
}
//若返回的是Post请求且Controller对象的名称为GraphqlController则拦截
if (returnType.hasMethodAnnotation(PostMapping.class) &&
StringUtils.equals(GraphQLController.class.getName(),
returnType.getExecutable().getDeclaringClass().getName())) {
return true;
}
return false;
}
/**
* 对拦截Repose的处理
* @param body
* @param returnType
* @param selectedContentType
* @param selectedConverterType
* @param request
* @param response
* @return
*/
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
try {
//生成rediskey
String redisKey = MyUtils.createRedisKey(((ServletServerHttpRequest) request).getServletRequest());
String redisValue;
//若body为字符串
if(body instanceof String){
redisValue = (String)body;
}else{
//否则进行序列化操作
redisValue = mapper.writeValueAsString(body);
}
//写入Redis缓存
this.redisTemplate.opsForValue().set(redisKey,redisValue , Duration.ofHours(1));
} catch (Exception e) {
e.printStackTrace();
}
return body;
}
}