ResponseBodyAdvice是Spring MVC框架中的一个接口,用于全局处理Controller返回的响应数据。它提供了一个自定义处理响应体的机制,可以在响应体写出之前或者之后,对响应体进行额外的处理或者修改,是一种典型的AOP编程方式。
1、代码实现
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.scm.boss.common.utils.FieldListUtils;
import org.apache.commons.collections.CollectionUtils;
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.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.io.IOException;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
* 特殊数据权限过滤
* @date 2023/7/12 14:54
* @author luohao
*/
@Component
@RestControllerAdvice
public class BaseGlobalResponseBodyAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(final Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
if(ObjectUtils.isEmpty(body)){
return body;
}
//需要过滤的字段(可配置)
List<String> fieldList = FieldListUtils.getFieldList();
if(CollectionUtils.isEmpty(fieldList)){
return body;
}
SerializeConfig config = new SerializeConfig();
config.put( Date.class, new DateJsonSerializer());
return objectEval(JSONObject.parseObject(JSON.toJSONString(body,config)), fieldList);
}
/**
* 权限数据处理
* @param body
* @param nonPermAttrs
* @return
*/
public Object objectEval(Object body, List<String> nonPermAttrs) {
if (Objects.nonNull(body) && body instanceof Map) {
Map<String, Object> map = (Map<String, Object>) body;
map.keySet().forEach(key -> {
Object o = map.get(key);
if (Objects.nonNull(o) && o instanceof Map) {
map.put(key, objectEval(o, nonPermAttrs));
} else if (Objects.nonNull(o) && o instanceof List){
map.put(key, objectEval(o, nonPermAttrs));
}else {
List<String> collect = nonPermAttrs.stream().filter(i -> i.equals(key)).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(collect)){
map.put(key, null);
}
}
});
} else if (Objects.nonNull(body) && body instanceof List) {
final List<Object> dataList = (List<Object>) body;
dataList.forEach(i -> objectEval(i,nonPermAttrs));
}
return body;
}
}
/**
* 返回日期数据处理
* @date 2023/10/19 9:19
* @author luohao
*/
class DateJsonSerializer implements ObjectSerializer {
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.getWriter();
if (object == null) {
serializer.getWriter().writeNull();
return;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone( TimeZone.getTimeZone("Etc/GMT-8"));
out.write("\"" + sdf.format( (Date) object ) + "\"");
}
}