spring aop给返回值添加额外字段
1、默认情况下直接修改返回值为新对象时无法达到预期结果、但可通过序列化方式达到给原对象增加字段的目的
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import cn.as.foundation.web.api.BusinessCode;
import cn.as.foundation.web.exception.BusinessException;
import cn.as.geekbidder.core.annotation.Dict;
import cn.as.geekbidder.core.util.JacksonTool;
import cn.as.maple.platform.api.model.User;
import cn.as.maple.platform.api.service.UserService;
import cn.as.maple.process.api.model.FlowTask;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.flowable.engine.TaskService;
import org.flowable.identitylink.api.IdentityLink;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@Aspect
@Component
@Slf4j
public class AddCurrentUser {
@Autowired
private TaskService taskService;
@Autowired
private UserService userService;
/**
* Pointcut
*/
@Pointcut("execution(* cn.togeek.maple.process.controller.FlowTaskController.*(..))")
public void joinPoint() {}
private void addOtherInfo(Object result) {
if (result instanceof IPage) {
List<ObjectNode> items = new ArrayList<>();
List<?> records = ((IPage<?>) result).getRecords();
if(CollectionUtils.isEmpty(records)) {
return;
}
for (Object record : records) {
ObjectNode item = doAdd(record);
items.add(item);
}
((IPage<ObjectNode>) result).setRecords(items);
}
}
public ObjectNode doAdd(Object record) {
//解决@JsonFormat注解解析不了的问题
String json = JacksonTool.object2String(record);
ObjectNode item = JacksonTool.string2Object(json, ObjectNode.class);
if(Objects.isNull(item)) {
throw new BusinessException(BusinessCode.SYSTEM_ERROR.getCode(), "返回值解析失败");
}
String taskId = (String) ReflectUtil.getFieldValue(record, "taskId");
List<IdentityLink> idList = this.taskService.getIdentityLinksForTask(taskId);
List<User> collect = idList.stream().map(e -> {
List<User> users;
if(e.getUserId() != null) {
users = userService.getUsersByIds(Collections.singletonList(e.getUserId()));
}
else {
users = userService.getUserByRole(e.getGroupId());
}
return users;
}).flatMap(Collection::stream).collect(Collectors.toList());
String users = collect.stream().map(User::getName).collect(Collectors.joining(","));
item.put("currentUser", users);
return item;
}
@AfterReturning(value = "joinPoint()", returning = "methodResult")
public void afterRt(JoinPoint jp, Object methodResult) {
addOtherInfo(methodResult);
}
}
2、工具类
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* json 工具类
* @author ludangxin
* @date 2021/4/1
*/
@Slf4j
public class JacksonTool {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private static final String STANDARD_PATTERN = "yyyy-MM-dd HH:mm:ss";
private static final String DATE_PATTERN = "yyyy-MM-dd";
private static final String TIME_PATTERN = "HH:mm:ss";
static {
//设置java.util.Date时间类的序列化以及反序列化的格式
OBJECT_MAPPER.setDateFormat(new SimpleDateFormat(STANDARD_PATTERN));
// 初始化JavaTimeModule
JavaTimeModule javaTimeModule = new JavaTimeModule();
//处理LocalDateTime
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(STANDARD_PATTERN);
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));
//处理LocalDate
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter));
//处理LocalTime
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(TIME_PATTERN);
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(timeFormatter));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(timeFormatter));
//处理Long
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
OBJECT_MAPPER.registerModule(simpleModule);
//注册时间模块, 支持支持jsr310, 即新的时间类(java.time包下的时间类)
OBJECT_MAPPER.registerModule(javaTimeModule);
// 包含所有字段
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.ALWAYS);
// 在序列化一个空对象时时不抛出异常
OBJECT_MAPPER.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// 忽略反序列化时在json字符串中存在, 但在java对象中不存在的属性
OBJECT_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
public static <T> String object2String(T object) {
if(object == null) {
return null;
}
try {
return object instanceof String ? (String) object:OBJECT_MAPPER.writeValueAsString(object);
}
catch(IOException e) {
log.warn("Parse object to string error", e);
return null;
}
}
public static <T> String object2StringPretty(T object) {
if(object == null) {
return null;
}
try {
return object instanceof String ? (String) object:OBJECT_MAPPER.writerWithDefaultPrettyPrinter()
.writeValueAsString(object);
}
catch(IOException e) {
log.warn("Parse object to string error", e);
return null;
}
}
public static <T> T string2Object(String str, Class<T> clazz) {
if(StringUtils.isEmpty(str) || clazz == null) {
return null;
}
try {
return clazz.equals(String.class) ? (T) str : OBJECT_MAPPER.readValue(str, clazz);
}
catch(Exception e) {
log.warn("Parse String to object error!", e);
return null;
}
}
public static <T> T string2Object(String str, TypeReference<T> typeReference) {
if(StringUtils.isEmpty(str) || typeReference == null) {
return null;
}
try {
return typeReference.getType().equals(String.class) ? (T)str : OBJECT_MAPPER.readValue(str, typeReference);
}
catch(Exception e) {
log.warn("Parse String to object error!", e);
return null;
}
}
public static <T> T string2Object(String str, Class<?> collectionClass, Class<?>... elementClass) {
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClass, elementClass);
try {
return OBJECT_MAPPER.readValue(str, javaType);
}
catch(Exception e) {
log.warn("Parse String to object error!", e);
return null;
}
}
/**
* 把对象转换为有序map,在序列化时确保对象的顺序和属性编排时一致
*/
public static Map<String, Object> objectToLinkedHashMap(Object obj) {
if(null == obj) {
return Maps.newHashMap();
}
return objectToLikedMap(obj);
}
public static LinkedHashMap<String, Object> objectToLikedMap(Object data) {
try {
return string2Object(object2String(data), LinkedHashMap.class);
}
catch(Exception e) {
return Maps.newLinkedHashMap();
}
}
/**
* json字符串转成list
*
* @param jsonString
* @param cls
* @return
*/
public static <T> List<T> jsonToList(String jsonString, Class<T> cls) {
try {
return OBJECT_MAPPER.readValue(jsonString, getCollectionType(List.class, cls));
} catch (JsonProcessingException e) {
String className = cls.getSimpleName();
log.error(" parse json [{}] to class [{}] error:{}", jsonString, className, e);
}
return null;
}
/**
* 获取泛型的Collection Type
*
* @param collectionClass 泛型的Collection
* @param elementClasses 实体bean
* @return JavaType Java类型
*/
private static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
return OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClass, elementClasses);
}
}

浙公网安备 33010602011771号