feat: 升级springboot3

This commit is contained in:
2025-10-30 16:25:30 +08:00
parent 7321a9e172
commit 2a72c5f783
68 changed files with 242 additions and 436 deletions
@@ -19,7 +19,7 @@ package cn.odboy.base;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
/** /**
* 通用参数 * 通用参数
@@ -21,8 +21,8 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.validation.constraints.Min; import jakarta.validation.constraints.Min;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
/** /**
@@ -17,10 +17,9 @@
package cn.odboy.framework.context; package cn.odboy.framework.context;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects; import java.util.Objects;
/** /**
@@ -16,139 +16,33 @@
package cn.odboy.framework.doc; package cn.odboy.framework.doc;
import cn.odboy.constant.SystemConst;
import cn.odboy.framework.properties.AppProperties; import cn.odboy.framework.properties.AppProperties;
import cn.odboy.util.CsAnonTagUtil; import io.swagger.v3.oas.models.Components;
import org.springframework.beans.BeansException; import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/** /**
* api页面 /doc.html * api页面 /doc.html
*/ */
@Configuration @Configuration
@EnableSwagger2
public class SwaggerConfig { public class SwaggerConfig {
@Value("${server.servlet.context-path:}")
private String apiPath;
@Autowired @Autowired
private AppProperties properties; private AppProperties properties;
@Autowired
private ApplicationContext applicationContext;
@Bean @Bean
public Docket createRestApi() { public OpenAPI customOpenAPI() {
return new Docket(DocumentationType.SWAGGER_2).enable(properties.getSwagger().getEnabled()) // 添加开关控制
.pathMapping("/") if (!properties.getSwagger().getEnabled()) {
.apiInfo(apiInfo()) return new OpenAPI();
.select() }
.paths(PathSelectors.regex("^(?!/error).*")) return new OpenAPI().components(new Components().addSecuritySchemes("Authorization",
.paths(PathSelectors.any()) new SecurityScheme().name("Authorization").type(SecurityScheme.Type.APIKEY).in(SecurityScheme.In.HEADER)))
.build() .info(new Info().title("CuteJava 接口文档").version("1.4.1").description("一个简单且易上手的自动化运维平台"))
//添加登陆认证 .addSecurityItem(new SecurityRequirement().addList("Authorization"));
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().description("一个简单且易上手的自动化运维平台")
.title("CuteJava 接口文档")
.version("1.4.1")
.build();
}
private List<SecurityScheme> securitySchemes() {
//设置请求头信息
List<SecurityScheme> securitySchemes = new ArrayList<>();
ApiKey apiKey = new ApiKey(SystemConst.HEADER_NAME, SystemConst.HEADER_NAME, "header");
securitySchemes.add(apiKey);
return securitySchemes;
}
private List<SecurityContext> securityContexts() {
//设置需要登录认证的路径
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(getContextByPath());
return securityContexts;
}
private SecurityContext getContextByPath() {
Set<String> urls = CsAnonTagUtil.getAllAnonymousUrl(applicationContext);
urls = urls.stream().filter(url -> !"/".equals(url)).collect(Collectors.toSet());
String regExp = "^(?!" + apiPath + String.join("|" + apiPath, urls) + ").*$";
return SecurityContext.builder().securityReferences(defaultAuth()).operationSelector(o -> o.requestMappingPattern()
// 排除不需要认证的接口
.matches(regExp)).build();
}
private List<SecurityReference> defaultAuth() {
List<SecurityReference> securityReferences = new ArrayList<>();
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
securityReferences.add(new SecurityReference(SystemConst.HEADER_NAME, authorizationScopes));
return securityReferences;
}
/**
* 解决Springfox与SpringBoot集成后, WebMvcRequestHandlerProvider和WebFluxRequestHandlerProvider冲突问题
*
* @return /
*/
@Bean
@SuppressWarnings({"unchecked", "all"})
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
List<T> filteredMappings =
mappings.stream().filter(mapping -> mapping.getPatternParser() == null).collect(Collectors.toList());
mappings.clear();
mappings.addAll(filteredMappings);
}
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
if (field != null) {
field.setAccessible(true);
try {
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to access handlerMappings field", e);
}
}
return Collections.emptyList();
}
};
} }
} }
@@ -16,8 +16,8 @@
package cn.odboy.framework.mybatisplus.config; package cn.odboy.framework.mybatisplus.config;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; import com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure;
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; import com.alibaba.druid.spring.boot3.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.util.Utils; import com.alibaba.druid.util.Utils;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -26,9 +26,9 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import javax.servlet.*; import jakarta.servlet.*;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
@Configuration @Configuration
@@ -27,10 +27,9 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import jakarta.validation.constraints.NotNull;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -21,10 +21,10 @@ import com.alibaba.fastjson2.JSONFactory;
import com.alibaba.fastjson2.JSONWriter; import com.alibaba.fastjson2.JSONWriter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.MurmurHash3; import org.apache.commons.codec.digest.MurmurHash3;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler; import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.cache.interceptor.KeyGenerator;
@@ -49,7 +49,7 @@ import java.util.Map;
@Configuration @Configuration
@EnableCaching @EnableCaching
@AutoConfigureBefore(RedisAutoConfiguration.class) @AutoConfigureBefore(RedisAutoConfiguration.class)
public class RedisConfiguration extends CachingConfigurerSupport { public class RedisConfiguration {
/** /**
* 自动识别json对象白名单配置(仅允许解析的包名, 范围越小越安全)<br/> 未配置可能导致, 登录失败, 反复登录等问题 * 自动识别json对象白名单配置(仅允许解析的包名, 范围越小越安全)<br/> 未配置可能导致, 登录失败, 反复登录等问题
*/ */
@@ -69,7 +69,8 @@ public class RedisConfiguration extends CachingConfigurerSupport {
public RedisCacheConfiguration redisCacheConfiguration() { public RedisCacheConfiguration redisCacheConfiguration() {
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig(); RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofHours(2)); configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer))
.entryTtl(Duration.ofHours(2));
return configuration; return configuration;
} }
@@ -109,7 +110,6 @@ public class RedisConfiguration extends CachingConfigurerSupport {
*/ */
@Bean @Bean
@Override
public KeyGenerator keyGenerator() { public KeyGenerator keyGenerator() {
return (target, method, params) -> { return (target, method, params) -> {
Map<String, Object> container = new HashMap<>(8); Map<String, Object> container = new HashMap<>(8);
@@ -132,7 +132,6 @@ public class RedisConfiguration extends CachingConfigurerSupport {
} }
@Bean @Bean
@SuppressWarnings({"unchecked", "all"})
public CacheErrorHandler errorHandler() { public CacheErrorHandler errorHandler() {
return new SimpleCacheErrorHandler() { return new SimpleCacheErrorHandler() {
@Override @Override
@@ -1,43 +0,0 @@
/*
* Copyright 2021-2025 Odboy
*
* 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.odboy.framework.websocket.config;
import io.undertow.server.DefaultByteBufferPool;
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
/**
* 解决启动io.undertow.websockets.jsr UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used的警告
*
* @date 2024-06-07
*/
@Component
public class WsFactory implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
@Override
public void customize(UndertowServletWebServerFactory factory) {
factory.addDeploymentInfoCustomizers(deploymentInfo -> {
WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 1024));
deploymentInfo.addServletContextAttribute(
"io.undertow.websockets.jsr.WebSocketDeploymentInfo",
webSocketDeploymentInfo);
});
}
}
@@ -17,13 +17,12 @@
package cn.odboy.framework.websocket.context; package cn.odboy.framework.websocket.context;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import jakarta.websocket.server.ServerEndpoint;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import jakarta.websocket.*;
import javax.websocket.*; import jakarta.websocket.server.PathParam;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@@ -23,7 +23,7 @@ import lombok.experimental.UtilityClass;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@@ -42,8 +42,7 @@ public class CsAnonTagUtil {
* @return / * @return /
*/ */
public static Map<String, Set<String>> getAnonymousUrl(final ApplicationContext applicationContext) { public static Map<String, Set<String>> getAnonymousUrl(final ApplicationContext applicationContext) {
RequestMappingHandlerMapping requestMappingHandlerMapping = RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
(RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods(); Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();
Map<String, java.util.Set<String>> anonymousUrls = new HashMap<>(8); Map<String, java.util.Set<String>> anonymousUrls = new HashMap<>(8);
// 获取匿名标记 // 获取匿名标记
@@ -58,29 +57,27 @@ public class CsAnonTagUtil {
AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class); AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class);
if (null != anonymousAccess && infoEntry.getKey() != null) { if (null != anonymousAccess && infoEntry.getKey() != null) {
List<RequestMethod> requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods()); List<RequestMethod> requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods());
RequestMethodEnum request = RequestMethodEnum.find(requestMethods.isEmpty() ? RequestMethodEnum request = RequestMethodEnum.find(requestMethods.isEmpty() ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name());
RequestMethodEnum.ALL.getType() : PathPatternsRequestCondition pathPatternsCondition = infoEntry.getKey().getPathPatternsCondition();
requestMethods.get(0).name()); if (pathPatternsCondition != null) {
PatternsRequestCondition patternsCondition = infoEntry.getKey().getPatternsCondition();
if (patternsCondition != null) {
switch (Objects.requireNonNull(request)) { switch (Objects.requireNonNull(request)) {
case GET: case GET:
get.addAll(patternsCondition.getPatterns()); get.addAll(pathPatternsCondition.getPatternValues());
break; break;
case POST: case POST:
post.addAll(patternsCondition.getPatterns()); post.addAll(pathPatternsCondition.getPatternValues());
break; break;
case PUT: case PUT:
put.addAll(patternsCondition.getPatterns()); put.addAll(pathPatternsCondition.getPatternValues());
break; break;
case PATCH: case PATCH:
patch.addAll(patternsCondition.getPatterns()); patch.addAll(pathPatternsCondition.getPatternValues());
break; break;
case DELETE: case DELETE:
delete.addAll(patternsCondition.getPatterns()); delete.addAll(pathPatternsCondition.getPatternValues());
break; break;
default: default:
all.addAll(patternsCondition.getPatterns()); all.addAll(pathPatternsCondition.getPatternValues());
break; break;
} }
} }
@@ -21,7 +21,7 @@ import cn.hutool.http.useragent.UserAgentUtil;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
@@ -29,9 +29,9 @@ import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream; import jakarta.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.*; import java.io.*;
import java.nio.file.Files; import java.nio.file.Files;
import java.security.MessageDigest; import java.security.MessageDigest;
@@ -19,11 +19,11 @@ package cn.odboy.util;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import javax.validation.ConstraintViolation; import jakarta.validation.ConstraintViolation;
import javax.validation.Validation; import jakarta.validation.Validation;
import javax.validation.Validator; import jakarta.validation.Validator;
import javax.validation.ValidatorFactory; import jakarta.validation.ValidatorFactory;
import javax.validation.groups.Default; import jakarta.validation.groups.Default;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -38,6 +38,7 @@ import cn.odboy.util.CsStringUtil;
import com.wf.captcha.base.Captcha; import com.wf.captcha.base.Captcha;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -51,7 +52,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -32,7 +32,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
@@ -32,7 +32,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -32,7 +32,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Set; import java.util.Set;
@@ -34,7 +34,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
@RestController @RestController
@@ -35,7 +35,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -25,13 +25,13 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Set; import java.util.Set;
@@ -33,7 +33,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
@Slf4j @Slf4j
@@ -35,7 +35,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Set; import java.util.Set;
@@ -34,7 +34,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -46,7 +46,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -26,8 +26,8 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
@@ -25,7 +25,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@Getter @Getter
@Setter @Setter
@@ -22,8 +22,8 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@Getter @Getter
@Setter @Setter
@@ -23,7 +23,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
/** /**
* 邮件配置类,数据存覆盖式存入数据存 * 邮件配置类,数据存覆盖式存入数据存
@@ -24,8 +24,8 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.Objects; import java.util.Objects;
@Getter @Getter
@@ -26,7 +26,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
@@ -22,8 +22,8 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@Getter @Getter
@Setter @Setter
@@ -23,8 +23,8 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
@@ -25,9 +25,9 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.Email; import jakarta.validation.constraints.Email;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.Date; import java.util.Date;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
@@ -20,7 +20,7 @@ import cn.odboy.base.CsObject;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
@Getter @Getter
@Setter @Setter
@@ -20,8 +20,8 @@ import cn.odboy.base.CsObject;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -20,7 +20,7 @@ import cn.odboy.base.CsObject;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -21,8 +21,8 @@ import cn.odboy.system.dal.dataobject.SystemDictTb;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -20,8 +20,8 @@ import cn.odboy.base.CsObject;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -21,8 +21,8 @@ import cn.odboy.system.dal.dataobject.SystemDeptTb;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.Set; import java.util.Set;
@Data @Data
@@ -21,8 +21,8 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import java.util.List; import java.util.List;
/** /**
@@ -20,8 +20,8 @@ import cn.odboy.base.CsObject;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -20,7 +20,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
@Getter @Getter
@Setter @Setter
@@ -13,8 +13,8 @@ import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -36,7 +36,7 @@ import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.lang.reflect.Method; import java.lang.reflect.Method;
/** /**
@@ -36,7 +36,7 @@ import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.lang.reflect.Method; import java.lang.reflect.Method;
/** /**
@@ -20,6 +20,7 @@ import cn.odboy.constant.RequestMethodEnum;
import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO; import cn.odboy.system.dal.redis.SystemUserOnlineInfoDAO;
import cn.odboy.system.framework.permission.core.handler.JwtAccessDeniedHandler; import cn.odboy.system.framework.permission.core.handler.JwtAccessDeniedHandler;
import cn.odboy.system.framework.permission.core.handler.JwtAuthenticationEntryPoint; import cn.odboy.system.framework.permission.core.handler.JwtAuthenticationEntryPoint;
import cn.odboy.system.framework.permission.core.handler.TokenFilter;
import cn.odboy.system.framework.permission.core.handler.TokenProvider; import cn.odboy.system.framework.permission.core.handler.TokenProvider;
import cn.odboy.util.CsAnonTagUtil; import cn.odboy.util.CsAnonTagUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -27,20 +28,23 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.core.GrantedAuthorityDefaults; import org.springframework.security.config.core.GrantedAuthorityDefaults;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.CorsFilter; import org.springframework.web.filter.CorsFilter;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@Configuration @Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) @EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SpringSecurityConfig { public class SpringSecurityConfig {
@Autowired @Autowired
private TokenProvider tokenProvider; private TokenProvider tokenProvider;
@@ -71,43 +75,71 @@ public class SpringSecurityConfig {
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
// 获取匿名标记 // 获取匿名标记
Map<String, Set<String>> anonymousUrls = CsAnonTagUtil.getAnonymousUrl(applicationContext); Map<String, Set<String>> anonymousUrls = CsAnonTagUtil.getAnonymousUrl(applicationContext);
// 创建TokenFilter实例
TokenFilter customFilter = new TokenFilter(tokenProvider, systemUserOnlineInfoDAO);
return httpSecurity return httpSecurity
// 禁用 CSRF // 禁用 CSRF
.csrf().disable().addFilter(corsFilter) .csrf(AbstractHttpConfigurer::disable)
.addFilter(corsFilter)
.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class)
// 授权异常 // 授权异常
.exceptionHandling().authenticationEntryPoint(authenticationErrorHandler).accessDeniedHandler(jwtAccessDeniedHandler) .exceptionHandling(exceptionHandling -> exceptionHandling
.authenticationEntryPoint(authenticationErrorHandler)
.accessDeniedHandler(jwtAccessDeniedHandler))
// 防止iframe 造成跨域 // 防止iframe 造成跨域
.and().headers().frameOptions().disable() .headers(headers -> headers
.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
// 不创建会话 // 不创建会话
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests() .sessionManagement(sessionManagement -> sessionManagement
// 静态资源等等 .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/websocket/**").permitAll() .authorizeHttpRequests(authorizeRequests -> authorizeRequests
// swagger 文档 // 静态资源等等
.antMatchers("/swagger-ui.html").permitAll().antMatchers("/swagger-resources/**").permitAll().antMatchers("/webjars/**").permitAll().antMatchers("/*/api-docs").permitAll() .requestMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/websocket/**")
// 文件 .permitAll()
.antMatchers("/avatar/**").permitAll().antMatchers("/file/**").permitAll() // swagger 文档
// 阿里巴巴 druid .requestMatchers("/swagger-ui.html")
.antMatchers("/druid/**").permitAll() .permitAll()
// 放行OPTIONS请求 .requestMatchers("/swagger-resources/**")
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll() .permitAll()
// 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型 .requestMatchers("/webjars/**")
// GET .permitAll()
.antMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll() .requestMatchers("/*/api-docs")
// POST .permitAll()
.antMatchers(HttpMethod.POST, anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll() // 文件
// PUT .requestMatchers("/avatar/**")
.antMatchers(HttpMethod.PUT, anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll() .permitAll()
// PATCH .requestMatchers("/file/**")
.antMatchers(HttpMethod.PATCH, anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll() .permitAll()
// DELETE // 阿里巴巴 druid
.antMatchers(HttpMethod.DELETE, anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll() .requestMatchers("/druid/**")
// 所有类型的接口都放行 .permitAll()
.antMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll() // 放行OPTIONS请求
// 所有请求都需要认证 .requestMatchers(HttpMethod.OPTIONS, "/**")
.anyRequest().authenticated().and().apply(securityConfigurerAdapter()).and().build(); .permitAll()
// 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型
// GET
.requestMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0]))
.permitAll()
// POST
.requestMatchers(HttpMethod.POST, anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0]))
.permitAll()
// PUT
.requestMatchers(HttpMethod.PUT, anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0]))
.permitAll()
// PATCH
.requestMatchers(HttpMethod.PATCH, anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0]))
.permitAll()
// DELETE
.requestMatchers(HttpMethod.DELETE, anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0]))
.permitAll()
// 所有类型的接口都放行
.requestMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0]))
.permitAll()
// 所有请求都需要认证
.anyRequest()
.authenticated())
.build();
} }
}
private TokenConfigurer securityConfigurerAdapter() {
return new TokenConfigurer(tokenProvider, systemUserOnlineInfoDAO);
}
}
@@ -32,7 +32,7 @@ import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -23,8 +23,8 @@ import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
@Component @Component
@@ -24,8 +24,8 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
@Slf4j @Slf4j
@@ -26,11 +26,11 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.filter.GenericFilterBean; import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain; import jakarta.servlet.FilterChain;
import javax.servlet.ServletException; import jakarta.servlet.ServletException;
import javax.servlet.ServletRequest; import jakarta.servlet.ServletRequest;
import javax.servlet.ServletResponse; import jakarta.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException; import java.io.IOException;
@Slf4j @Slf4j
@@ -38,7 +38,7 @@ import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@@ -18,12 +18,11 @@ package cn.odboy.system.framework.quartz;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import cn.odboy.system.dal.dataobject.SystemQuartzJobTb; import cn.odboy.system.dal.dataobject.SystemQuartzJobTb;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.quartz.*; import org.quartz.*;
import org.quartz.impl.triggers.CronTriggerImpl; import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date; import java.util.Date;
@Slf4j @Slf4j
@@ -26,7 +26,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.util.unit.DataSize; import org.springframework.util.unit.DataSize;
import javax.servlet.MultipartConfigElement; import jakarta.servlet.MultipartConfigElement;
import java.io.File; import java.io.File;
@Slf4j @Slf4j
@@ -39,8 +39,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream; import jakarta.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
@@ -41,7 +41,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.*; import java.util.*;
@@ -33,7 +33,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
@@ -31,7 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
@@ -36,7 +36,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
@@ -39,7 +39,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.*; import java.util.*;
@@ -24,7 +24,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@@ -38,7 +38,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
@@ -40,7 +40,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -36,12 +36,12 @@ import cn.odboy.util.CsStringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
@@ -40,7 +40,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -46,6 +46,12 @@ spring:
type: redis type: redis
data: data:
redis: redis:
database: ${REDIS_DB:1}
host: ${REDIS_HOST:192.168.100.128}
port: ${REDIS_PORT:26379}
password: ${REDIS_PWD:kd123456}
# 连接超时时间
timeout: 5000
repositories: repositories:
# 是否启用Redis存储(关闭防止出现 Multiple Spring Data modules found, entering strict repository configuration mode) # 是否启用Redis存储(关闭防止出现 Multiple Spring Data modules found, entering strict repository configuration mode)
enabled: false enabled: false
@@ -109,24 +115,6 @@ spring:
config: config:
multi-statement-allow: true multi-statement-allow: true
aop-patterns: "cn.odboy.mapper.*,cn.odboy.service.*,cn.odboy.*.mapper.*,cn.odboy.*.service.*" aop-patterns: "cn.odboy.mapper.*,cn.odboy.service.*,cn.odboy.*.mapper.*,cn.odboy.*.service.*"
redis:
database: ${REDIS_DB:1}
host: ${REDIS_HOST:192.168.100.128}
port: ${REDIS_PORT:26379}
password: ${REDIS_PWD:kd123456}
# 连接超时时间
timeout: 5000
# 连接池配置
lettuce:
pool:
# 连接池最大连接数
max-active: 30
# 连接池最大阻塞等待时间(毫秒),负值表示没有限制
max-wait: -1
# 连接池中的最大空闲连接数
max-idle: 20
# 连接池中的最小空闲连接数
min-idle: 1
# 数据库一定不能区分大小写 # 数据库一定不能区分大小写
quartz: quartz:
# 必需,指定使用 JDBC 存储 # 必需,指定使用 JDBC 存储
@@ -46,6 +46,23 @@ spring:
type: redis type: redis
data: data:
redis: redis:
database: ${REDIS_DB:1}
host: ${REDIS_HOST:192.168.100.128}
port: ${REDIS_PORT:26379}
password: ${REDIS_PWD:kd123456}
# 连接超时时间
timeout: 5000
# 连接池配置
lettuce:
pool:
# 连接池最大连接数
max-active: 30
# 连接池最大阻塞等待时间(毫秒),负值表示没有限制
max-wait: -1
# 连接池中的最大空闲连接数
max-idle: 20
# 连接池中的最小空闲连接数
min-idle: 1
repositories: repositories:
# 是否启用Redis存储(关闭防止出现 Multiple Spring Data modules found, entering strict repository configuration mode) # 是否启用Redis存储(关闭防止出现 Multiple Spring Data modules found, entering strict repository configuration mode)
enabled: false enabled: false
@@ -53,10 +70,10 @@ spring:
druid: druid:
db-type: com.alibaba.druid.pool.DruidDataSource db-type: com.alibaba.druid.pool.DruidDataSource
# sql监控 # sql监控
# driverClassName: com.p6spy.engine.spy.P6SpyDriver driverClassName: com.p6spy.engine.spy.P6SpyDriver
# url: jdbc:p6spy:mysql://192.168.100.128:23306/cutejava?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true url: jdbc:p6spy:mysql://192.168.100.128:23306/cutejava?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
driverClassName: com.mysql.cj.jdbc.Driver # driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.100.128:23306/cutejava?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true # url: jdbc:mysql://192.168.100.128:23306/cutejava?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: root username: root
password: kd123456 password: kd123456
# 初始连接数,建议设置为与最小空闲连接数相同 # 初始连接数,建议设置为与最小空闲连接数相同
@@ -109,24 +126,6 @@ spring:
config: config:
multi-statement-allow: true multi-statement-allow: true
aop-patterns: "cn.odboy.mapper.*,cn.odboy.service.*,cn.odboy.*.mapper.*,cn.odboy.*.service.*" aop-patterns: "cn.odboy.mapper.*,cn.odboy.service.*,cn.odboy.*.mapper.*,cn.odboy.*.service.*"
redis:
database: ${REDIS_DB:1}
host: ${REDIS_HOST:192.168.100.128}
port: ${REDIS_PORT:26379}
password: ${REDIS_PWD:kd123456}
# 连接超时时间
timeout: 5000
# 连接池配置
lettuce:
pool:
# 连接池最大连接数
max-active: 30
# 连接池最大阻塞等待时间(毫秒),负值表示没有限制
max-wait: -1
# 连接池中的最大空闲连接数
max-idle: 20
# 连接池中的最小空闲连接数
min-idle: 1
# 数据库一定不能区分大小写 # 数据库一定不能区分大小写
quartz: quartz:
# 必需,指定使用 JDBC 存储 # 必需,指定使用 JDBC 存储
@@ -136,7 +135,7 @@ spring:
quartz: quartz:
scheduler: scheduler:
# 必需,指定调度器实例的名称 # 必需,指定调度器实例的名称
instanceName: cutejava instanceName: ${spring.application.name}
# 必需,指定调度器实例的 ID # 必需,指定调度器实例的 ID
instanceId: auto instanceId: auto
threadPool: threadPool:
@@ -193,8 +192,8 @@ app:
private-key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A== private-key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
# 鉴权 # 鉴权
jwt: jwt:
# 必须使用最少88位的Base64对该令牌进行编码 # 必须使用最少88位的Base64对该令牌进行编码 cn.odboy.util.CsBase64SecretUtil
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI= base64-secret: YzE5ZWNjMjlkMGY4NDc4MDlmYzE0Y2I0MTk4YTQ4YjY5NTU0OGQxODNjNjQ0MmU1YjBmZTYwYjljYzI0M2M4MTJkZjk3Y2ZlYjg3ZTQxMjM4MjEwY2ZiYzE4YmFiYmZlZDVhM2M1YmI3M2FmNDFmNWJmM2MyMTM1ZDNhMmRmYzY=
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html # 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
token-validity-in-seconds: 14400000 token-validity-in-seconds: 14400000
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 # token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
@@ -204,7 +203,7 @@ app:
# 登录 # 登录
login: login:
# 是否限制单用户登录 # 是否限制单用户登录
single: false single: true
# 验证码 # 验证码
captchaSetting: captchaSetting:
# 验证码类型配置 查看 LoginProperties 类 # 验证码类型配置 查看 LoginProperties 类
@@ -223,7 +222,7 @@ app:
font-size: 25 font-size: 25
# 是否开启 swagger-ui # 是否开启 swagger-ui
swagger: swagger:
enabled: true enabled: false
# 针对@Async # 针对@Async
async-task-pool: async-task-pool:
# 核心线程池大小 # 核心线程池大小
@@ -23,6 +23,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import static cn.odboy.util.CsStringUtil.*;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
@@ -30,27 +31,27 @@ public class CsStringUtilTest {
@Test @Test
public void testToCamelCase() { public void testToCamelCase() {
assertNull(CsStringUtil.toCamelCase(null)); assertNull(toCamelCase(null));
} }
@Test @Test
public void testToCapitalizeCamelCase() { public void testToCapitalizeCamelCase() {
assertNull(CsStringUtil.toCapitalizeCamelCase(null)); assertNull(CsStringUtil.toCapitalizeCamelCase(null));
assertEquals("HelloWorld", CsStringUtil.toCapitalizeCamelCase("hello_world")); assertEquals("HelloWorld", toCapitalizeCamelCase("hello_world"));
} }
@Test @Test
public void testToUnderScoreCase() { public void testToUnderScoreCase() {
assertNull(CsStringUtil.toUnderScoreCase(null)); assertNull(CsStringUtil.toUnderScoreCase(null));
assertEquals("hello_world", CsStringUtil.toUnderScoreCase("helloWorld")); assertEquals("hello_world", toUnderScoreCase("helloWorld"));
assertEquals("\u0000\u0000", CsStringUtil.toUnderScoreCase("\u0000\u0000")); assertEquals("\u0000\u0000", toUnderScoreCase("\u0000\u0000"));
assertEquals("\u0000_a", CsStringUtil.toUnderScoreCase("\u0000A")); assertEquals("\u0000_a", toUnderScoreCase("\u0000A"));
} }
@Test @Test
public void testGetWeekDay() { public void testGetWeekDay() {
SimpleDateFormat simpleDateformat = new SimpleDateFormat("E"); SimpleDateFormat simpleDateformat = new SimpleDateFormat("E");
assertEquals(simpleDateformat.format(new Date()), CsStringUtil.getWeekDay()); assertEquals(simpleDateformat.format(new Date()), getWeekDay());
} }
@Test @Test
+12 -69
View File
@@ -20,21 +20,19 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version> <version>3.5.7</version>
</parent> </parent>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding> <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>11</java.version> <java.version>17</java.version>
<logback.version>1.2.9</logback.version>
<fastjson2.version>2.0.57</fastjson2.version> <fastjson2.version>2.0.57</fastjson2.version>
<druid.version>1.2.27</druid.version> <druid.version>1.2.27</druid.version>
<commons-pool2.version>2.11.1</commons-pool2.version> <commons-pool2.version>2.11.1</commons-pool2.version>
<mybatis-plus.version>3.5.14</mybatis-plus.version> <mybatis-plus.version>3.5.14</mybatis-plus.version>
<hutool.version>5.8.40</hutool.version> <hutool.version>5.8.40</hutool.version>
<!-- <jjwt.version>0.11.5</jjwt.version>-->
<jjwt.version>0.12.6</jjwt.version> <jjwt.version>0.12.6</jjwt.version>
<!-- oshi监控需要指定jna版本, 问题详见 https://github.com/oshi/oshi/issues/1040 --> <!-- oshi监控需要指定jna版本, 问题详见 https://github.com/oshi/oshi/issues/1040 -->
<jna.version>5.8.0</jna.version> <jna.version>5.8.0</jna.version>
@@ -106,13 +104,6 @@
<artifactId>spring-boot-starter-data-redis</artifactId> <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency> </dependency>
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.redisson/redisson &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.redisson</groupId>-->
<!-- <artifactId>redisson</artifactId>-->
<!-- <version>3.50.0</version>-->
<!-- </dependency>-->
<!-- Spring boot websocket --> <!-- Spring boot websocket -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@@ -122,7 +113,7 @@
<!-- mybatisplus --> <!-- mybatisplus -->
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId> <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version> <version>${mybatis-plus.version}</version>
</dependency> </dependency>
<dependency> <dependency>
@@ -173,15 +164,8 @@
<!-- Swagger UI 相关 --> <!-- Swagger UI 相关 -->
<dependency> <dependency>
<groupId>com.github.xiaoymin</groupId> <groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId> <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>3.0.3</version> <version>4.5.0</version>
<exclusions>
<!-- 去掉 swagger-annotations 依赖, 避免冲突 -->
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.swagger</groupId> <groupId>io.swagger</groupId>
@@ -200,7 +184,7 @@
<!-- druid数据源驱动 --> <!-- druid数据源驱动 -->
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId> <artifactId>druid-spring-boot-3-starter</artifactId>
<version>${druid.version}</version> <version>${druid.version}</version>
</dependency> </dependency>
@@ -238,23 +222,6 @@
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<!-- excel工具 -->
<!-- <dependency>-->
<!-- <groupId>org.apache.poi</groupId>-->
<!-- <artifactId>poi</artifactId>-->
<!-- <version>5.4.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.poi</groupId>-->
<!-- <artifactId>poi-ooxml</artifactId>-->
<!-- <version>5.4.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>xerces</groupId>-->
<!-- <artifactId>xercesImpl</artifactId>-->
<!-- <version>2.12.2</version>-->
<!-- </dependency>-->
<!-- fastjson2 --> <!-- fastjson2 -->
<dependency> <dependency>
<groupId>com.alibaba.fastjson2</groupId> <groupId>com.alibaba.fastjson2</groupId>
@@ -373,36 +340,6 @@
<version>3.11.1</version> <version>3.11.1</version>
</dependency> </dependency>
<!-- https://blog.csdn.net/q854214434/article/details/102374684 -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-jta-atomikos</artifactId>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; 旧版本 dingtalk sdk &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>alibaba-dingtalk-service-sdk</artifactId>-->
<!-- <version>2.0.0</version>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>javax.mail</groupId>-->
<!-- <artifactId>mail</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; 新版本 dingtalk sdk &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>dingtalk</artifactId>-->
<!-- <version>2.0.66</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; stream流 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.dingtalk.open</groupId>-->
<!-- <artifactId>app-stream-client</artifactId>-->
<!-- <version>1.3.7</version>-->
<!-- </dependency>-->
<dependency> <dependency>
<groupId>joda-time</groupId> <groupId>joda-time</groupId>
<artifactId>joda-time</artifactId> <artifactId>joda-time</artifactId>
@@ -431,6 +368,12 @@
<artifactId>rhino</artifactId> <artifactId>rhino</artifactId>
<version>1.8.0</version> <version>1.8.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.5.0-jre</version>
</dependency>
</dependencies> </dependencies>
<build> <build>