Commit eadc4f749a2452ab2c3705bcaf75fca32ee41a2d
1 parent
9c1c2659
替换带代码里所有 fastjson 的内容,统一使用 jackson
不考虑使用 gson 的原因,是基本停止了维护
Showing
17 changed files
with
106 additions
and
131 deletions
pom.xml
| ... | ... | @@ -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 | -<!-- <!– 解析客户端操作系统、浏览器等 –>--> | |
| 68 | -<!-- <dependency>--> | |
| 69 | -<!-- <groupId>eu.bitwalker</groupId>--> | |
| 70 | -<!-- <artifactId>UserAgentUtils</artifactId>--> | |
| 71 | -<!-- <version>${bitwalker.version}</version>--> | |
| 72 | -<!-- </dependency>--> | |
| 73 | - | |
| 74 | -<!-- <!– 获取系统信息 –>--> | |
| 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 | <!-- <!–velocity代码生成使用模板 –>--> |
| 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 => { |
| 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<T> 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: | ... | ... |