1
0
mirror of synced 2026-05-22 14:43:15 +00:00

feat: 新增 SaTokenPlugin 接口,重构插件体系

This commit is contained in:
click33
2025-02-21 02:32:57 +08:00
parent 54bf228ec9
commit a4c9dc1e68
11 changed files with 209 additions and 117 deletions
@@ -16,10 +16,7 @@
package cn.dev33.satoken.spring;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.json.SaJsonTemplate;
import cn.dev33.satoken.json.SaJsonTemplateDefaultImpl;
import cn.dev33.satoken.spring.context.path.ApplicationContextPathLoading;
import cn.dev33.satoken.spring.json.SaJsonTemplateForJackson;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
@@ -41,25 +38,6 @@ public class SaBeanRegister {
public SaTokenConfig getSaTokenConfig() {
return new SaTokenConfig();
}
/**
* 获取 json 转换器 Bean (Jackson版)
*
* @return json 转换器 Bean (Jackson版)
*/
@Bean
public SaJsonTemplate getSaJsonTemplateForJackson() {
try {
// 部分开发者会在 springboot 项目中排除 jackson 依赖,所以这里做一个判断:
// 1、如果项目中存在 jackson 依赖,则使用 jackson 的 json 转换器
// 2、如果项目中不存在 jackson 依赖,则使用默认的 json 转换器
// to:防止因为 jackson 依赖问题导致项目无法启动
Class.forName("com.fasterxml.jackson.databind.ObjectMapper");
return new SaJsonTemplateForJackson();
} catch (ClassNotFoundException e) {
return new SaJsonTemplateDefaultImpl();
}
}
/**
* 应用上下文路径加载器
@@ -1,113 +0,0 @@
/*
* 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.spring.json;
import cn.dev33.satoken.error.SaSpringBootErrorCode;
import cn.dev33.satoken.exception.SaJsonConvertException;
import cn.dev33.satoken.json.SaJsonTemplate;
import cn.dev33.satoken.util.SaFoxUtil;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
import java.util.Map;
/**
* JSON 转换器, Jackson 版实现
*
* @author click33
* @since 1.34.0
*/
public class SaJsonTemplateForJackson implements SaJsonTemplate {
/**
* 底层 Mapper 对象
*/
public ObjectMapper objectMapper = new ObjectMapper();
public SaJsonTemplateForJackson() {
// 1、使 objectMapper 序列化时带上类型信息,以便该 json 字符串可以成功反序列化
// 构建反序列化限制器,此处可以限制只允许指定类型或指定包下的类型才可以反序列化,此处指定所有类型都可以反序列化
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
// 允许所有子类型反序列化(即反序列化时遇到的类)
.allowIfSubType(Object.class)
// 允许所有基类型反序列化(如 Object、自定义抽象类)
.allowIfBaseType(Object.class)
.build();
// 启用全局默认类型(嵌入类型信息)
objectMapper.activateDefaultTyping(
ptv,
// 对非 final 类嵌入类型信息
ObjectMapper.DefaultTyping.NON_FINAL,
// 类型信息以属性形式存在("@class"
JsonTypeInfo.As.PROPERTY
);
// 2、使空 bean 在序列化时也能记录类型信息,而不是只序列化成 {}
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
}
/**
* 序列化:对象 -> json 字符串
*/
@Override
public String objectToJson(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new SaJsonConvertException(e).setCode(SaSpringBootErrorCode.CODE_20103);
}
}
/**
* 反序列化:json 字符串 → 对象
*/
@Override
public Object jsonToObject(String jsonStr) {
if(SaFoxUtil.isEmpty(jsonStr)) {
return null;
}
try {
Object value = objectMapper.readValue(jsonStr, Object.class);
return value;
} catch (JsonProcessingException e) {
throw new SaJsonConvertException(e).setCode(SaSpringBootErrorCode.CODE_20106);
}
}
/**
* 反序列化:json 字符串 → Map
*/
@Override
public Map<String, Object> jsonToMap(String jsonStr) {
if(SaFoxUtil.isEmpty(jsonStr)) {
return null;
}
try {
@SuppressWarnings("unchecked")
Map<String, Object> map = objectMapper.readValue(jsonStr, Map.class);
return map;
} catch (JsonProcessingException e) {
throw new SaJsonConvertException(e).setCode(SaSpringBootErrorCode.CODE_20104);
}
}
}