租赁系统
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
package com.m2pool.lease.config;
|
||||
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||
|
||||
public class JacksonMessageConverter extends Jackson2JsonMessageConverter {
|
||||
public JacksonMessageConverter() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fromMessage(Message message) {
|
||||
message.getMessageProperties().setContentType("application/json");
|
||||
return super.fromMessage(message);
|
||||
}
|
||||
}
|
||||
91
src/main/java/com/m2pool/lease/config/LoginInterceptor.java
Normal file
91
src/main/java/com/m2pool/lease/config/LoginInterceptor.java
Normal file
@@ -0,0 +1,91 @@
|
||||
package com.m2pool.lease.config;
|
||||
|
||||
import com.m2pool.lease.annotation.LoginRequired;
|
||||
import com.m2pool.lease.entity.LeaseUser;
|
||||
import com.m2pool.lease.exception.AuthException;
|
||||
import com.m2pool.lease.redis.RedisAuthKey;
|
||||
import com.m2pool.lease.redis.service.RedisService;
|
||||
import com.m2pool.lease.utils.JwtUtils;
|
||||
import com.m2pool.lease.utils.SecurityUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.m2pool.lease.utils.JwtUtils.AUTHENTICATION;
|
||||
import static com.m2pool.lease.utils.JwtUtils.EXPIRETIME;
|
||||
|
||||
@Component
|
||||
public class LoginInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
// 如果不是映射到方法直接通过
|
||||
if (!(handler instanceof HandlerMethod)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String uri = request.getRequestURI();
|
||||
if (uri.contains("/doc.html") || uri.contains("/webjars/")
|
||||
|| uri.contains("/swagger-resources") || uri.contains("/v2/api-docs")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
||||
Method method = handlerMethod.getMethod();
|
||||
|
||||
// 获取方法上的注解
|
||||
LoginRequired loginRequired = method.getAnnotation(LoginRequired.class);
|
||||
// 如果方法上没有注解,获取类上的注解
|
||||
if (loginRequired == null) {
|
||||
loginRequired = handlerMethod.getBeanType().getAnnotation(LoginRequired.class);
|
||||
}
|
||||
|
||||
// 如果没有注解或者注解值为true,则校验token
|
||||
if (loginRequired == null || loginRequired.value()) {
|
||||
String token = request.getHeader(AUTHENTICATION);
|
||||
if (token == null || !isValidToken(token)) {
|
||||
throw new AuthException("用户未登录");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 验证token 并刷新token
|
||||
*/
|
||||
private boolean isValidToken(String token) {
|
||||
String userEmail = JwtUtils.getUserName(token);
|
||||
String getUserId = JwtUtils.getUserId(token);
|
||||
//1.把userEmail存入ThreadLocal 本地线程变量中
|
||||
SecurityUtils.setUserEmail(userEmail);
|
||||
SecurityUtils.setUserId(Long.valueOf(getUserId));
|
||||
//2.校验token是否过期
|
||||
String userKey = RedisAuthKey.getUserLoginKey(userEmail);
|
||||
LeaseUser loginUser = redisService.getCacheObject(userKey);
|
||||
if (loginUser == null){
|
||||
return false;
|
||||
}
|
||||
//3.刷新token 过期时间
|
||||
redisService.setCacheObject(userKey, loginUser, EXPIRETIME, TimeUnit.MINUTES);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
|
||||
SecurityUtils.remove();
|
||||
}
|
||||
}
|
||||
289
src/main/java/com/m2pool/lease/config/RabbitMQConfig.java
Normal file
289
src/main/java/com/m2pool/lease/config/RabbitMQConfig.java
Normal file
@@ -0,0 +1,289 @@
|
||||
package com.m2pool.lease.config;
|
||||
|
||||
|
||||
import org.springframework.amqp.core.*;
|
||||
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.m2pool.lease.constant.RabbitmqConstant.*;
|
||||
|
||||
@Configuration
|
||||
public class RabbitMQConfig {
|
||||
|
||||
@Bean
|
||||
public MessageConverter jackson2JsonMessageConverter() {
|
||||
//自动生成消息唯一id
|
||||
//jackson2JsonMessageConverter.setCreateMessageIds(true);
|
||||
return new JacksonMessageConverter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
|
||||
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
|
||||
rabbitTemplate.setMessageConverter(jackson2JsonMessageConverter());
|
||||
|
||||
//// 自定义 MessagePostProcessor 来设置 content-type
|
||||
//rabbitTemplate.setBeforePublishPostProcessors(new MessagePostProcessor() {
|
||||
// @Override
|
||||
// public Message postProcessMessage(Message message) {
|
||||
// // 设置 content-type 为 application/json
|
||||
// message.getMessageProperties().setContentType("application/json");
|
||||
// return message;
|
||||
// }
|
||||
//});
|
||||
// 开启发布确认模式
|
||||
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
|
||||
if (ack) {
|
||||
System.out.println("消息发送成功,correlationData: " + correlationData);
|
||||
} else {
|
||||
System.out.println("消息发送失败,原因: " + cause);
|
||||
// 这里可以添加将失败消息存储到数据库的逻辑
|
||||
}
|
||||
});
|
||||
rabbitTemplate.setMandatory(true);
|
||||
return rabbitTemplate;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
|
||||
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
|
||||
factory.setConnectionFactory(connectionFactory);
|
||||
//消费者序列化
|
||||
factory.setMessageConverter(jackson2JsonMessageConverter());
|
||||
factory.setConcurrentConsumers(3); // 设置初始消费者数量
|
||||
factory.setMaxConcurrentConsumers(5); // 设置最大消费者数量
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 矿池代理队列
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Queue poolProxyQueue() {
|
||||
// durable 设置为 true 表示队列持久化
|
||||
return new Queue(POOL_PROXY_QUEUE_NAME, true);
|
||||
}
|
||||
|
||||
//----------------定义订单延迟队列------------------------
|
||||
|
||||
/**
|
||||
* 死信 交换机
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public DirectExchange deadLetterExchange() {
|
||||
return new DirectExchange(DEAD_LETTER_EXCHANGE_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 死信 队列
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Queue deadLetterQueue() {
|
||||
return new Queue(DEAD_LETTER_QUEUE_NAME, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 死信 队列绑定死信交换机
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Binding deadLetterBinding() {
|
||||
return BindingBuilder.bind(deadLetterQueue()).to(deadLetterExchange()).with(DEAD_LETTER_ROUTING_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单超时消息 交换机
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public DirectExchange orderOvertimeExchange() {
|
||||
return new DirectExchange(ORDER_OVERTIME_EXCHANGE_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单超时消息 队列 (死信交换机达成延迟队列功能)
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Queue orderOvertimeQueue() {
|
||||
Map<String, Object> args = new HashMap<>();
|
||||
// 设置死信交换机
|
||||
args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE_NAME);
|
||||
// 设置死信路由键
|
||||
args.put("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY);
|
||||
// 设置队列中消息的 TTL(单位:毫秒)
|
||||
args.put("x-message-ttl", 900000);
|
||||
return new Queue(ORDER_OVERTIME_QUEUE_NAME, true, false, false, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单超时消息 队列绑定普通交换机
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Binding orderOvertimeBinding() {
|
||||
return BindingBuilder.bind(orderOvertimeQueue()).to(orderOvertimeExchange()).with(ORDER_OVERTIME_ROUTING_KEY);
|
||||
}
|
||||
|
||||
//----------------定义订单延迟队列------------------------
|
||||
|
||||
//----------------定义支付相关队列------------------------
|
||||
/**
|
||||
* 声明 Topic 类型的交换机
|
||||
*/
|
||||
@Bean
|
||||
public DirectExchange payExchange() {
|
||||
return new DirectExchange(PAY_EXCHANGE);
|
||||
}
|
||||
|
||||
// 支付相关队列声明
|
||||
/**
|
||||
* 声明支付消息队列
|
||||
*/
|
||||
@Bean
|
||||
public Queue payAutoQueue() {
|
||||
return new Queue(PAY_AUTO_QUEUE, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 声明支付返回消息队列
|
||||
*/
|
||||
@Bean
|
||||
public Queue payAutoReturnQueue() {
|
||||
return new Queue(PAY_AUTO_RETURN_QUEUE, true);
|
||||
}
|
||||
|
||||
// 余额充值相关队列声明
|
||||
/**
|
||||
* 声明余额充值消息队列
|
||||
*/
|
||||
@Bean
|
||||
public Queue payRechargeQueue() {
|
||||
return new Queue(PAY_RECHARGE_QUEUE, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 声明余额充值返回信息队列
|
||||
*/
|
||||
@Bean
|
||||
public Queue payRechargeReturnQueue() {
|
||||
return new Queue(PAY_RECHARGE_RETURN_QUEUE, true);
|
||||
}
|
||||
|
||||
// 余额提现相关队列声明
|
||||
/**
|
||||
* 声明余额提现消息队列
|
||||
*/
|
||||
@Bean
|
||||
public Queue payWithdrawQueue() {
|
||||
return new Queue(PAY_WITHDRAW_QUEUE, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 声明余额提现返回信息队列
|
||||
*/
|
||||
@Bean
|
||||
public Queue payWithdrawReturnQueue() {
|
||||
return new Queue(PAY_WITHDRAW_RETURN_QUEUE, true);
|
||||
}
|
||||
|
||||
// 支付相关绑定
|
||||
/**
|
||||
* 将支付消息队列绑定到交换机
|
||||
*/
|
||||
@Bean
|
||||
public Binding payAutoBinding() {
|
||||
return BindingBuilder.bind(payAutoQueue()).to(payExchange()).with(PAY_AUTO_ROUTING_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将支付返回消息队列绑定到交换机
|
||||
*/
|
||||
@Bean
|
||||
public Binding payAutoReturnBinding() {
|
||||
return BindingBuilder.bind(payAutoReturnQueue()).to(payExchange()).with(PAY_AUTO_RETURN_ROUTING_KEY);
|
||||
}
|
||||
|
||||
|
||||
// 余额充值相关绑定
|
||||
/**
|
||||
* 将余额充值消息队列绑定到交换机
|
||||
*/
|
||||
@Bean
|
||||
public Binding payRechargeBinding() {
|
||||
return BindingBuilder.bind(payRechargeQueue()).to(payExchange()).with(PAY_RECHARGE_ROUTING_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将余额充值返回信息队列绑定到交换机
|
||||
*/
|
||||
@Bean
|
||||
public Binding payRechargeReturnBinding() {
|
||||
return BindingBuilder.bind(payRechargeReturnQueue()).to(payExchange()).with(PAY_RECHARGE_RETURN_ROUTING_KEY);
|
||||
}
|
||||
|
||||
// 余额提现相关绑定
|
||||
/**
|
||||
* 将余额提现消息队列绑定到交换机
|
||||
*/
|
||||
@Bean
|
||||
public Binding payWithdrawBinding() {
|
||||
return BindingBuilder.bind(payWithdrawQueue()).to(payExchange()).with(PAY_WITHDRAW_ROUTING_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将余额提现返回信息队列绑定到交换机
|
||||
*/
|
||||
@Bean
|
||||
public Binding payWithdrawReturnBinding() {
|
||||
return BindingBuilder.bind(payWithdrawReturnQueue()).to(payExchange()).with(PAY_WITHDRAW_RETURN_ROUTING_KEY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//钱包删除 提现相关绑定
|
||||
|
||||
|
||||
@Bean
|
||||
public Queue deleteWalletReturnQueue() {
|
||||
return new Queue(DELETE_WALLET_RETURN_QUEUE, true);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Queue deleteWalletQueue() {
|
||||
return new Queue(DELETE_WALLET_QUEUE, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将钱包删除消息队列绑定到交换机
|
||||
*/
|
||||
@Bean
|
||||
public Binding deleteWalletBinding() {
|
||||
return BindingBuilder.bind(deleteWalletQueue()).to(payExchange()).with(DELETE_WALLET_ROUTING_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将钱包删除返回信息队列绑定到交换机
|
||||
*/
|
||||
@Bean
|
||||
public Binding deleteWalletReturnBinding() {
|
||||
return BindingBuilder.bind(deleteWalletReturnQueue()).to(payExchange()).with(DELETE_WALLET_RETURN_ROUTING_KEY);
|
||||
}
|
||||
|
||||
|
||||
//----------------定义支付相关队列------------------------
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package com.m2pool.lease.config;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.*;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||
import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* @Description swagger自动配置
|
||||
* @Date 2024/6/12 15:28
|
||||
* @Author dy
|
||||
*/
|
||||
@EnableSwagger2
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true)
|
||||
public class SwaggerAutoConfiguration {
|
||||
|
||||
/** 默认的排除路径,排除Spring Boot默认的错误处理路径和端点 */
|
||||
private static final List<String> DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**");
|
||||
|
||||
private static final String BASE_PATH = "/**";
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SwaggerProperties swaggerProperties()
|
||||
{
|
||||
return new SwaggerProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket api(SwaggerProperties swaggerProperties)
|
||||
{
|
||||
// base-path处理
|
||||
if (swaggerProperties.getBasePath().isEmpty())
|
||||
{
|
||||
swaggerProperties.getBasePath().add(BASE_PATH);
|
||||
}
|
||||
|
||||
// noinspection unchecked
|
||||
List<Predicate<String>> basePath = new ArrayList<Predicate<String>>();
|
||||
swaggerProperties.getBasePath().forEach(path -> basePath.add(PathSelectors.ant(path)));
|
||||
|
||||
// exclude-path处理 需要额外排除的url规则
|
||||
if (swaggerProperties.getExcludePath().isEmpty())
|
||||
{
|
||||
swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH);
|
||||
}
|
||||
|
||||
ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2).host(swaggerProperties.getHost())
|
||||
.apiInfo(apiInfo(swaggerProperties)).select()
|
||||
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()));
|
||||
|
||||
swaggerProperties.getBasePath().forEach(p -> builder.paths(PathSelectors.ant(p)));
|
||||
swaggerProperties.getExcludePath().forEach(p -> builder.paths(PathSelectors.ant(p).negate()));
|
||||
|
||||
|
||||
return builder.build().securitySchemes(securitySchemes()).securityContexts(securityContexts()).pathMapping("/lease");
|
||||
|
||||
}
|
||||
|
||||
/** 安全模式,指定token通过Authorization头请求头传递 */
|
||||
private List<SecurityScheme> securitySchemes()
|
||||
{
|
||||
List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
|
||||
apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
|
||||
return apiKeyList;
|
||||
}
|
||||
|
||||
/** 安全上下文 */
|
||||
private List<SecurityContext> securityContexts()
|
||||
{
|
||||
List<SecurityContext> securityContexts = new ArrayList<>();
|
||||
securityContexts.add(
|
||||
SecurityContext.builder()
|
||||
.securityReferences(defaultAuth())
|
||||
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
|
||||
.build());
|
||||
return securityContexts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 默认的全局鉴权策略
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<SecurityReference> defaultAuth()
|
||||
{
|
||||
//
|
||||
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
|
||||
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
|
||||
authorizationScopes[0] = authorizationScope;
|
||||
List<SecurityReference> securityReferences = new ArrayList<>();
|
||||
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
|
||||
return securityReferences;
|
||||
}
|
||||
|
||||
|
||||
private ApiInfo apiInfo(SwaggerProperties swaggerProperties)
|
||||
{
|
||||
return new ApiInfoBuilder()
|
||||
.title(swaggerProperties.getTitle())
|
||||
.description(swaggerProperties.getDescription())
|
||||
.license(swaggerProperties.getLicense())
|
||||
.licenseUrl(swaggerProperties.getLicenseUrl())
|
||||
.termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
|
||||
.contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail()))
|
||||
.version(swaggerProperties.getVersion())
|
||||
.build();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.m2pool.lease.config;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
|
||||
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
|
||||
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description TODO
|
||||
* @Date 2024/6/12 17:14
|
||||
* @Author dy
|
||||
*/
|
||||
@Component
|
||||
public class SwaggerBeanPostProcessor implements 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> copy = mappings.stream().filter(mapping -> mapping.getPatternParser() == null)
|
||||
.collect(Collectors.toList());
|
||||
mappings.clear();
|
||||
mappings.addAll(copy);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean)
|
||||
{
|
||||
try
|
||||
{
|
||||
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
|
||||
field.setAccessible(true);
|
||||
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
|
||||
}
|
||||
catch (IllegalArgumentException | IllegalAccessException e)
|
||||
{
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
350
src/main/java/com/m2pool/lease/config/SwaggerProperties.java
Normal file
350
src/main/java/com/m2pool/lease/config/SwaggerProperties.java
Normal file
@@ -0,0 +1,350 @@
|
||||
package com.m2pool.lease.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description Swagger配置
|
||||
* @Date 2024/6/12 15:16
|
||||
* @Author dy
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties("swagger")
|
||||
public class SwaggerProperties {
|
||||
/**
|
||||
* 是否开启swagger
|
||||
*/
|
||||
private Boolean enabled;
|
||||
|
||||
/**
|
||||
* swagger会解析的包路径
|
||||
**/
|
||||
private String basePackage = "";
|
||||
|
||||
/**
|
||||
* swagger会解析的url规则
|
||||
**/
|
||||
private List<String> basePath = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 在basePath基础上需要排除的url规则
|
||||
**/
|
||||
private List<String> excludePath = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 标题
|
||||
**/
|
||||
private String title = "";
|
||||
|
||||
/**
|
||||
* 描述
|
||||
**/
|
||||
private String description = "";
|
||||
|
||||
/**
|
||||
* 版本
|
||||
**/
|
||||
private String version = "";
|
||||
|
||||
/**
|
||||
* 许可证
|
||||
**/
|
||||
private String license = "";
|
||||
|
||||
/**
|
||||
* 许可证URL
|
||||
**/
|
||||
private String licenseUrl = "";
|
||||
|
||||
/**
|
||||
* 服务条款URL
|
||||
**/
|
||||
private String termsOfServiceUrl = "";
|
||||
|
||||
/**
|
||||
* host信息
|
||||
**/
|
||||
private String host = "";
|
||||
|
||||
/**
|
||||
* 联系人信息
|
||||
*/
|
||||
private Contact contact = new Contact();
|
||||
|
||||
/**
|
||||
* 全局统一鉴权配置
|
||||
**/
|
||||
private Authorization authorization = new Authorization();
|
||||
|
||||
public Boolean getEnabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getBasePackage()
|
||||
{
|
||||
return basePackage;
|
||||
}
|
||||
|
||||
public void setBasePackage(String basePackage)
|
||||
{
|
||||
this.basePackage = basePackage;
|
||||
}
|
||||
|
||||
public List<String> getBasePath()
|
||||
{
|
||||
return basePath;
|
||||
}
|
||||
|
||||
public void setBasePath(List<String> basePath)
|
||||
{
|
||||
this.basePath = basePath;
|
||||
}
|
||||
|
||||
public List<String> getExcludePath()
|
||||
{
|
||||
return excludePath;
|
||||
}
|
||||
|
||||
public void setExcludePath(List<String> excludePath)
|
||||
{
|
||||
this.excludePath = excludePath;
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version)
|
||||
{
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getLicense()
|
||||
{
|
||||
return license;
|
||||
}
|
||||
|
||||
public void setLicense(String license)
|
||||
{
|
||||
this.license = license;
|
||||
}
|
||||
|
||||
public String getLicenseUrl()
|
||||
{
|
||||
return licenseUrl;
|
||||
}
|
||||
|
||||
public void setLicenseUrl(String licenseUrl)
|
||||
{
|
||||
this.licenseUrl = licenseUrl;
|
||||
}
|
||||
|
||||
public String getTermsOfServiceUrl()
|
||||
{
|
||||
return termsOfServiceUrl;
|
||||
}
|
||||
|
||||
public void setTermsOfServiceUrl(String termsOfServiceUrl)
|
||||
{
|
||||
this.termsOfServiceUrl = termsOfServiceUrl;
|
||||
}
|
||||
|
||||
public String getHost()
|
||||
{
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host)
|
||||
{
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public Contact getContact()
|
||||
{
|
||||
return contact;
|
||||
}
|
||||
|
||||
public void setContact(Contact contact)
|
||||
{
|
||||
this.contact = contact;
|
||||
}
|
||||
|
||||
public Authorization getAuthorization()
|
||||
{
|
||||
return authorization;
|
||||
}
|
||||
|
||||
public void setAuthorization(Authorization authorization)
|
||||
{
|
||||
this.authorization = authorization;
|
||||
}
|
||||
|
||||
public static class Contact
|
||||
{
|
||||
/**
|
||||
* 联系人
|
||||
**/
|
||||
private String name = "";
|
||||
/**
|
||||
* 联系人url
|
||||
**/
|
||||
private String url = "";
|
||||
/**
|
||||
* 联系人email
|
||||
**/
|
||||
private String email = "";
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getUrl()
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url)
|
||||
{
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getEmail()
|
||||
{
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email)
|
||||
{
|
||||
this.email = email;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Authorization
|
||||
{
|
||||
/**
|
||||
* 鉴权策略ID,需要和SecurityReferences ID保持一致
|
||||
*/
|
||||
private String name = "";
|
||||
|
||||
/**
|
||||
* 需要开启鉴权URL的正则
|
||||
*/
|
||||
private String authRegex = "^.*$";
|
||||
|
||||
/**
|
||||
* 鉴权作用域列表
|
||||
*/
|
||||
private List<AuthorizationScope> authorizationScopeList = new ArrayList<>();
|
||||
|
||||
private List<String> tokenUrlList = new ArrayList<>();
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAuthRegex()
|
||||
{
|
||||
return authRegex;
|
||||
}
|
||||
|
||||
public void setAuthRegex(String authRegex)
|
||||
{
|
||||
this.authRegex = authRegex;
|
||||
}
|
||||
|
||||
public List<AuthorizationScope> getAuthorizationScopeList()
|
||||
{
|
||||
return authorizationScopeList;
|
||||
}
|
||||
|
||||
public void setAuthorizationScopeList(List<AuthorizationScope> authorizationScopeList)
|
||||
{
|
||||
this.authorizationScopeList = authorizationScopeList;
|
||||
}
|
||||
|
||||
public List<String> getTokenUrlList()
|
||||
{
|
||||
return tokenUrlList;
|
||||
}
|
||||
|
||||
public void setTokenUrlList(List<String> tokenUrlList)
|
||||
{
|
||||
this.tokenUrlList = tokenUrlList;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AuthorizationScope
|
||||
{
|
||||
/**
|
||||
* 作用域名称
|
||||
*/
|
||||
private String scope = "";
|
||||
|
||||
/**
|
||||
* 作用域描述
|
||||
*/
|
||||
private String description = "";
|
||||
|
||||
public String getScope()
|
||||
{
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(String scope)
|
||||
{
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.m2pool.lease.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* @Description 资源映射路径
|
||||
* @Date 2024/6/12 17:25
|
||||
* @Author dy
|
||||
*/
|
||||
@Configuration
|
||||
public class SwaggerWebConfiguration implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry)
|
||||
{
|
||||
/** swagger-ui 地址 */
|
||||
registry.addResourceHandler("/swagger-ui/**")
|
||||
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
|
||||
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
|
||||
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
|
||||
}
|
||||
|
||||
}
|
||||
31
src/main/java/com/m2pool/lease/config/ThreadPoolConfig.java
Normal file
31
src/main/java/com/m2pool/lease/config/ThreadPoolConfig.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package com.m2pool.lease.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
@Configuration
|
||||
public class ThreadPoolConfig {
|
||||
|
||||
@Bean(name = "customThreadPool")
|
||||
public ThreadPoolTaskExecutor customTaskThreadPool() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
// 核心线程数
|
||||
executor.setCorePoolSize(5);
|
||||
// 最大线程数
|
||||
executor.setMaxPoolSize(10);
|
||||
// 队列容量
|
||||
executor.setQueueCapacity(50);
|
||||
// 线程空闲时间(秒)
|
||||
executor.setKeepAliveSeconds(30);
|
||||
// 线程名前缀
|
||||
executor.setThreadNamePrefix("custom-task-thread-");
|
||||
// 拒绝策略
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
// 初始化
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
38
src/main/java/com/m2pool/lease/config/WebMvcConfig.java
Normal file
38
src/main/java/com/m2pool/lease/config/WebMvcConfig.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.m2pool.lease.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
@Resource
|
||||
private LoginInterceptor loginInterceptor;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(loginInterceptor)
|
||||
.addPathPatterns("/**");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
|
||||
// 设置允许跨域请求路径
|
||||
registry.addMapping("/**")
|
||||
// 设置允许跨域请求的域名
|
||||
.allowedOriginPatterns("*") //或.allowedOriginPatterns("http://www.baidu.com") 指定域名
|
||||
//是否允许cookie
|
||||
.allowCredentials(true)
|
||||
// 设置允许的请求方式
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE")
|
||||
// 设置允许的header属性
|
||||
.allowedHeaders("*")
|
||||
// 允许跨域时间
|
||||
.maxAge(3600);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user