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,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 | -<!-- <!– 解析客户端操作系统、浏览器等 –>--> | ||
| 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 | <!-- <!–velocity代码生成使用模板 –>--> | 65 | <!-- <!–velocity代码生成使用模板 –>--> |
| 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 => { | @@ -61,9 +61,10 @@ service.interceptors.response.use(res => { | ||
| 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<T> implements Serializable { | @@ -69,13 +68,11 @@ public final class CommonResult<T> 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: |