Commit eadc4f749a2452ab2c3705bcaf75fca32ee41a2d

Authored by YunaiV
1 parent 9c1c2659

替换带代码里所有 fastjson 的内容,统一使用 jackson

不考虑使用 gson 的原因,是基本停止了维护
... ... @@ -31,7 +31,6 @@
31 31 <!-- <swagger.version>2.9.2</swagger.version>-->
32 32 <!-- <kaptcha.version>2.3.2</kaptcha.version>-->
33 33 <!-- <pagehelper.boot.version>1.3.0</pagehelper.boot.version>-->
34   -<!-- <fastjson.version>1.2.74</fastjson.version>-->
35 34 <!-- <oshi.version>5.3.6</oshi.version>-->
36 35 <!-- <jna.version>5.6.0</jna.version>-->
37 36 <!-- <commons.io.version>2.5</commons.io.version>-->
... ... @@ -55,7 +54,6 @@
55 54 <lombok.version>1.16.14</lombok.version>
56 55 <mapstruct.version>1.4.1.Final</mapstruct.version>
57 56 <jjwt.version>0.9.1</jjwt.version>
58   - <fastjson.version>1.2.75</fastjson.version>
59 57 <hutool.version>5.5.6</hutool.version>
60 58 <easyexcel.verion>2.2.7</easyexcel.verion>
61 59 </properties>
... ... @@ -64,32 +62,6 @@
64 62 <dependencyManagement>
65 63 <dependencies>
66 64  
67   -<!-- &lt;!&ndash; 解析客户端操作系统、浏览器等 &ndash;&gt;-->
68   -<!-- <dependency>-->
69   -<!-- <groupId>eu.bitwalker</groupId>-->
70   -<!-- <artifactId>UserAgentUtils</artifactId>-->
71   -<!-- <version>${bitwalker.version}</version>-->
72   -<!-- </dependency>-->
73   -
74   -<!-- &lt;!&ndash; 获取系统信息 &ndash;&gt;-->
75   -<!-- <dependency>-->
76   -<!-- <groupId>com.github.oshi</groupId>-->
77   -<!-- <artifactId>oshi-core</artifactId>-->
78   -<!-- <version>${oshi.version}</version>-->
79   -<!-- </dependency>-->
80   -
81   -<!-- <dependency>-->
82   -<!-- <groupId>net.java.dev.jna</groupId>-->
83   -<!-- <artifactId>jna</artifactId>-->
84   -<!-- <version>${jna.version}</version>-->
85   -<!-- </dependency>-->
86   -
87   -<!-- <dependency>-->
88   -<!-- <groupId>net.java.dev.jna</groupId>-->
89   -<!-- <artifactId>jna-platform</artifactId>-->
90   -<!-- <version>${jna.version}</version>-->
91   -<!-- </dependency>-->
92   -
93 65 <!-- &lt;!&ndash;velocity代码生成使用模板 &ndash;&gt;-->
94 66 <!-- <dependency>-->
95 67 <!-- <groupId>org.apache.velocity</groupId>-->
... ... @@ -212,25 +184,12 @@
212 184 </dependency>
213 185  
214 186 <dependency>
215   - <groupId>com.alibaba</groupId>
216   - <artifactId>fastjson</artifactId>
217   - <version>${fastjson.version}</version>
218   - </dependency>
219   -
220   - <dependency>
221 187 <groupId>org.projectlombok</groupId>
222 188 <artifactId>lombok</artifactId>
223 189 <version>${lombok.version}</version>
224 190 </dependency>
225 191  
226 192 <dependency>
227   - <!-- 解析客户端操作系统、浏览器等 TODO 芋艿:后面看看 hutool 有没替代 -->
228   - <groupId>eu.bitwalker</groupId>
229   - <artifactId>UserAgentUtils</artifactId>
230   - <version>1.21</version>
231   - </dependency>
232   -
233   - <dependency>
234 193 <groupId>org.mapstruct</groupId>
235 194 <artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
236 195 <version>${mapstruct.version}</version>
... ...
ruoyi-ui/src/utils/request.js
... ... @@ -61,9 +61,10 @@ service.interceptors.response.use(res =&gt; {
61 61 }
62 62 ).then(() => {
63 63 store.dispatch('LogOut').then(() => {
64   - if (location.pathname !== '/login') { // 避免重复跳转
65   - location.href = '/index';
66   - }
  64 + // if (location.pathname !== '/login') { // 避免重复跳转
  65 + //
  66 + // }
  67 + location.href = '/index';
67 68 })
68 69 })
69 70 } else if (code === 500) {
... ...
src/main/java/cn/iocoder/dashboard/common/pojo/CommonResult.java
... ... @@ -4,7 +4,6 @@ import cn.iocoder.dashboard.common.exception.ErrorCode;
4 4 import cn.iocoder.dashboard.common.exception.GlobalException;
5 5 import cn.iocoder.dashboard.common.exception.ServiceException;
6 6 import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
7   -import com.alibaba.fastjson.annotation.JSONField;
8 7 import com.fasterxml.jackson.annotation.JsonIgnore;
9 8 import lombok.Data;
10 9 import org.springframework.util.Assert;
... ... @@ -69,13 +68,11 @@ public final class CommonResult&lt;T&gt; implements Serializable {
69 68 return result;
70 69 }
71 70  
72   - @JSONField(serialize = false) // 避免 fastjson 序列化
73 71 @JsonIgnore // 避免 jackson 序列化
74 72 public boolean isSuccess() {
75 73 return GlobalErrorCodeConstants.SUCCESS.getCode().equals(code);
76 74 }
77 75  
78   - @JSONField(serialize = false) // 避免 fastjson 序列化
79 76 @JsonIgnore // 避免 jackson 序列化
80 77 public boolean isError() {
81 78 return !isSuccess();
... ...
src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/aop/OperateLogAspect.java
... ... @@ -11,8 +11,8 @@ import cn.iocoder.dashboard.framework.logger.operatelog.core.service.OperateLogF
11 11 import cn.iocoder.dashboard.framework.security.core.util.SecurityUtils;
12 12 import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils;
13 13 import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogCreateReqVO;
  14 +import cn.iocoder.dashboard.util.json.JSONUtils;
14 15 import cn.iocoder.dashboard.util.servlet.ServletUtils;
15   -import com.alibaba.fastjson.JSON;
16 16 import com.google.common.collect.Maps;
17 17 import io.swagger.annotations.Api;
18 18 import io.swagger.annotations.ApiOperation;
... ... @@ -319,7 +319,7 @@ public class OperateLogAspect {
319 319 // 被忽略时,标记为 ignore 字符串,避免和 null 混在一起
320 320 args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]");
321 321 }
322   - return JSON.toJSONString(args);
  322 + return JSONUtils.toJSONString(args);
323 323 }
324 324  
325 325 private static String obtainResultData(Object result) {
... ... @@ -327,7 +327,7 @@ public class OperateLogAspect {
327 327 if (result instanceof CommonResult) {
328 328 result = ((CommonResult<?>) result).getData();
329 329 }
330   - return JSON.toJSONString(result);
  330 + return JSONUtils.toJSONString(result);
331 331 }
332 332  
333 333 private static boolean isIgnoreArgs(Object object) {
... ...
src/main/java/cn/iocoder/dashboard/framework/mybatis/core/type/JacksonLongSetTypeHandler.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.mybatis.core.type;
  2 +
  3 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
  4 +import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
  5 +import com.fasterxml.jackson.core.JsonProcessingException;
  6 +import com.fasterxml.jackson.core.type.TypeReference;
  7 +import com.fasterxml.jackson.databind.ObjectMapper;
  8 +
  9 +import java.io.IOException;
  10 +import java.util.Set;
  11 +
  12 +/**
  13 + * 参考 {@link com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler} 实现
  14 + * 在我们将字符串反序列化为 Set 并且泛型为 Long 时,如果每个元素的数值太小,会被处理成 Integer 类型,导致可能存在隐性的 BUG。
  15 + *
  16 + * 例如说哦,{@link SysUserDO#getPostIds()} 属性
  17 + *
  18 + * @author 芋道源码
  19 + */
  20 +public class JacksonLongSetTypeHandler extends AbstractJsonTypeHandler<Object> {
  21 +
  22 + // TODO 芋艿,需要将 Spring 的设置下进来
  23 + private static final ObjectMapper objectMapper = new ObjectMapper();
  24 +
  25 + private static final TypeReference<Set<Long>> typeReference = new TypeReference<Set<Long>>(){};
  26 +
  27 + @Override
  28 + protected Object parse(String json) {
  29 + try {
  30 + return objectMapper.readValue(json, typeReference);
  31 + } catch (IOException e) {
  32 + throw new RuntimeException(e);
  33 + }
  34 + }
  35 +
  36 + @Override
  37 + protected String toJson(Object obj) {
  38 + try {
  39 + return objectMapper.writeValueAsString(obj);
  40 + } catch (JsonProcessingException e) {
  41 + throw new RuntimeException(e);
  42 + }
  43 + }
  44 +
  45 +}
... ...
src/main/java/cn/iocoder/dashboard/framework/redis/config/RedisConfig.java
1 1 package cn.iocoder.dashboard.framework.redis.config;
2 2  
3 3 import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener;
4   -import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
5 4 import lombok.extern.slf4j.Slf4j;
6 5 import org.springframework.context.annotation.Bean;
7 6 import org.springframework.context.annotation.Configuration;
... ... @@ -29,7 +28,7 @@ public class RedisConfig {
29 28 // 使用 String 序列化方式,序列化 KEY 。
30 29 template.setKeySerializer(RedisSerializer.string());
31 30 // 使用 JSON 序列化方式(库是 FastJSON ),序列化 VALUE 。
32   - template.setValueSerializer(new GenericFastJsonRedisSerializer());
  31 + template.setValueSerializer(RedisSerializer.json());
33 32 return template;
34 33 }
35 34  
... ...
src/main/java/cn/iocoder/dashboard/framework/redis/core/pubsub/ChannelMessage.java
1 1 package cn.iocoder.dashboard.framework.redis.core.pubsub;
2 2  
3   -import com.alibaba.fastjson.annotation.JSONField;
  3 +import com.fasterxml.jackson.annotation.JsonIgnore;
4 4  
5 5 /**
6 6 * Redis Channel Message 接口
... ... @@ -12,7 +12,7 @@ public interface ChannelMessage {
12 12 *
13 13 * @return Channel
14 14 */
15   - @JSONField(serialize = false) // 必须序列化
  15 + @JsonIgnore // 必须序列化
16 16 String getChannel();
17 17  
18 18 }
... ...
src/main/java/cn/iocoder/dashboard/framework/security/core/LoginUser.java
1 1 package cn.iocoder.dashboard.framework.security.core;
2 2  
3 3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
4   -import com.alibaba.fastjson.annotation.JSONField;
  4 +import com.fasterxml.jackson.annotation.JsonIgnore;
5 5 import lombok.Data;
6 6 import org.springframework.security.core.GrantedAuthority;
7 7 import org.springframework.security.core.userdetails.UserDetails;
... ... @@ -49,43 +49,43 @@ public class LoginUser implements UserDetails {
49 49 private Integer status;
50 50  
51 51 @Override
52   - @JSONField(serialize = false) // 避免序列化
  52 + @JsonIgnore// 避免序列化
53 53 public String getPassword() {
54 54 return password;
55 55 }
56 56  
57 57 @Override
58   - @JSONField(serialize = false) // 避免序列化
  58 + @JsonIgnore
59 59 public String getUsername() {
60 60 return username;
61 61 }
62 62  
63 63 @Override
64   - @JSONField(serialize = false) // 避免序列化
  64 + @JsonIgnore// 避免序列化
65 65 public boolean isEnabled() {
66 66 return CommonStatusEnum.ENABLE.getStatus().equals(status);
67 67 }
68 68  
69 69 @Override
70   - @JSONField(serialize = false) // 避免序列化
  70 + @JsonIgnore// 避免序列化
71 71 public Collection<? extends GrantedAuthority> getAuthorities() {
72 72 return null;
73 73 }
74 74  
75 75 @Override
76   - @JSONField(serialize = false) // 避免序列化
  76 + @JsonIgnore// 避免序列化
77 77 public boolean isAccountNonExpired() {
78 78 return true; // 返回 true,不依赖 Spring Security 判断
79 79 }
80 80  
81 81 @Override
82   - @JSONField(serialize = false) // 避免序列化
  82 + @JsonIgnore// 避免序列化
83 83 public boolean isAccountNonLocked() {
84 84 return true; // 返回 true,不依赖 Spring Security 判断
85 85 }
86 86  
87 87 @Override
88   - @JSONField(serialize = false) // 避免序列化
  88 + @JsonIgnore// 避免序列化
89 89 public boolean isCredentialsNonExpired() {
90 90 return true; // 返回 true,不依赖 Spring Security 判断
91 91 }
... ...
src/main/java/cn/iocoder/dashboard/framework/web/config/WebConfiguration.java
1 1 package cn.iocoder.dashboard.framework.web.config;
2 2  
3   -import cn.iocoder.dashboard.util.servlet.ServletUtils;
4   -import com.alibaba.fastjson.serializer.SerializerFeature;
5   -import com.alibaba.fastjson.support.config.FastJsonConfig;
6   -import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
7 3 import org.springframework.boot.context.properties.EnableConfigurationProperties;
8 4 import org.springframework.context.annotation.Bean;
9 5 import org.springframework.context.annotation.Configuration;
10 6 import org.springframework.core.annotation.Order;
11   -import org.springframework.http.MediaType;
12   -import org.springframework.http.converter.HttpMessageConverter;
13 7 import org.springframework.web.bind.annotation.RestController;
14 8 import org.springframework.web.cors.CorsConfiguration;
15 9 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
... ... @@ -18,10 +12,6 @@ import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
18 12 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
19 13  
20 14 import javax.annotation.Resource;
21   -import javax.servlet.http.HttpServletRequest;
22   -import java.nio.charset.Charset;
23   -import java.util.Collections;
24   -import java.util.List;
25 15  
26 16 /**
27 17 * Web 配置类
... ... @@ -40,46 +30,6 @@ public class WebConfiguration implements WebMvcConfigurer {
40 30 && clazz.getPackage().getName().startsWith(webProperties.getControllerPackage()));
41 31 }
42 32  
43   - // ========== MessageConverter 相关 ==========
44   -
45   - @Override
46   - public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
47   - // 创建 FastJsonHttpMessageConverter 对象
48   - // 重写 canRead 和 canWrite 方法,判断只处理自己写的 API 为前缀的 URL。原因是,FastJSON 和一些三方框架集成存在问题,例如说:
49   - // 1. 与 Spring Boot Admin 时,由于 Registration 基于 Builder 构造对象,导致它无法反序列化
50   - // 2. 与 Spring Boot Actuator 时,貌似也存在问题,具体还没去排查。
51   - // 但是,为什么不替换回 Jackson 呢?
52   - // 原因是,一些 Number 数值比较小时,反序列化回来是 Integer 类型,实际是 Long 类型。此时,在序列化时,会报 Integer 无法转换成 Long 的异常
53   - FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter() {
54   -
55   - @Override
56   - protected boolean canRead(MediaType mediaType) {
57   - return isApiPrefix() && super.canRead(mediaType);
58   - }
59   -
60   - @Override
61   - protected boolean canWrite(MediaType mediaType) {
62   - return isApiPrefix() && super.canWrite(mediaType);
63   - }
64   -
65   - private boolean isApiPrefix() {
66   - HttpServletRequest request = ServletUtils.getRequest();
67   - return request != null && request.getRequestURI().startsWith(webProperties.getApiPrefix());
68   - }
69   -
70   - };
71   - // 自定义 FastJson 配置
72   - FastJsonConfig fastJsonConfig = new FastJsonConfig();
73   - fastJsonConfig.setCharset(Charset.defaultCharset()); // 设置字符集
74   - fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect, // 剔除循环引用
75   - SerializerFeature.WriteNonStringKeyAsString); // 解决 Integer 作为 Key 时,转换为 String 类型,避免浏览器报错
76   - fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
77   - // 设置支持的 MediaType
78   - fastJsonHttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
79   - // 添加到 converters 中
80   - converters.add(0, fastJsonHttpMessageConverter); // 注意,添加到最开头,放在 MappingJackson2XmlHttpMessageConverter 前面
81   - }
82   -
83 33 // ========== Filter 相关 ==========
84 34  
85 35 /**
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/logger/SysOperateLogDO.java
1 1 package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger;
2 2  
3 3 import cn.iocoder.dashboard.common.pojo.CommonResult;
  4 +import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum;
4 5 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
5 6 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
6   -import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum;
7 7 import com.baomidou.mybatisplus.annotation.TableField;
8 8 import com.baomidou.mybatisplus.annotation.TableId;
9 9 import com.baomidou.mybatisplus.annotation.TableName;
10   -import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
  10 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
11 11 import lombok.Data;
12 12 import lombok.EqualsAndHashCode;
13 13  
... ... @@ -75,7 +75,7 @@ public class SysOperateLogDO extends BaseDO {
75 75 * 拓展字段,有些复杂的业务,需要记录一些字段
76 76 * 例如说,记录订单编号,则可以添加 key 为 "orderId",value 为订单编号
77 77 */
78   - @TableField(typeHandler = FastjsonTypeHandler.class)
  78 + @TableField(typeHandler = JacksonTypeHandler.class)
79 79 private Map<String, Object> exts;
80 80  
81 81 /**
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/permission/SysRoleDO.java
... ... @@ -2,13 +2,13 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission;
2 2  
3 3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
  5 +import cn.iocoder.dashboard.framework.mybatis.core.type.JacksonLongSetTypeHandler;
5 6 import cn.iocoder.dashboard.framework.security.core.enums.DataScopeEnum;
6 7 import cn.iocoder.dashboard.modules.system.enums.permission.RoleCodeEnum;
7 8 import cn.iocoder.dashboard.modules.system.enums.permission.SysRoleTypeEnum;
8 9 import com.baomidou.mybatisplus.annotation.TableField;
9 10 import com.baomidou.mybatisplus.annotation.TableId;
10 11 import com.baomidou.mybatisplus.annotation.TableName;
11   -import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
12 12 import lombok.Data;
13 13 import lombok.EqualsAndHashCode;
14 14  
... ... @@ -71,7 +71,7 @@ public class SysRoleDO extends BaseDO {
71 71 *
72 72 * 适用于 {@link #dataScope} 的值为 {@link DataScopeEnum#DEPT_CUSTOM} 时
73 73 */
74   - @TableField(typeHandler = FastjsonTypeHandler.class)
  74 + @TableField(typeHandler = JacksonLongSetTypeHandler.class)
75 75 private Set<Long> dataScopeDeptIds;
76 76  
77 77 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/user/SysUserDO.java
... ... @@ -2,11 +2,11 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user;
2 2  
3 3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
  5 +import cn.iocoder.dashboard.framework.mybatis.core.type.JacksonLongSetTypeHandler;
5 6 import cn.iocoder.dashboard.modules.system.enums.common.SysSexEnum;
6 7 import com.baomidou.mybatisplus.annotation.TableField;
7 8 import com.baomidou.mybatisplus.annotation.TableId;
8 9 import com.baomidou.mybatisplus.annotation.TableName;
9   -import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
10 10 import lombok.Data;
11 11 import lombok.EqualsAndHashCode;
12 12 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
... ... @@ -54,7 +54,7 @@ public class SysUserDO extends BaseDO {
54 54 /**
55 55 * 岗位编号数组
56 56 */
57   - @TableField(typeHandler = FastjsonTypeHandler.class)
  57 + @TableField(typeHandler = JacksonLongSetTypeHandler.class)
58 58 private Set<Long> postIds;
59 59 /**
60 60 * 用户邮箱
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/auth/SysLoginUserRedisDAO.java
1 1 package cn.iocoder.dashboard.modules.system.dal.redis.dao.auth;
2 2  
3 3 import cn.iocoder.dashboard.framework.security.core.LoginUser;
4   -import com.alibaba.fastjson.JSON;
  4 +import cn.iocoder.dashboard.util.json.JSONUtils;
5 5 import org.springframework.data.redis.core.StringRedisTemplate;
6 6 import org.springframework.stereotype.Repository;
7 7  
... ... @@ -22,12 +22,12 @@ public class SysLoginUserRedisDAO {
22 22  
23 23 public LoginUser get(String sessionId) {
24 24 String redisKey = formatKey(sessionId);
25   - return JSON.parseObject(stringRedisTemplate.opsForValue().get(redisKey), LoginUser.class);
  25 + return JSONUtils.parseObject(stringRedisTemplate.opsForValue().get(redisKey), LoginUser.class);
26 26 }
27 27  
28 28 public void set(String sessionId, LoginUser loginUser) {
29 29 String redisKey = formatKey(sessionId);
30   - stringRedisTemplate.opsForValue().set(redisKey, JSON.toJSONString(loginUser), LOGIN_USER.getTimeout());
  30 + stringRedisTemplate.opsForValue().set(redisKey, JSONUtils.toJSONString(loginUser), LOGIN_USER.getTimeout());
31 31 }
32 32  
33 33 public void delete(String accessToken) {
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/common/SysCaptchaRedisDAO.java
1 1 package cn.iocoder.dashboard.modules.system.dal.redis.dao.common;
2 2  
3   -import cn.iocoder.dashboard.framework.security.core.LoginUser;
4   -import com.alibaba.fastjson.JSON;
5 3 import org.springframework.data.redis.core.StringRedisTemplate;
6 4 import org.springframework.stereotype.Repository;
7 5  
8 6 import javax.annotation.Resource;
9   -
10 7 import java.time.Duration;
11 8  
12 9 import static cn.iocoder.dashboard.modules.system.dal.redis.RedisKeyConstants.CAPTCHA_CODE;
... ...
src/main/java/cn/iocoder/dashboard/util/json/JSONUtils.java
1 1 package cn.iocoder.dashboard.util.json;
2 2  
3   -import com.alibaba.fastjson.JSON;
  3 +import com.fasterxml.jackson.core.JsonProcessingException;
  4 +import com.fasterxml.jackson.databind.ObjectMapper;
  5 +
  6 +import java.io.IOException;
4 7  
5 8 /**
6 9 * JSON 工具类
... ... @@ -9,16 +12,35 @@ import com.alibaba.fastjson.JSON;
9 12 */
10 13 public class JSONUtils {
11 14  
  15 + private static ObjectMapper objectMapper = new ObjectMapper();
  16 +
  17 + // TODO 芋艿,需要将 Spring 的设置下进来
  18 + public static void setObjectMapper(ObjectMapper objectMapper) {
  19 + JSONUtils.objectMapper = objectMapper;
  20 + }
  21 +
12 22 public static String toJSONString(Object object) {
13   - return JSON.toJSONString(object);
  23 + try {
  24 + return objectMapper.writeValueAsString(object);
  25 + } catch (JsonProcessingException e) {
  26 + throw new RuntimeException(e);
  27 + }
14 28 }
15 29  
16 30 public static <T> T parseObject(String text, Class<T> clazz) {
17   - return JSON.parseObject(text, clazz);
  31 + try {
  32 + return objectMapper.readValue(text, clazz);
  33 + } catch (IOException e) {
  34 + throw new RuntimeException(e);
  35 + }
18 36 }
19 37  
20 38 public static <T> T parseObject(byte[] bytes, Class<T> clazz) {
21   - return JSON.parseObject(bytes, clazz);
  39 + try {
  40 + return objectMapper.readValue(bytes, clazz);
  41 + } catch (IOException e) {
  42 + throw new RuntimeException(e);
  43 + }
22 44 }
23 45  
24 46 }
... ...
src/main/java/cn/iocoder/dashboard/util/servlet/ServletUtils.java
... ... @@ -2,7 +2,7 @@ package cn.iocoder.dashboard.util.servlet;
2 2  
3 3 import cn.hutool.core.io.IoUtil;
4 4 import cn.hutool.extra.servlet.ServletUtil;
5   -import com.alibaba.fastjson.JSON;
  5 +import cn.iocoder.dashboard.util.json.JSONUtils;
6 6 import org.springframework.http.MediaType;
7 7 import org.springframework.web.context.request.RequestAttributes;
8 8 import org.springframework.web.context.request.RequestContextHolder;
... ... @@ -28,7 +28,7 @@ public class ServletUtils {
28 28 */
29 29 @SuppressWarnings("deprecation") // 必须使用 APPLICATION_JSON_UTF8_VALUE,否则会乱码
30 30 public static void writeJSON(HttpServletResponse response, Object object) {
31   - String content = JSON.toJSONString(object);
  31 + String content = JSONUtils.toJSONString(object);
32 32 ServletUtil.write(response, content, MediaType.APPLICATION_JSON_UTF8_VALUE);
33 33 }
34 34  
... ...
src/main/resources/application.yaml
... ... @@ -31,6 +31,11 @@ spring:
31 31 url: http://127.0.0.1:8080/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址
32 32 # Spring Boot Admin Server 服务端的相关配置
33 33 context-path: /admin # 配置 Spring
  34 + # Jackson 配置项
  35 + jackson:
  36 + serialization:
  37 + write-dates-as-timestamps: true # 设置时间的格式,使用时间戳
  38 + write-date-timestamps-as-nanoseconds: false # 设置不使用 nanoseconds 的格式。例如说 1611460870.401,而是直接 1611460870401
34 39  
35 40 # 芋道配置项,设置当前项目所有自定义的配置
36 41 yudao:
... ...