spring aop给返回值添加额外字段

1、默认情况下直接修改返回值为新对象时无法达到预期结果、但可通过序列化方式达到给原对象增加字段的目的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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、工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
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);
   }
}

  

 

 

posted @   漂渡  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示