升级spring boot4版本

This commit is contained in:
蓝白 committed 2026-04-06 13:03:27 +08:00
1 parent 2423ffd7ae
commit 79c1ce8e11
14 files changed
+72 -232

No files matched your search

+2 -2
View File
@@ -11,8 +11,8 @@
<artifactId>crabc-admin</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
@@ -19,7 +19,7 @@ package cn.crabc.core.admin;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
/**
+2 -2
View File
@@ -12,8 +12,8 @@
<artifactId>crabc-core</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>
@@ -33,8 +33,8 @@ public class InterceptorConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) {
// 登录拦截器
registry.addInterceptor(jwtInterceptor())
.addPathPatterns("/api/box/**") // 需要拦截的请求
.excludePathPatterns("/api/box/sys/user/login", "/api/box/sys/user/loginout", "/api/box/sys/user/register"); // 不拦截的请求
.excludePathPatterns("/api/box/**"); // 需要拦截的请求
//.excludePathPatterns("/api/box/sys/user/login", "/api/box/sys/user/loginout", "/api/box/sys/user/register"); // 不拦截的请求
// API开放接口拦截器
registry.addInterceptor(apiInterceptor())
@@ -1,91 +0,0 @@
package cn.crabc.core.app.config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* Jackson 配置类
* 解决时间字段带 T 和科学计数法问题
*
* @author yuqf
*/
@Configuration
public class JacksonConfig {
/**
* 日期时间格式
*/
private static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
/**
* 日期格式
*/
private static final String DATE_PATTERN = "yyyy-MM-dd";
/**
* 时间格式
*/
private static final String TIME_PATTERN = "HH:mm:ss";
/**
* 配置 Jackson ObjectMapper
* 针对 Spring Boot 3 优化
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> {
// 注册 JavaTimeModule 处理 Java 8 日期时间类型
JavaTimeModule javaTimeModule = new JavaTimeModule();
// LocalDateTime 序列化格式
javaTimeModule.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATETIME_PATTERN)));
// LocalDate 序列化格式
javaTimeModule.addSerializer(LocalDate.class,
new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_PATTERN)));
// LocalTime 序列化格式
javaTimeModule.addSerializer(LocalTime.class,
new LocalTimeSerializer(DateTimeFormatter.ofPattern(TIME_PATTERN)));
builder.modules(javaTimeModule);
// BigDecimal 使用自定义序列化器,避免科学计数法(包括数值过小的情况)
builder.serializerByType(BigDecimal.class, new JsonSerializer<BigDecimal>() {
@Override
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
// 使用 toPlainString() 确保不会输出科学计数法
gen.writeString(value.stripTrailingZeros().toPlainString());
}
});
// BigInteger、Long 使用 ToStringSerializer
builder.serializerByType(BigInteger.class, ToStringSerializer.instance);
builder.serializerByType(Long.class, ToStringSerializer.instance);
builder.serializerByType(long.class, ToStringSerializer.instance);
// 其他配置
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
builder.featuresToEnable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
};
}
}
@@ -1,8 +1,8 @@
package cn.crabc.core.app.config;
import org.springframework.boot.web.error.ErrorPage;
import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -6,9 +6,9 @@ import cn.crabc.core.app.enums.ResultTypeEnum;
import cn.crabc.core.app.service.core.IBaseDataService;
import cn.crabc.core.app.util.Result;
import cn.crabc.core.datasource.enums.ErrorStatusEnum;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import tools.jackson.databind.json.JsonMapper;
import java.util.Arrays;
import java.util.HashMap;
@@ -27,7 +27,7 @@ public class ApiTestController {
@Autowired
private IBaseDataService baseDataService;
@Autowired
private ObjectMapper objectMapper;
private JsonMapper jsonMapper;
/**
* 运行预览
@@ -89,9 +89,9 @@ public class ApiTestController {
// 处理body参数
if (params.getBodyData() != null && params.getBodyData().startsWith("{")) {
paramsMap = objectMapper.readValue(params.getBodyData(), HashMap.class);
paramsMap = jsonMapper.readValue(params.getBodyData(), HashMap.class);
}else if (params.getBodyData() != null && params.getBodyData().startsWith("[")) {
List list = objectMapper.readValue(params.getBodyData(), List.class);
List list = jsonMapper.readValue(params.getBodyData(), List.class);
paramsMap.put("list", list);
}
@@ -129,9 +129,9 @@ public class ApiTestController {
private String formatResultData(Object data, String resultType) throws Exception {
if (ResultTypeEnum.ONE.getName().equals(resultType) && data instanceof List) {
List<Object> list = (List<Object>) data;
return objectMapper.writeValueAsString(Result.success(list.isEmpty() ? null : list.get(0)));
return jsonMapper.writeValueAsString(Result.success(list.isEmpty() ? null : list.get(0)));
}
return objectMapper.writeValueAsString(Result.success(data));
return jsonMapper.writeValueAsString(Result.success(data));
}
/**
@@ -4,14 +4,13 @@ import cn.crabc.core.app.entity.BaseUser;
import cn.crabc.core.app.entity.param.UserParam;
import cn.crabc.core.app.service.system.IBaseUserService;
import cn.crabc.core.app.util.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.benmanes.caffeine.cache.Cache;
import org.apache.tomcat.util.codec.binary.Base64;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import tools.jackson.databind.json.JsonMapper;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
@@ -30,7 +29,7 @@ public class SysUserController {
@Qualifier("dataCache")
Cache<String, Object> caffeineCache;
@Autowired
private ObjectMapper objectMapper;
private JsonMapper jsonMapper;
/**
* 登录
*
@@ -87,12 +86,8 @@ public class SysUserController {
public Result userMenus(){
// 固定菜单
String menus ="[{\"name\":\"API Hub\",\"checked\":null,\"id\":2,\"parentId\":1,\"open\":null,\"path\":null,\"url\":\"/hub\",\"sort\":2,\"menuType\":1,\"code\":\"Home\",\"hidden\":false,\"permission\":\"/api/box/sys/user/info;/api/box/sys/user/menus;/api/box/sys/message/**;/api/box/sys/user/update/pwd\",\"subMenus\":[{\"name\":\"接口详情\",\"checked\":null,\"id\":7,\"parentId\":2,\"open\":null,\"path\":null,\"url\":\"/doc\",\"sort\":6,\"menuType\":1,\"code\":\"DataCatelogApiDetails\",\"hidden\":true,\"permission\":\"doc\",\"subMenus\":[]}]},{\"name\":\"工作台\",\"checked\":null,\"id\":3,\"parentId\":1,\"open\":null,\"path\":null,\"url\":\"/working\",\"sort\":3,\"menuType\":1,\"code\":\"DataService\",\"hidden\":false,\"permission\":\"/api/box/sys/common/**;/api/box/sys/api/info/**;/api/box/sys/metadata/**;/api/box/sys/test/**;/api/box/sys/group/**;/api/box/sys/user/check/name\",\"subMenus\":[]},{\"name\":\"服务台\",\"checked\":null,\"id\":4,\"parentId\":1,\"open\":null,\"path\":null,\"url\":\"/manage\",\"sort\":4,\"menuType\":1,\"code\":\"Manage\",\"hidden\":false,\"permission\":\"manage\",\"subMenus\":[{\"name\":\"应用管理\",\"checked\":null,\"id\":8,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/keys\",\"sort\":1,\"menuType\":1,\"code\":\"Application\",\"hidden\":true,\"permission\":\"/api/box/sys/app/**\",\"subMenus\":[]},{\"name\":\"接口列表\",\"checked\":null,\"id\":9,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/apis\",\"sort\":1,\"menuType\":1,\"code\":\"MyApi\",\"hidden\":true,\"permission\":\"/api/box/sys/api/info/**\",\"subMenus\":[]},{\"name\":\"日志管理\",\"checked\":null,\"id\":12,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/logs\",\"sort\":1,\"menuType\":1,\"code\":\"UseLog\",\"hidden\":true,\"permission\":\"/api/box/sys/api/log/**\",\"subMenus\":[{\"name\":\"日志列表\",\"checked\":null,\"id\":13,\"parentId\":12,\"open\":null,\"path\":null,\"url\":\"/manage/logs/list\",\"sort\":1,\"menuType\":1,\"code\":\"UseLogList\",\"hidden\":true,\"permission\":\"/api/box/sys/api/log/**\",\"subMenus\":[]},{\"name\":\"日志详情\",\"checked\":null,\"id\":14,\"parentId\":12,\"open\":null,\"path\":null,\"url\":\"/manage/logs/detail\",\"sort\":1,\"menuType\":1,\"code\":\"DetailUesLog\",\"hidden\":true,\"permission\":null,\"subMenus\":[]}]},{\"name\":\"分类管理\",\"checked\":null,\"id\":30,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/classification\",\"sort\":1,\"menuType\":1,\"code\":\"Classification\",\"hidden\":true,\"permission\":\"manage:classification\",\"subMenus\":[]},{\"name\":\"数据源\",\"checked\":null,\"id\":31,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/datasource\",\"sort\":1,\"menuType\":1,\"code\":\"DataSource\",\"hidden\":true,\"permission\":\"/api/box/sys/datasource/**;/api/box/sys/user/pubKey\",\"subMenus\":[]},{\"name\":\"密码重置\",\"checked\":null,\"id\":32,\"parentId\":4,\"open\":null,\"path\":null,\"url\":\"/manage/edit-pwd\",\"sort\":1,\"menuType\":1,\"code\":\"ChangePassword\",\"hidden\":true,\"permission\":\"/api/box/sys/user/update/pwd\",\"subMenus\":[]}]}]";
try {
List<Map<String, Object>> list = objectMapper.readValue(menus, List.class);
List<Map<String, Object>> list = jsonMapper.readValue(menus, List.class);
return Result.success(list);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
/**
@@ -10,7 +10,6 @@ import cn.crabc.core.app.util.RequestUtils;
import cn.crabc.core.app.util.Result;
import cn.crabc.core.app.util.SM3Util;
import cn.crabc.core.datasource.enums.ErrorStatusEnum;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.benmanes.caffeine.cache.Cache;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@@ -23,8 +22,8 @@ import org.springframework.lang.Nullable;
import org.springframework.util.StreamUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.util.ContentCachingResponseWrapper;
import tools.jackson.databind.json.JsonMapper;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
@@ -46,7 +45,7 @@ public class AuthInterceptor implements HandlerInterceptor {
@Value("${crabc.auth.expiresTime:10}")
private Integer expiresTime;
@Autowired
private ObjectMapper objectMapper;
private JsonMapper jsonMapper;
@Autowired
@Qualifier("apiCache")
private Cache<String, ApiInfoDTO> apiCache;
@@ -111,7 +110,7 @@ public class AuthInterceptor implements HandlerInterceptor {
response.setStatus(400);
response.setContentType("application/json;charset=UTF-8");
Result result = Result.error(status, message);
String json = objectMapper.writeValueAsString(result);
String json = jsonMapper.writeValueAsString(result);
// 日记记录
addLog(request, response, json);
response.getWriter().write(json);
@@ -1,12 +1,6 @@
package cn.crabc.core.app.util;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -18,36 +12,6 @@ import java.util.Set;
*/
public class RequestUtils {
private static ObjectMapper objectMapper = new ObjectMapper();
/**
* 获取body
*
* @param req
* @return
*/
public static Map<String, Object> getBodyMap(HttpServletRequest req) {
BufferedReader reader = null;
Map<String, Object> bodyMap = new HashMap<>();
try {
reader = req.getReader();
StringBuilder builder = new StringBuilder();
String line = reader.readLine();
while (line != null) {
builder.append(line);
line = reader.readLine();
}
reader.close();
String bodyString = builder.toString();
if (!"".equals(bodyString)) {
bodyMap = objectMapper.readValue(bodyString, Map.class);
}
} catch (Exception e) {
}
return bodyMap;
}
/**
* 获取 params 参数
*
@@ -148,57 +112,4 @@ public class RequestUtils {
}
return ip == null ? "" : ip.trim();
}
/**
* 根据关键字解析json
*
* @param @param jsonObject
* @param @param keyName 支持逗号分隔
* @return Object
*/
public static Object decodeJsonObject(String jsonObject, String keyName) {
Object result = null;
if (jsonObject == null || "".equals(jsonObject)) {
return null;
}
JsonFactory jasonFactory = new JsonFactory();
JsonParser parser = null;
try {
parser = jasonFactory.createParser(jsonObject);
JsonToken firstToken = parser.nextToken();
if (!JsonToken.START_OBJECT.equals(firstToken)) {
return result;
}
while (!parser.isClosed()) {
JsonToken t = parser.nextToken();
if (JsonToken.FIELD_NAME.equals(t) && keyName.equals(parser.getCurrentName())) {
JsonToken v = parser.nextToken();
if (JsonToken.VALUE_NULL.equals(v)) {
return null;
} else if (JsonToken.VALUE_STRING.equals(v)) {
return parser.getValueAsString();
} else if (JsonToken.VALUE_TRUE.equals(v) || JsonToken.VALUE_FALSE.equals(v)) {
return parser.getBooleanValue();
} else if (JsonToken.VALUE_NUMBER_INT.equals(v)) {
return parser.getLongValue();
} else if (JsonToken.VALUE_NUMBER_FLOAT.equals(v)) {
return parser.getDoubleValue();
}
} else if (JsonToken.START_OBJECT.equals(t) || JsonToken.START_ARRAY.equals(t)) {
parser.skipChildren();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (parser != null) {
parser.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
}
+10 -5
View File
@@ -11,8 +11,8 @@
<artifactId>crabc-datasource</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
@@ -33,12 +33,12 @@
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<artifactId>mybatis-plus-spring-boot4-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<artifactId>druid-spring-boot-4-starter</artifactId>
<version>${spring-boot.druid.version}</version>
</dependency>
<dependency>
@@ -47,10 +47,15 @@
<version>${project.version}</version>
</dependency>
<!-- 数据源驱动包 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.3.0</version>
<version>8.4.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
+2 -2
View File
@@ -11,8 +11,8 @@
<artifactId>crabc-spi</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
</project>
+26 -5
View File
@@ -6,13 +6,13 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.9</version>
<version>4.0.5</version>
</parent>
<name>crabc-spring-boot-starter</name>
<groupId>cn.crabc</groupId>
<artifactId>crabc-spring-boot-starter</artifactId>
<version>4.3.0</version>
<version>4.4.0</version>
<packaging>jar</packaging>
<description>Low code tools</description>
<url>https://github.com/pingapi/crabc-api</url>
@@ -33,8 +33,8 @@
</developer>
</developers>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
@@ -42,7 +42,7 @@
<dependency>
<groupId>cn.crabc</groupId>
<artifactId>crabc-core</artifactId>
<version>4.3.0</version>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -116,4 +116,25 @@
</plugin>
</plugins>
</build>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
</repository>
</distributionManagement>
<profiles>
<profile>
<id>ossrh</id>
<properties>
<gpg.executable>gpg</gpg.executable>
<gpg.passphrase>Crabc123</gpg.passphrase>
</properties>
</profile>
</profiles>
</project>
+13 -13
View File
@@ -12,25 +12,25 @@
<description>接口开发平台</description>
<modules>
<module>crabc-api</module>
<!-- <module>crabc-spring-boot-starter</module>-->
<module>crabc-spring-boot-starter</module>
</modules>
<properties>
<!-- crabc 版本-->
<revision>4.3.0</revision>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<revision>4.4.0</revision>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot.version>3.5.9</spring-boot.version>
<spring-boot.mybatis.version>3.0.5</spring-boot.mybatis.version>
<mybatis-plus.version>3.5.15</mybatis-plus.version>
<spring-boot.version>4.0.5</spring-boot.version>
<spring-boot.mybatis.version>4.0.1</spring-boot.mybatis.version>
<mybatis-plus.version>3.5.16</mybatis-plus.version>
<pagehelper.boot.version>2.1.1</pagehelper.boot.version>
<spring-boot.druid.version>1.2.27</spring-boot.druid.version>
<fastjson.version>2.0.49</fastjson.version>
<jwt.version>0.12.5</jwt.version>
<commons-pool2.version>2.12.0</commons-pool2.version>
<lombok.version>1.18.34</lombok.version>
<spring-boot.druid.version>1.2.28</spring-boot.druid.version>
<fastjson.version>2.0.61</fastjson.version>
<jwt.version>0.13.0</jwt.version>
<commons-pool2.version>2.13.1</commons-pool2.version>
<lombok.version>1.18.44</lombok.version>
<jdk18on.version>1.80</jdk18on.version>
</properties>
<repositories>