mirror of
https://gitee.com/dromara/sa-token.git
synced 2026-02-27 16:50:24 +08:00
Compare commits
2
Commits
c2becdf498
...
f6c5131ad2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6c5131ad2 | ||
|
|
9c07f7a007 |
@@ -119,6 +119,11 @@
|
|||||||
<artifactId>sa-token-jackson</artifactId>
|
<artifactId>sa-token-jackson</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-jackson3</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.dev33</groupId>
|
<groupId>cn.dev33</groupId>
|
||||||
<artifactId>sa-token-fastjson</artifactId>
|
<artifactId>sa-token-fastjson</artifactId>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
<reactor-core.version>3.7.4</reactor-core.version>
|
<reactor-core.version>3.7.4</reactor-core.version>
|
||||||
<jackson-databind.version>2.13.4.1</jackson-databind.version>
|
<jackson-databind.version>2.13.4.1</jackson-databind.version>
|
||||||
<jackson-datatype-jsr310.version>2.11.2</jackson-datatype-jsr310.version>
|
<jackson-datatype-jsr310.version>2.11.2</jackson-datatype-jsr310.version>
|
||||||
|
<jackson3-databind.version>3.0.0</jackson3-databind.version>
|
||||||
<servlet-api.version>3.1.0</servlet-api.version>
|
<servlet-api.version>3.1.0</servlet-api.version>
|
||||||
<jakarta-servlet-api.version>6.0.0</jakarta-servlet-api.version>
|
<jakarta-servlet-api.version>6.0.0</jakarta-servlet-api.version>
|
||||||
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
|
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
|
||||||
@@ -97,6 +98,13 @@
|
|||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>${jackson-databind.version}</version>
|
<version>${jackson-databind.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- jackson-databind 3.x (tools.jackson) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>tools.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>${jackson3-databind.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- solon -->
|
<!-- solon -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
<modules>
|
<modules>
|
||||||
<!-- 通用插件 -->
|
<!-- 通用插件 -->
|
||||||
<module>sa-token-jackson</module>
|
<module>sa-token-jackson</module>
|
||||||
|
<module>sa-token-jackson3</module>
|
||||||
<module>sa-token-fastjson</module>
|
<module>sa-token-fastjson</module>
|
||||||
<module>sa-token-fastjson2</module>
|
<module>sa-token-fastjson2</module>
|
||||||
<module>sa-token-snack3</module>
|
<module>sa-token-snack3</module>
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ import cn.dev33.satoken.json.SaJsonTemplateDefaultImpl;
|
|||||||
import cn.dev33.satoken.json.SaJsonTemplateForJackson;
|
import cn.dev33.satoken.json.SaJsonTemplateForJackson;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SaToken 插件安装:JSON 转换器 (jackjson 版)
|
* SaToken 插件安装:JSON 转换器 (jackson 版)
|
||||||
*
|
*
|
||||||
* @author click33
|
* @author click33
|
||||||
* @since 1.41.0
|
* @since 1.41.0
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-plugin</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>sa-token-jackson3</name>
|
||||||
|
<artifactId>sa-token-jackson3</artifactId>
|
||||||
|
<description>sa-token-jackson3: Sa-Token 与 Jackson 3 整合</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- sa-token-core -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- jackson-databind 3.x (Java 8 时间支持已内置) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>tools.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>17</source>
|
||||||
|
<target>17</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
+121
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020-2099 sa-token.cc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.dev33.satoken.json;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.exception.SaJsonConvertException;
|
||||||
|
import cn.dev33.satoken.util.SaFoxUtil;
|
||||||
|
import tools.jackson.core.JacksonException;
|
||||||
|
import tools.jackson.databind.DeserializationFeature;
|
||||||
|
import tools.jackson.databind.DefaultTyping;
|
||||||
|
import tools.jackson.databind.SerializationFeature;
|
||||||
|
import tools.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
|
||||||
|
import tools.jackson.databind.jsontype.PolymorphicTypeValidator;
|
||||||
|
import tools.jackson.databind.json.JsonMapper;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON 转换器,Jackson 3 版实现
|
||||||
|
*
|
||||||
|
* @author click33
|
||||||
|
* @since 1.45.0
|
||||||
|
*/
|
||||||
|
public class SaJsonTemplateForJackson3 implements SaJsonTemplate {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 底层 Mapper 对象(带多态类型信息,用于 Session 等复杂对象序列化)
|
||||||
|
*/
|
||||||
|
public final JsonMapper objectMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 Map 的 Mapper(无多态类型配置,用于简单 JSON 解析)
|
||||||
|
*/
|
||||||
|
public final JsonMapper mapObjectMapper;
|
||||||
|
|
||||||
|
public SaJsonTemplateForJackson3() {
|
||||||
|
// 1、构建反序列化限制器(PolymorphicTypeValidator),限制哪些类型可以被自动多态反序列化
|
||||||
|
// 这里允许所有 Object 类型和其子类型参与多态反序列化,从而支持复杂对象(如 SaSession)的序列化、反序列化
|
||||||
|
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
|
||||||
|
.allowIfSubType(Object.class) // 允许 Object.class 的子类型被反序列化
|
||||||
|
.allowIfBaseType(Object.class) // 允许 Object.class 作为基类型(在启用多态时)
|
||||||
|
.build(); // 构建 Validator 实例
|
||||||
|
|
||||||
|
// 2、通过 JsonMapper 的 builder 模式创建 objectMapper(用于带多态类型信息的 JSON 处理,Jackson3 默认不可变需用构建器)
|
||||||
|
this.objectMapper = JsonMapper.builder()
|
||||||
|
// 启用默认多态类型处理,并以 "@class" 作为写入类型信息的属性名(即持久化时包含类型字段),仅对非 final 类型生效
|
||||||
|
.activateDefaultTypingAsProperty(ptv, DefaultTyping.NON_FINAL, "@class")
|
||||||
|
.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) // 序列化时如果 bean 没有属性,则不抛出异常
|
||||||
|
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) // 反序列化时如果有未知属性,也不抛出异常(兼容性更好)
|
||||||
|
.build(); // 构建真正的 JsonMapper 实例
|
||||||
|
|
||||||
|
// 3、创建 mapObjectMapper,用于简单类型(如 Map)的序列化和反序列化,和 objectMapper 独立,且不启用多态类型
|
||||||
|
this.mapObjectMapper = JsonMapper.builder()
|
||||||
|
.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) // 序列化时如果 bean 没有属性,则不抛出异常
|
||||||
|
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) // 反序列化时如果有未知属性,也不抛出异常,避免出错
|
||||||
|
.build(); // 构建用于处理简单场景的 JsonMapper 实例
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 序列化:对象 -> json 字符串
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String objectToJson(Object obj) {
|
||||||
|
if (SaFoxUtil.isEmpty(obj)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (obj instanceof Map) {
|
||||||
|
return mapObjectMapper.writeValueAsString(obj);
|
||||||
|
}
|
||||||
|
return objectMapper.writeValueAsString(obj);
|
||||||
|
} catch (JacksonException e) {
|
||||||
|
throw new SaJsonConvertException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 反序列化:json 字符串 → 对象
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> T jsonToObject(String jsonStr, Class<T> type) {
|
||||||
|
if (SaFoxUtil.isEmpty(jsonStr)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return objectMapper.readValue(jsonStr, type);
|
||||||
|
} catch (JacksonException e) {
|
||||||
|
throw new SaJsonConvertException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 json 字符串解析为 Map
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> jsonToMap(String jsonStr) {
|
||||||
|
if (SaFoxUtil.isEmpty(jsonStr)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<String, Object> map = mapObjectMapper.readValue(jsonStr, Map.class);
|
||||||
|
return map;
|
||||||
|
} catch (JacksonException e) {
|
||||||
|
throw new SaJsonConvertException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020-2099 sa-token.cc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.dev33.satoken.plugin;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.SaManager;
|
||||||
|
import cn.dev33.satoken.json.SaJsonTemplateDefaultImpl;
|
||||||
|
import cn.dev33.satoken.json.SaJsonTemplateForJackson3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SaToken 插件安装:JSON 转换器 (Jackson 3 版)
|
||||||
|
*
|
||||||
|
* @author click33
|
||||||
|
* @since 1.45.0
|
||||||
|
*/
|
||||||
|
public class SaTokenPluginForJackson3 implements SaTokenPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void install() {
|
||||||
|
// 只有在未提供自定义的 json 解析器时才会生效,给予其较弱的优先级
|
||||||
|
if (SaManager.getSaJsonTemplate().getClass() == SaJsonTemplateDefaultImpl.class) {
|
||||||
|
SaManager.setSaJsonTemplate(new SaJsonTemplateForJackson3());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
cn.dev33.satoken.plugin.SaTokenPluginForJackson3
|
||||||
@@ -21,11 +21,13 @@
|
|||||||
<!-- 所有子模块 -->
|
<!-- 所有子模块 -->
|
||||||
<modules>
|
<modules>
|
||||||
<!-- <module>sa-token-core-test</module> -->
|
<!-- <module>sa-token-core-test</module> -->
|
||||||
|
<module>sa-token-easy-test</module>
|
||||||
<module>sa-token-springboot-test</module>
|
<module>sa-token-springboot-test</module>
|
||||||
<!-- <module>sa-token-springboot-integrate-test</module> -->
|
<!-- <module>sa-token-springboot-integrate-test</module> -->
|
||||||
<module>sa-token-jwt-test</module>
|
<module>sa-token-jwt-test</module>
|
||||||
<module>sa-token-temp-jwt-test</module>
|
<module>sa-token-temp-jwt-test</module>
|
||||||
<module>sa-token-json-test</module>
|
<module>sa-token-json-test</module>
|
||||||
|
<module>sa-token-jackson3-test</module>
|
||||||
<module>sa-token-serializer-test</module>
|
<module>sa-token-serializer-test</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-test</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>sa-token-easy-test</name>
|
||||||
|
<artifactId>sa-token-easy-test</artifactId>
|
||||||
|
<description>sa-token-easy-test</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-jackson3</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Jackson 3(testJackson3 需要,sa-token-jackson3 中为 optional) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>tools.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package com.pj.test;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.SaManager;
|
||||||
|
import cn.dev33.satoken.exception.NotImplException;
|
||||||
|
import cn.dev33.satoken.json.SaJsonTemplateDefaultImpl;
|
||||||
|
import cn.dev33.satoken.json.SaJsonTemplateForJackson3;
|
||||||
|
import com.pj.test.model.SysUser;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sa-Token json 序列化模块测试
|
||||||
|
*
|
||||||
|
* @author click33
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SaJsonTemplateTest {
|
||||||
|
|
||||||
|
// 开始
|
||||||
|
@BeforeAll
|
||||||
|
public static void beforeClass() {
|
||||||
|
System.out.println("\n\n------------------------ SaJsonTemplateTest star ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
@AfterAll
|
||||||
|
public static void afterClass() {
|
||||||
|
System.out.println("\n\n------------------------ SaJsonTemplateTest end ... \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试:DefaultImpl
|
||||||
|
@Test
|
||||||
|
public void testDefaultImpl() {
|
||||||
|
SaManager.setSaJsonTemplate(new SaJsonTemplateDefaultImpl());
|
||||||
|
Assertions.assertEquals(SaManager.getSaJsonTemplate().getClass(), SaJsonTemplateDefaultImpl.class);
|
||||||
|
|
||||||
|
// test Object -> Json
|
||||||
|
SysUser user = new SysUser(10001, "张三", 18);
|
||||||
|
Assertions.assertThrows(NotImplException.class, () -> SaManager.getSaJsonTemplate().objectToJson(user) );
|
||||||
|
Assertions.assertThrows(NotImplException.class, () -> SaManager.getSaJsonTemplate().jsonToObject("xxx", SysUser.class) );
|
||||||
|
Assertions.assertThrows(NotImplException.class, () -> SaManager.getSaJsonTemplate().jsonToObject("xxx") );
|
||||||
|
Assertions.assertThrows(NotImplException.class, () -> SaManager.getSaJsonTemplate().jsonToMap("xxx") );
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试:Jackson3
|
||||||
|
@Test
|
||||||
|
public void testJackson3() {
|
||||||
|
SaManager.setSaJsonTemplate(new SaJsonTemplateForJackson3());
|
||||||
|
Assertions.assertEquals(SaJsonTemplateForJackson3.class, SaManager.getSaJsonTemplate().getClass());
|
||||||
|
|
||||||
|
// test Object -> Json
|
||||||
|
SysUser user = new SysUser(10001, "张三", 18);
|
||||||
|
String objectJson = SaManager.getSaJsonTemplate().objectToJson(user);
|
||||||
|
// 与 json2 不同点:Jackson 3 默认按字母序排列属性
|
||||||
|
Assertions.assertEquals("{\"@class\":\"com.pj.test.model.SysUser\",\"age\":18,\"id\":10001,\"name\":\"张三\",\"role\":null}", objectJson);
|
||||||
|
|
||||||
|
// test Json -> Object
|
||||||
|
SysUser user2 = SaManager.getSaJsonTemplate().jsonToObject(objectJson, SysUser.class);
|
||||||
|
Assertions.assertEquals(user2.toString(), user.toString());
|
||||||
|
|
||||||
|
SysUser user3 = (SysUser)SaManager.getSaJsonTemplate().jsonToObject(objectJson);
|
||||||
|
Assertions.assertEquals(user3.toString(), user.toString());
|
||||||
|
|
||||||
|
// more
|
||||||
|
testNull();
|
||||||
|
testMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试 Map 的转换
|
||||||
|
private void testMap() {
|
||||||
|
|
||||||
|
// test Map -> Json
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("id", 10001);
|
||||||
|
map.put("name", "张三");
|
||||||
|
map.put("age", 18);
|
||||||
|
String mapJson = SaManager.getSaJsonTemplate().objectToJson(map);
|
||||||
|
Assertions.assertEquals("{\"name\":\"张三\",\"id\":10001,\"age\":18}", mapJson);
|
||||||
|
|
||||||
|
// test Json -> Map
|
||||||
|
Map<String, Object> map2 = SaManager.getSaJsonTemplate().jsonToMap(mapJson);
|
||||||
|
Assertions.assertEquals(map2.toString(), map.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试 Null 值
|
||||||
|
private void testNull() {
|
||||||
|
Assertions.assertNull(SaManager.getSaJsonTemplate().objectToJson(null));
|
||||||
|
Assertions.assertNull(SaManager.getSaJsonTemplate().jsonToObject(null, SysUser.class));
|
||||||
|
Assertions.assertNull(SaManager.getSaJsonTemplate().jsonToObject(null));
|
||||||
|
Assertions.assertNull(SaManager.getSaJsonTemplate().jsonToMap(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.pj.test.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Role 实体类
|
||||||
|
*
|
||||||
|
* @author click33
|
||||||
|
* @since 2022-10-15
|
||||||
|
*/
|
||||||
|
public class SysRole {
|
||||||
|
//
|
||||||
|
// public SysRole() {
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public SysRole(long id, String name) {
|
||||||
|
// super();
|
||||||
|
// this.id = id;
|
||||||
|
// this.name = name;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 角色id
|
||||||
|
// */
|
||||||
|
// private long id;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 角色名称
|
||||||
|
// */
|
||||||
|
// private String name;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @return id
|
||||||
|
// */
|
||||||
|
// public long getId() {
|
||||||
|
// return id;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @param id 要设置的 id
|
||||||
|
// */
|
||||||
|
// public void setId(long id) {
|
||||||
|
// this.id = id;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @return name
|
||||||
|
// */
|
||||||
|
// public String getName() {
|
||||||
|
// return name;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @param name 要设置的 name
|
||||||
|
// */
|
||||||
|
// public void setName(String name) {
|
||||||
|
// this.name = name;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public String toString() {
|
||||||
|
// return "SysRole [id=" + id + ", name=" + name + "]";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package com.pj.test.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User 实体类
|
||||||
|
*
|
||||||
|
* @author click33
|
||||||
|
* @since 2022-10-15
|
||||||
|
*/
|
||||||
|
public class SysUser {
|
||||||
|
|
||||||
|
public SysUser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SysUser(long id, String name, int age) {
|
||||||
|
super();
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户年龄
|
||||||
|
*/
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户角色
|
||||||
|
*/
|
||||||
|
private SysRole role;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return id
|
||||||
|
*/
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id 要设置的 id
|
||||||
|
*/
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name 要设置的 name
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return age
|
||||||
|
*/
|
||||||
|
public int getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param age 要设置的 age
|
||||||
|
*/
|
||||||
|
public void setAge(int age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SysRole getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SysUser setRole(SysRole role) {
|
||||||
|
this.role = role;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SysUser{" +
|
||||||
|
"id=" + id +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", age=" + age +
|
||||||
|
", role=" + role +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-test</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>sa-token-jackson3-test</name>
|
||||||
|
<artifactId>sa-token-jackson3-test</artifactId>
|
||||||
|
<description>sa-token-jackson3-test</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-jackson3</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Jackson 3(testJackson3 需要,sa-token-jackson3 中为 optional) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>tools.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
package com.pj.test;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.SaManager;
|
||||||
|
import cn.dev33.satoken.json.SaJsonTemplateForJackson3;
|
||||||
|
import com.pj.test.model.SysUser;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sa-Token-jackson3 序列化模块测试
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 为什么单独写一个模块来测试 Jackson 3 ?
|
||||||
|
*
|
||||||
|
* 在同一个项目里同时引入 jackson 2 和 jackson 3 后,
|
||||||
|
* 执行:
|
||||||
|
* SysUser user3 = (SysUser)SaManager.getSaJsonTemplate().jsonToObject(objectJson);
|
||||||
|
* 会报错:
|
||||||
|
* java.lang.NoSuchFieldError: POJO
|
||||||
|
* at tools.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:399)
|
||||||
|
* at tools.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:361)
|
||||||
|
* at tools.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:265)
|
||||||
|
* at tools.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
|
||||||
|
* at tools.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:158)
|
||||||
|
* at tools.jackson.databind.DeserializationContext.findNonContextualValueDeserializer(DeserializationContext.java:733)
|
||||||
|
* at tools.jackson.databind.deser.jdk.UntypedObjectDeserializer._findCustomDeser(UntypedObjectDeserializer.java:179)
|
||||||
|
* at tools.jackson.databind.deser.jdk.UntypedObjectDeserializer.resolve(UntypedObjectDeserializer.java:152)
|
||||||
|
*
|
||||||
|
* 暂未找到解决方案,所以只能单独写一个测试类来测试 Jackson 3 的功能了。
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
* @author click33
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SaJsonTemplateForJackson3Test {
|
||||||
|
|
||||||
|
// 开始
|
||||||
|
@BeforeAll
|
||||||
|
public static void beforeClass() {
|
||||||
|
System.out.println("\n\n------------------------ SaJsonTemplateForJackson3 Test star ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
@AfterAll
|
||||||
|
public static void afterClass() {
|
||||||
|
System.out.println("\n\n------------------------ SaJsonTemplateForJackson3 Test end ... \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试:Jackson3
|
||||||
|
@Test
|
||||||
|
public void testJackson3() {
|
||||||
|
SaManager.setSaJsonTemplate(new SaJsonTemplateForJackson3());
|
||||||
|
Assertions.assertEquals(SaJsonTemplateForJackson3.class, SaManager.getSaJsonTemplate().getClass());
|
||||||
|
|
||||||
|
// test Object -> Json
|
||||||
|
SysUser user = new SysUser(10001, "张三", 18);
|
||||||
|
String objectJson = SaManager.getSaJsonTemplate().objectToJson(user);
|
||||||
|
// 与 json2 不同点:Jackson 3 默认按字母序排列属性
|
||||||
|
Assertions.assertEquals("{\"@class\":\"com.pj.test.model.SysUser\",\"age\":18,\"id\":10001,\"name\":\"张三\",\"role\":null}", objectJson);
|
||||||
|
|
||||||
|
// test Json -> Object
|
||||||
|
SysUser user2 = SaManager.getSaJsonTemplate().jsonToObject(objectJson, SysUser.class);
|
||||||
|
Assertions.assertEquals(user2.toString(), user.toString());
|
||||||
|
|
||||||
|
SysUser user3 = (SysUser)SaManager.getSaJsonTemplate().jsonToObject(objectJson);
|
||||||
|
Assertions.assertEquals(user3.toString(), user.toString());
|
||||||
|
|
||||||
|
// more
|
||||||
|
testNull();
|
||||||
|
testMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试 Map 的转换
|
||||||
|
private void testMap() {
|
||||||
|
|
||||||
|
// test Map -> Json
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("id", 10001);
|
||||||
|
map.put("name", "张三");
|
||||||
|
map.put("age", 18);
|
||||||
|
String mapJson = SaManager.getSaJsonTemplate().objectToJson(map);
|
||||||
|
Assertions.assertEquals("{\"name\":\"张三\",\"id\":10001,\"age\":18}", mapJson);
|
||||||
|
|
||||||
|
// test Json -> Map
|
||||||
|
Map<String, Object> map2 = SaManager.getSaJsonTemplate().jsonToMap(mapJson);
|
||||||
|
Assertions.assertEquals(map2.toString(), map.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试 Null 值
|
||||||
|
private void testNull() {
|
||||||
|
Assertions.assertNull(SaManager.getSaJsonTemplate().objectToJson(null));
|
||||||
|
Assertions.assertNull(SaManager.getSaJsonTemplate().jsonToObject(null, SysUser.class));
|
||||||
|
Assertions.assertNull(SaManager.getSaJsonTemplate().jsonToObject(null));
|
||||||
|
Assertions.assertNull(SaManager.getSaJsonTemplate().jsonToMap(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.pj.test.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Role 实体类
|
||||||
|
*
|
||||||
|
* @author click33
|
||||||
|
* @since 2022-10-15
|
||||||
|
*/
|
||||||
|
public class SysRole {
|
||||||
|
//
|
||||||
|
// public SysRole() {
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public SysRole(long id, String name) {
|
||||||
|
// super();
|
||||||
|
// this.id = id;
|
||||||
|
// this.name = name;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 角色id
|
||||||
|
// */
|
||||||
|
// private long id;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 角色名称
|
||||||
|
// */
|
||||||
|
// private String name;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @return id
|
||||||
|
// */
|
||||||
|
// public long getId() {
|
||||||
|
// return id;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @param id 要设置的 id
|
||||||
|
// */
|
||||||
|
// public void setId(long id) {
|
||||||
|
// this.id = id;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @return name
|
||||||
|
// */
|
||||||
|
// public String getName() {
|
||||||
|
// return name;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @param name 要设置的 name
|
||||||
|
// */
|
||||||
|
// public void setName(String name) {
|
||||||
|
// this.name = name;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public String toString() {
|
||||||
|
// return "SysRole [id=" + id + ", name=" + name + "]";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package com.pj.test.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User 实体类
|
||||||
|
*
|
||||||
|
* @author click33
|
||||||
|
* @since 2022-10-15
|
||||||
|
*/
|
||||||
|
public class SysUser {
|
||||||
|
|
||||||
|
public SysUser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SysUser(long id, String name, int age) {
|
||||||
|
super();
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户年龄
|
||||||
|
*/
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户角色
|
||||||
|
*/
|
||||||
|
private SysRole role;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return id
|
||||||
|
*/
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id 要设置的 id
|
||||||
|
*/
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name 要设置的 name
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return age
|
||||||
|
*/
|
||||||
|
public int getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param age 要设置的 age
|
||||||
|
*/
|
||||||
|
public void setAge(int age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SysRole getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SysUser setRole(SysRole role) {
|
||||||
|
this.role = role;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SysUser{" +
|
||||||
|
"id=" + id +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", age=" + age +
|
||||||
|
", role=" + role +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user