Commit eadc4f749a2452ab2c3705bcaf75fca32ee41a2d

Authored by YunaiV
1 parent 9c1c2659

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

不考虑使用 gson 的原因,是基本停止了维护
@@ -31,7 +31,6 @@ @@ -31,7 +31,6 @@
31 <!-- <swagger.version>2.9.2</swagger.version>--> 31 <!-- <swagger.version>2.9.2</swagger.version>-->
32 <!-- <kaptcha.version>2.3.2</kaptcha.version>--> 32 <!-- <kaptcha.version>2.3.2</kaptcha.version>-->
33 <!-- <pagehelper.boot.version>1.3.0</pagehelper.boot.version>--> 33 <!-- <pagehelper.boot.version>1.3.0</pagehelper.boot.version>-->
34 -<!-- <fastjson.version>1.2.74</fastjson.version>-->  
35 <!-- <oshi.version>5.3.6</oshi.version>--> 34 <!-- <oshi.version>5.3.6</oshi.version>-->
36 <!-- <jna.version>5.6.0</jna.version>--> 35 <!-- <jna.version>5.6.0</jna.version>-->
37 <!-- <commons.io.version>2.5</commons.io.version>--> 36 <!-- <commons.io.version>2.5</commons.io.version>-->
@@ -55,7 +54,6 @@ @@ -55,7 +54,6 @@
55 <lombok.version>1.16.14</lombok.version> 54 <lombok.version>1.16.14</lombok.version>
56 <mapstruct.version>1.4.1.Final</mapstruct.version> 55 <mapstruct.version>1.4.1.Final</mapstruct.version>
57 <jjwt.version>0.9.1</jjwt.version> 56 <jjwt.version>0.9.1</jjwt.version>
58 - <fastjson.version>1.2.75</fastjson.version>  
59 <hutool.version>5.5.6</hutool.version> 57 <hutool.version>5.5.6</hutool.version>
60 <easyexcel.verion>2.2.7</easyexcel.verion> 58 <easyexcel.verion>2.2.7</easyexcel.verion>
61 </properties> 59 </properties>
@@ -64,32 +62,6 @@ @@ -64,32 +62,6 @@
64 <dependencyManagement> 62 <dependencyManagement>
65 <dependencies> 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 <!-- &lt;!&ndash;velocity代码生成使用模板 &ndash;&gt;--> 65 <!-- &lt;!&ndash;velocity代码生成使用模板 &ndash;&gt;-->
94 <!-- <dependency>--> 66 <!-- <dependency>-->
95 <!-- <groupId>org.apache.velocity</groupId>--> 67 <!-- <groupId>org.apache.velocity</groupId>-->
@@ -212,25 +184,12 @@ @@ -212,25 +184,12 @@
212 </dependency> 184 </dependency>
213 185
214 <dependency> 186 <dependency>
215 - <groupId>com.alibaba</groupId>  
216 - <artifactId>fastjson</artifactId>  
217 - <version>${fastjson.version}</version>  
218 - </dependency>  
219 -  
220 - <dependency>  
221 <groupId>org.projectlombok</groupId> 187 <groupId>org.projectlombok</groupId>
222 <artifactId>lombok</artifactId> 188 <artifactId>lombok</artifactId>
223 <version>${lombok.version}</version> 189 <version>${lombok.version}</version>
224 </dependency> 190 </dependency>
225 191
226 <dependency> 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 <groupId>org.mapstruct</groupId> 193 <groupId>org.mapstruct</groupId>
235 <artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher --> 194 <artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
236 <version>${mapstruct.version}</version> 195 <version>${mapstruct.version}</version>
ruoyi-ui/src/utils/request.js
@@ -61,9 +61,10 @@ service.interceptors.response.use(res =&gt; { @@ -61,9 +61,10 @@ service.interceptors.response.use(res =&gt; {
61 } 61 }
62 ).then(() => { 62 ).then(() => {
63 store.dispatch('LogOut').then(() => { 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 } else if (code === 500) { 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,7 +4,6 @@ import cn.iocoder.dashboard.common.exception.ErrorCode;
4 import cn.iocoder.dashboard.common.exception.GlobalException; 4 import cn.iocoder.dashboard.common.exception.GlobalException;
5 import cn.iocoder.dashboard.common.exception.ServiceException; 5 import cn.iocoder.dashboard.common.exception.ServiceException;
6 import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants; 6 import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
7 -import com.alibaba.fastjson.annotation.JSONField;  
8 import com.fasterxml.jackson.annotation.JsonIgnore; 7 import com.fasterxml.jackson.annotation.JsonIgnore;
9 import lombok.Data; 8 import lombok.Data;
10 import org.springframework.util.Assert; 9 import org.springframework.util.Assert;
@@ -69,13 +68,11 @@ public final class CommonResult&lt;T&gt; implements Serializable { @@ -69,13 +68,11 @@ public final class CommonResult&lt;T&gt; implements Serializable {
69 return result; 68 return result;
70 } 69 }
71 70
72 - @JSONField(serialize = false) // 避免 fastjson 序列化  
73 @JsonIgnore // 避免 jackson 序列化 71 @JsonIgnore // 避免 jackson 序列化
74 public boolean isSuccess() { 72 public boolean isSuccess() {
75 return GlobalErrorCodeConstants.SUCCESS.getCode().equals(code); 73 return GlobalErrorCodeConstants.SUCCESS.getCode().equals(code);
76 } 74 }
77 75
78 - @JSONField(serialize = false) // 避免 fastjson 序列化  
79 @JsonIgnore // 避免 jackson 序列化 76 @JsonIgnore // 避免 jackson 序列化
80 public boolean isError() { 77 public boolean isError() {
81 return !isSuccess(); 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,8 +11,8 @@ import cn.iocoder.dashboard.framework.logger.operatelog.core.service.OperateLogF
11 import cn.iocoder.dashboard.framework.security.core.util.SecurityUtils; 11 import cn.iocoder.dashboard.framework.security.core.util.SecurityUtils;
12 import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils; 12 import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils;
13 import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogCreateReqVO; 13 import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogCreateReqVO;
  14 +import cn.iocoder.dashboard.util.json.JSONUtils;
14 import cn.iocoder.dashboard.util.servlet.ServletUtils; 15 import cn.iocoder.dashboard.util.servlet.ServletUtils;
15 -import com.alibaba.fastjson.JSON;  
16 import com.google.common.collect.Maps; 16 import com.google.common.collect.Maps;
17 import io.swagger.annotations.Api; 17 import io.swagger.annotations.Api;
18 import io.swagger.annotations.ApiOperation; 18 import io.swagger.annotations.ApiOperation;
@@ -319,7 +319,7 @@ public class OperateLogAspect { @@ -319,7 +319,7 @@ public class OperateLogAspect {
319 // 被忽略时,标记为 ignore 字符串,避免和 null 混在一起 319 // 被忽略时,标记为 ignore 字符串,避免和 null 混在一起
320 args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]"); 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 private static String obtainResultData(Object result) { 325 private static String obtainResultData(Object result) {
@@ -327,7 +327,7 @@ public class OperateLogAspect { @@ -327,7 +327,7 @@ public class OperateLogAspect {
327 if (result instanceof CommonResult) { 327 if (result instanceof CommonResult) {
328 result = ((CommonResult<?>) result).getData(); 328 result = ((CommonResult<?>) result).getData();
329 } 329 }
330 - return JSON.toJSONString(result); 330 + return JSONUtils.toJSONString(result);
331 } 331 }
332 332
333 private static boolean isIgnoreArgs(Object object) { 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 package cn.iocoder.dashboard.framework.redis.config; 1 package cn.iocoder.dashboard.framework.redis.config;
2 2
3 import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; 3 import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener;
4 -import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;  
5 import lombok.extern.slf4j.Slf4j; 4 import lombok.extern.slf4j.Slf4j;
6 import org.springframework.context.annotation.Bean; 5 import org.springframework.context.annotation.Bean;
7 import org.springframework.context.annotation.Configuration; 6 import org.springframework.context.annotation.Configuration;
@@ -29,7 +28,7 @@ public class RedisConfig { @@ -29,7 +28,7 @@ public class RedisConfig {
29 // 使用 String 序列化方式,序列化 KEY 。 28 // 使用 String 序列化方式,序列化 KEY 。
30 template.setKeySerializer(RedisSerializer.string()); 29 template.setKeySerializer(RedisSerializer.string());
31 // 使用 JSON 序列化方式(库是 FastJSON ),序列化 VALUE 。 30 // 使用 JSON 序列化方式(库是 FastJSON ),序列化 VALUE 。
32 - template.setValueSerializer(new GenericFastJsonRedisSerializer()); 31 + template.setValueSerializer(RedisSerializer.json());
33 return template; 32 return template;
34 } 33 }
35 34
src/main/java/cn/iocoder/dashboard/framework/redis/core/pubsub/ChannelMessage.java
1 package cn.iocoder.dashboard.framework.redis.core.pubsub; 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 * Redis Channel Message 接口 6 * Redis Channel Message 接口
@@ -12,7 +12,7 @@ public interface ChannelMessage { @@ -12,7 +12,7 @@ public interface ChannelMessage {
12 * 12 *
13 * @return Channel 13 * @return Channel
14 */ 14 */
15 - @JSONField(serialize = false) // 必须序列化 15 + @JsonIgnore // 必须序列化
16 String getChannel(); 16 String getChannel();
17 17
18 } 18 }
src/main/java/cn/iocoder/dashboard/framework/security/core/LoginUser.java
1 package cn.iocoder.dashboard.framework.security.core; 1 package cn.iocoder.dashboard.framework.security.core;
2 2
3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum; 3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
4 -import com.alibaba.fastjson.annotation.JSONField; 4 +import com.fasterxml.jackson.annotation.JsonIgnore;
5 import lombok.Data; 5 import lombok.Data;
6 import org.springframework.security.core.GrantedAuthority; 6 import org.springframework.security.core.GrantedAuthority;
7 import org.springframework.security.core.userdetails.UserDetails; 7 import org.springframework.security.core.userdetails.UserDetails;
@@ -49,43 +49,43 @@ public class LoginUser implements UserDetails { @@ -49,43 +49,43 @@ public class LoginUser implements UserDetails {
49 private Integer status; 49 private Integer status;
50 50
51 @Override 51 @Override
52 - @JSONField(serialize = false) // 避免序列化 52 + @JsonIgnore// 避免序列化
53 public String getPassword() { 53 public String getPassword() {
54 return password; 54 return password;
55 } 55 }
56 56
57 @Override 57 @Override
58 - @JSONField(serialize = false) // 避免序列化 58 + @JsonIgnore
59 public String getUsername() { 59 public String getUsername() {
60 return username; 60 return username;
61 } 61 }
62 62
63 @Override 63 @Override
64 - @JSONField(serialize = false) // 避免序列化 64 + @JsonIgnore// 避免序列化
65 public boolean isEnabled() { 65 public boolean isEnabled() {
66 return CommonStatusEnum.ENABLE.getStatus().equals(status); 66 return CommonStatusEnum.ENABLE.getStatus().equals(status);
67 } 67 }
68 68
69 @Override 69 @Override
70 - @JSONField(serialize = false) // 避免序列化 70 + @JsonIgnore// 避免序列化
71 public Collection<? extends GrantedAuthority> getAuthorities() { 71 public Collection<? extends GrantedAuthority> getAuthorities() {
72 return null; 72 return null;
73 } 73 }
74 74
75 @Override 75 @Override
76 - @JSONField(serialize = false) // 避免序列化 76 + @JsonIgnore// 避免序列化
77 public boolean isAccountNonExpired() { 77 public boolean isAccountNonExpired() {
78 return true; // 返回 true,不依赖 Spring Security 判断 78 return true; // 返回 true,不依赖 Spring Security 判断
79 } 79 }
80 80
81 @Override 81 @Override
82 - @JSONField(serialize = false) // 避免序列化 82 + @JsonIgnore// 避免序列化
83 public boolean isAccountNonLocked() { 83 public boolean isAccountNonLocked() {
84 return true; // 返回 true,不依赖 Spring Security 判断 84 return true; // 返回 true,不依赖 Spring Security 判断
85 } 85 }
86 86
87 @Override 87 @Override
88 - @JSONField(serialize = false) // 避免序列化 88 + @JsonIgnore// 避免序列化
89 public boolean isCredentialsNonExpired() { 89 public boolean isCredentialsNonExpired() {
90 return true; // 返回 true,不依赖 Spring Security 判断 90 return true; // 返回 true,不依赖 Spring Security 判断
91 } 91 }
src/main/java/cn/iocoder/dashboard/framework/web/config/WebConfiguration.java
1 package cn.iocoder.dashboard.framework.web.config; 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 import org.springframework.boot.context.properties.EnableConfigurationProperties; 3 import org.springframework.boot.context.properties.EnableConfigurationProperties;
8 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Bean;
9 import org.springframework.context.annotation.Configuration; 5 import org.springframework.context.annotation.Configuration;
10 import org.springframework.core.annotation.Order; 6 import org.springframework.core.annotation.Order;
11 -import org.springframework.http.MediaType;  
12 -import org.springframework.http.converter.HttpMessageConverter;  
13 import org.springframework.web.bind.annotation.RestController; 7 import org.springframework.web.bind.annotation.RestController;
14 import org.springframework.web.cors.CorsConfiguration; 8 import org.springframework.web.cors.CorsConfiguration;
15 import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 9 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@@ -18,10 +12,6 @@ import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; @@ -18,10 +12,6 @@ import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
18 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 12 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
19 13
20 import javax.annotation.Resource; 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 * Web 配置类 17 * Web 配置类
@@ -40,46 +30,6 @@ public class WebConfiguration implements WebMvcConfigurer { @@ -40,46 +30,6 @@ public class WebConfiguration implements WebMvcConfigurer {
40 && clazz.getPackage().getName().startsWith(webProperties.getControllerPackage())); 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 // ========== Filter 相关 ========== 33 // ========== Filter 相关 ==========
84 34
85 /** 35 /**
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/logger/SysOperateLogDO.java
1 package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger; 1 package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger;
2 2
3 import cn.iocoder.dashboard.common.pojo.CommonResult; 3 import cn.iocoder.dashboard.common.pojo.CommonResult;
  4 +import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum;
4 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; 5 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
5 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; 6 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
6 -import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum;  
7 import com.baomidou.mybatisplus.annotation.TableField; 7 import com.baomidou.mybatisplus.annotation.TableField;
8 import com.baomidou.mybatisplus.annotation.TableId; 8 import com.baomidou.mybatisplus.annotation.TableId;
9 import com.baomidou.mybatisplus.annotation.TableName; 9 import com.baomidou.mybatisplus.annotation.TableName;
10 -import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; 10 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
11 import lombok.Data; 11 import lombok.Data;
12 import lombok.EqualsAndHashCode; 12 import lombok.EqualsAndHashCode;
13 13
@@ -75,7 +75,7 @@ public class SysOperateLogDO extends BaseDO { @@ -75,7 +75,7 @@ public class SysOperateLogDO extends BaseDO {
75 * 拓展字段,有些复杂的业务,需要记录一些字段 75 * 拓展字段,有些复杂的业务,需要记录一些字段
76 * 例如说,记录订单编号,则可以添加 key 为 "orderId",value 为订单编号 76 * 例如说,记录订单编号,则可以添加 key 为 "orderId",value 为订单编号
77 */ 77 */
78 - @TableField(typeHandler = FastjsonTypeHandler.class) 78 + @TableField(typeHandler = JacksonTypeHandler.class)
79 private Map<String, Object> exts; 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,13 +2,13 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission;
2 2
3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum; 3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
4 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
  5 +import cn.iocoder.dashboard.framework.mybatis.core.type.JacksonLongSetTypeHandler;
5 import cn.iocoder.dashboard.framework.security.core.enums.DataScopeEnum; 6 import cn.iocoder.dashboard.framework.security.core.enums.DataScopeEnum;
6 import cn.iocoder.dashboard.modules.system.enums.permission.RoleCodeEnum; 7 import cn.iocoder.dashboard.modules.system.enums.permission.RoleCodeEnum;
7 import cn.iocoder.dashboard.modules.system.enums.permission.SysRoleTypeEnum; 8 import cn.iocoder.dashboard.modules.system.enums.permission.SysRoleTypeEnum;
8 import com.baomidou.mybatisplus.annotation.TableField; 9 import com.baomidou.mybatisplus.annotation.TableField;
9 import com.baomidou.mybatisplus.annotation.TableId; 10 import com.baomidou.mybatisplus.annotation.TableId;
10 import com.baomidou.mybatisplus.annotation.TableName; 11 import com.baomidou.mybatisplus.annotation.TableName;
11 -import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;  
12 import lombok.Data; 12 import lombok.Data;
13 import lombok.EqualsAndHashCode; 13 import lombok.EqualsAndHashCode;
14 14
@@ -71,7 +71,7 @@ public class SysRoleDO extends BaseDO { @@ -71,7 +71,7 @@ public class SysRoleDO extends BaseDO {
71 * 71 *
72 * 适用于 {@link #dataScope} 的值为 {@link DataScopeEnum#DEPT_CUSTOM} 时 72 * 适用于 {@link #dataScope} 的值为 {@link DataScopeEnum#DEPT_CUSTOM} 时
73 */ 73 */
74 - @TableField(typeHandler = FastjsonTypeHandler.class) 74 + @TableField(typeHandler = JacksonLongSetTypeHandler.class)
75 private Set<Long> dataScopeDeptIds; 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,11 +2,11 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user;
2 2
3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum; 3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
4 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
  5 +import cn.iocoder.dashboard.framework.mybatis.core.type.JacksonLongSetTypeHandler;
5 import cn.iocoder.dashboard.modules.system.enums.common.SysSexEnum; 6 import cn.iocoder.dashboard.modules.system.enums.common.SysSexEnum;
6 import com.baomidou.mybatisplus.annotation.TableField; 7 import com.baomidou.mybatisplus.annotation.TableField;
7 import com.baomidou.mybatisplus.annotation.TableId; 8 import com.baomidou.mybatisplus.annotation.TableId;
8 import com.baomidou.mybatisplus.annotation.TableName; 9 import com.baomidou.mybatisplus.annotation.TableName;
9 -import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;  
10 import lombok.Data; 10 import lombok.Data;
11 import lombok.EqualsAndHashCode; 11 import lombok.EqualsAndHashCode;
12 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 12 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@@ -54,7 +54,7 @@ public class SysUserDO extends BaseDO { @@ -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 private Set<Long> postIds; 58 private Set<Long> postIds;
59 /** 59 /**
60 * 用户邮箱 60 * 用户邮箱
src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/auth/SysLoginUserRedisDAO.java
1 package cn.iocoder.dashboard.modules.system.dal.redis.dao.auth; 1 package cn.iocoder.dashboard.modules.system.dal.redis.dao.auth;
2 2
3 import cn.iocoder.dashboard.framework.security.core.LoginUser; 3 import cn.iocoder.dashboard.framework.security.core.LoginUser;
4 -import com.alibaba.fastjson.JSON; 4 +import cn.iocoder.dashboard.util.json.JSONUtils;
5 import org.springframework.data.redis.core.StringRedisTemplate; 5 import org.springframework.data.redis.core.StringRedisTemplate;
6 import org.springframework.stereotype.Repository; 6 import org.springframework.stereotype.Repository;
7 7
@@ -22,12 +22,12 @@ public class SysLoginUserRedisDAO { @@ -22,12 +22,12 @@ public class SysLoginUserRedisDAO {
22 22
23 public LoginUser get(String sessionId) { 23 public LoginUser get(String sessionId) {
24 String redisKey = formatKey(sessionId); 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 public void set(String sessionId, LoginUser loginUser) { 28 public void set(String sessionId, LoginUser loginUser) {
29 String redisKey = formatKey(sessionId); 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 public void delete(String accessToken) { 33 public void delete(String accessToken) {
src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/common/SysCaptchaRedisDAO.java
1 package cn.iocoder.dashboard.modules.system.dal.redis.dao.common; 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 import org.springframework.data.redis.core.StringRedisTemplate; 3 import org.springframework.data.redis.core.StringRedisTemplate;
6 import org.springframework.stereotype.Repository; 4 import org.springframework.stereotype.Repository;
7 5
8 import javax.annotation.Resource; 6 import javax.annotation.Resource;
9 -  
10 import java.time.Duration; 7 import java.time.Duration;
11 8
12 import static cn.iocoder.dashboard.modules.system.dal.redis.RedisKeyConstants.CAPTCHA_CODE; 9 import static cn.iocoder.dashboard.modules.system.dal.redis.RedisKeyConstants.CAPTCHA_CODE;
src/main/java/cn/iocoder/dashboard/util/json/JSONUtils.java
1 package cn.iocoder.dashboard.util.json; 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 * JSON 工具类 9 * JSON 工具类
@@ -9,16 +12,35 @@ import com.alibaba.fastjson.JSON; @@ -9,16 +12,35 @@ import com.alibaba.fastjson.JSON;
9 */ 12 */
10 public class JSONUtils { 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 public static String toJSONString(Object object) { 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 public static <T> T parseObject(String text, Class<T> clazz) { 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 public static <T> T parseObject(byte[] bytes, Class<T> clazz) { 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,7 +2,7 @@ package cn.iocoder.dashboard.util.servlet;
2 2
3 import cn.hutool.core.io.IoUtil; 3 import cn.hutool.core.io.IoUtil;
4 import cn.hutool.extra.servlet.ServletUtil; 4 import cn.hutool.extra.servlet.ServletUtil;
5 -import com.alibaba.fastjson.JSON; 5 +import cn.iocoder.dashboard.util.json.JSONUtils;
6 import org.springframework.http.MediaType; 6 import org.springframework.http.MediaType;
7 import org.springframework.web.context.request.RequestAttributes; 7 import org.springframework.web.context.request.RequestAttributes;
8 import org.springframework.web.context.request.RequestContextHolder; 8 import org.springframework.web.context.request.RequestContextHolder;
@@ -28,7 +28,7 @@ public class ServletUtils { @@ -28,7 +28,7 @@ public class ServletUtils {
28 */ 28 */
29 @SuppressWarnings("deprecation") // 必须使用 APPLICATION_JSON_UTF8_VALUE,否则会乱码 29 @SuppressWarnings("deprecation") // 必须使用 APPLICATION_JSON_UTF8_VALUE,否则会乱码
30 public static void writeJSON(HttpServletResponse response, Object object) { 30 public static void writeJSON(HttpServletResponse response, Object object) {
31 - String content = JSON.toJSONString(object); 31 + String content = JSONUtils.toJSONString(object);
32 ServletUtil.write(response, content, MediaType.APPLICATION_JSON_UTF8_VALUE); 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,6 +31,11 @@ spring:
31 url: http://127.0.0.1:8080/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址 31 url: http://127.0.0.1:8080/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址
32 # Spring Boot Admin Server 服务端的相关配置 32 # Spring Boot Admin Server 服务端的相关配置
33 context-path: /admin # 配置 Spring 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 yudao: 41 yudao: