Skip to content

Commit

Permalink
♻️ 拆分 ballcat-web 模块 && 异常通知自动配置方式重构
Browse files Browse the repository at this point in the history
link gh-237
  • Loading branch information
Hccake committed Jun 14, 2023
1 parent fd42663 commit 1017ee3
Show file tree
Hide file tree
Showing 33 changed files with 408 additions and 332 deletions.
5 changes: 5 additions & 0 deletions ballcat-dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,11 @@
<artifactId>ballcat-spring-boot-starter-web</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-web</artifactId>
<version>${revision}</version>
</dependency>

<!-- websocket -->
<dependency>
Expand Down
5 changes: 3 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<packaging>pom</packaging>
<name>ballcat</name>
<url>https://github.com/hccake/ballcat</url>
<description>项目基本脚手架</description>
<description>一个简单好用的功能组件库</description>

<modules>
<module>ballcat-dependencies</module>
Expand Down Expand Up @@ -82,12 +82,13 @@
<module>tesseract/ballcat-tesseract</module>

<module>web/ballcat-spring-boot-starter-web</module>
<module>web/ballcat-web</module>

<module>websocket/ballcat-websocket</module>
<module>websocket/ballcat-spring-boot-starter-websocket</module>

<module>xss/ballcat-spring-boot-starter-xss</module>
</modules>
</modules>

<properties>
<!-- maven 配置 -->
Expand Down
37 changes: 21 additions & 16 deletions web/ballcat-spring-boot-starter-web/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
<artifactId>ballcat-spring-boot-starter-web</artifactId>

<dependencies>
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-web</artifactId>
</dependency>
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-common-core</artifactId>
Expand All @@ -27,15 +31,10 @@
<groupId>org.ballcat</groupId>
<artifactId>ballcat-common-util</artifactId>
</dependency>
<!--webmvc-->
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-dingtalk</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-spring-boot-starter-mail</artifactId>
<scope>provided</scope>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--validation校验-->
<dependency>
Expand All @@ -46,6 +45,17 @@
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>

<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-dingtalk</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.ballcat</groupId>
<artifactId>ballcat-spring-boot-starter-mail</artifactId>
<optional>true</optional>
</dependency>
<!-- 当引入 actuator 时,针对其异常进行处理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
Expand All @@ -58,21 +68,16 @@
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--webmvc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-starter-undertow</artifactId>
<optional>true</optional>
</dependency>
<!-- 当引入 security 时,针对其异常进行处理 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.ballcat.autoconfigure.web.log.access;
package org.ballcat.autoconfigure.web.accesslog;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ballcat.web.accesslog.AccessLogFilter;
import org.ballcat.web.accesslog.AccessLogHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
Expand All @@ -35,7 +37,7 @@
havingValue = "true")
public class AccessLogAutoConfiguration {

private final AccessLogHandler<?> accessLogService;
private final AccessLogHandler<?> accessLogHandler;

private final AccessLogProperties accessLogProperties;

Expand All @@ -44,7 +46,7 @@ public class AccessLogAutoConfiguration {
public FilterRegistrationBean<AccessLogFilter> accessLogFilterRegistrationBean() {
log.debug("access log 记录拦截器已开启====");
FilterRegistrationBean<AccessLogFilter> registrationBean = new FilterRegistrationBean<>(
new AccessLogFilter(accessLogService, accessLogProperties.getIgnoreUrlPatterns()));
new AccessLogFilter(accessLogHandler, accessLogProperties.getIgnoreUrlPatterns()));
registrationBean.setOrder(accessLogProperties.getFilterOrder());
return registrationBean;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.ballcat.autoconfigure.web.log.access;
package org.ballcat.autoconfigure.web.accesslog;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
Expand All @@ -31,12 +31,12 @@
@ConfigurationProperties(prefix = AccessLogProperties.PREFIX)
public class AccessLogProperties {

public static final String PREFIX = "ballcat.log.access";
public static final String PREFIX = "ballcat.web.accesslog";

/**
* 开启 access log 的记录
*/
private boolean enabled = true;
private boolean enabled = false;

/**
* access log filter 的优先级
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ballcat.web.actuate.ActuatorSecurityFilter;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,105 +16,63 @@
package org.ballcat.autoconfigure.web.exception;

import lombok.RequiredArgsConstructor;
import org.ballcat.autoconfigure.web.exception.handler.DefaultGlobalExceptionHandler;
import org.ballcat.autoconfigure.web.exception.handler.DingTalkGlobalExceptionHandler;
import org.ballcat.autoconfigure.web.exception.handler.MailGlobalExceptionHandler;
import org.ballcat.autoconfigure.web.exception.handler.MultiGlobalExceptionHandler;
import org.ballcat.autoconfigure.web.exception.resolver.GlobalHandlerExceptionResolver;
import org.ballcat.autoconfigure.web.exception.resolver.SecurityHandlerExceptionResolver;
import org.ballcat.common.core.exception.handler.GlobalExceptionHandler;
import org.ballcat.dingtalk.DingTalkSender;
import org.ballcat.mail.sender.MailSender;
import org.ballcat.web.exception.handler.DoNothingGlobalExceptionHandler;
import org.ballcat.web.exception.handler.NoticeGlobalExceptionHandler;
import org.ballcat.web.exception.notice.ExceptionNoticeConfig;
import org.ballcat.web.exception.notice.ExceptionNotifier;
import org.ballcat.web.exception.resolver.GlobalHandlerExceptionResolver;
import org.ballcat.web.exception.resolver.SecurityHandlerExceptionResolver;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
* @author Hccake 2019/10/15 18:20
*/
@Import(ExceptionNoticeConfiguration.class)
@RequiredArgsConstructor
@AutoConfiguration
@EnableConfigurationProperties(ExceptionHandleProperties.class)
@EnableConfigurationProperties(ExceptionNoticeProperties.class)
public class ExceptionAutoConfiguration {

@Value("${spring.application.name: unknown-application}")
private String applicationName;

/**
* 默认的日志处理器
* @return DefaultExceptionHandler
* @deprecated 使用 enabled 来进行配置
* 发送异常通知的全局异常处理器
* @return {@link NoticeGlobalExceptionHandler}
*/
@Bean
@Deprecated
@ConditionalOnBean(ExceptionNotifier.class)
@ConditionalOnMissingBean(GlobalExceptionHandler.class)
@ConditionalOnProperty(prefix = ExceptionHandleProperties.PREFIX, matchIfMissing = true, name = "type",
havingValue = "NONE")
public GlobalExceptionHandler defaultGlobalExceptionHandler() {
return new DefaultGlobalExceptionHandler();
}
public GlobalExceptionHandler noticeGlobalExceptionHandler(
@Value("${spring.application.name: unknown-application}") String applicationName,
ExceptionNoticeProperties exceptionNoticeProperties, List<ExceptionNotifier> exceptionNotifiers) {

@Bean
@ConditionalOnMissingBean(GlobalExceptionHandler.class)
public GlobalExceptionHandler multiGlobalExceptionHandler(ExceptionHandleProperties properties,
ApplicationContext context) {
// 旧代码逻辑
if (properties.getType() != null) {
switch (properties.getType()) {
case NONE:
return new DefaultGlobalExceptionHandler();
case MAIL:
return new MailGlobalExceptionHandler(properties, context.getBean(MailSender.class),
context.getApplicationName());
default:
return new DingTalkGlobalExceptionHandler(properties, context.getBean(DingTalkSender.class),
context.getApplicationName());
}
}
// 为空 或者 为 false
if (!Boolean.TRUE.equals(properties.getEnabled())) {
return new DefaultGlobalExceptionHandler();
}
ExceptionNoticeConfig noticeConfig = new ExceptionNoticeConfig();
noticeConfig.setTime(exceptionNoticeProperties.getTime());
noticeConfig.setMax(exceptionNoticeProperties.getMax());
noticeConfig.setLength(exceptionNoticeProperties.getLength());
noticeConfig.setIgnoreExceptions(exceptionNoticeProperties.getIgnoreExceptions());
noticeConfig.setIgnoreChild(exceptionNoticeProperties.getIgnoreChild());

final Object mailSender;
if (CollectionUtils.isEmpty(properties.getReceiveEmails())) {
mailSender = null;
}
else {
mailSender = context.getBean(MailSender.class);
}
return new MultiGlobalExceptionHandler(properties, context.getApplicationName(), mailSender);
}

/**
* 钉钉消息通知的日志处理器
*/
@Bean
@ConditionalOnMissingBean(GlobalExceptionHandler.class)
@ConditionalOnProperty(prefix = "ballcat.exception", name = "type", havingValue = "DING_TALK")
public GlobalExceptionHandler dingTalkGlobalExceptionHandler(ExceptionHandleProperties exceptionHandleProperties,
ApplicationContext context) {
return new DingTalkGlobalExceptionHandler(exceptionHandleProperties, context.getBean(DingTalkSender.class),
applicationName);
return new NoticeGlobalExceptionHandler(applicationName, noticeConfig, exceptionNotifiers);
}

/**
* 邮件消息通知的日志处理器
* 什么都不做的异常处理器
* @return {@link DoNothingGlobalExceptionHandler}
*/
@Bean
@ConditionalOnMissingBean(GlobalExceptionHandler.class)
@ConditionalOnProperty(prefix = "ballcat.exception", name = "type", havingValue = "MAIL")
public GlobalExceptionHandler mailGlobalExceptionHandler(ExceptionHandleProperties exceptionHandleProperties,
ApplicationContext context) {
return new MailGlobalExceptionHandler(exceptionHandleProperties, context.getBean(MailSender.class),
applicationName);
public GlobalExceptionHandler doNothingGlobalExceptionHandler() {
return new DoNothingGlobalExceptionHandler();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright 2023 the original author or authors.
*
* 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
*
* https://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 org.ballcat.autoconfigure.web.exception;

import lombok.RequiredArgsConstructor;
import org.ballcat.dingtalk.DingTalkSender;
import org.ballcat.mail.sender.MailSender;
import org.ballcat.web.exception.notice.DingTalkExceptionNotifier;
import org.ballcat.web.exception.notice.MailExceptionNotifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.stream.Collectors;

/**
* 异常通知配置
*
* @author Hccake
*/
@Configuration(proxyBeanMethods = false)
public class ExceptionNoticeConfiguration {

@ConditionalOnClass(MailSender.class)
@ConditionalOnMissingBean(MailExceptionNotifier.class)
@ConditionalOnProperty(prefix = ExceptionNoticeProperties.PREFIX, name = "mail.recipient-emails")
@Configuration(proxyBeanMethods = false)
static class MailExceptionNotifierConfiguration {

@Bean
public MailExceptionNotifier mailExceptionNotifier(MailSender mailSender,
ExceptionNoticeProperties exceptionNoticeProperties) {
List<String> recipientEmails = exceptionNoticeProperties.getMail().getRecipientEmails();
return new MailExceptionNotifier(mailSender, recipientEmails);
}

}

@ConditionalOnClass(DingTalkSender.class)
@ConditionalOnMissingBean(DingTalkExceptionNotifier.class)
@ConditionalOnProperty(prefix = ExceptionNoticeProperties.PREFIX, name = "ding-talk.senders")
@Configuration(proxyBeanMethods = false)
static class DingTalkExceptionNotifierConfiguration {

@Bean
public DingTalkExceptionNotifier dingTalkExceptionNotifier(
ExceptionNoticeProperties exceptionNoticeProperties) {
ExceptionNoticeProperties.DingTalk dingTalk = exceptionNoticeProperties.getDingTalk();
ExceptionNoticeProperties.DingTalk.Sender sender = dingTalk.getSender();
DingTalkSender dingTalkSender = new DingTalkSender(sender.getUrl()).setSecret(sender.getSecret());
return new DingTalkExceptionNotifier(dingTalkSender, dingTalk.getAtAll());
}

}

}
Loading

0 comments on commit 1017ee3

Please sign in to comment.