Spring Boot整合全局異常處理器、junit、多環(huán)境、logback的過(guò)程
一、SpringBoot整合全局異常處理器
1. 非前后端分離(了解)
適用于傳統(tǒng)MVC應(yīng)用,返回視圖頁(yè)面:
@Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
ModelAndView mv = new ModelAndView();
// 設(shè)置錯(cuò)誤信息
mv.addObject("message", ex.getMessage());
mv.addObject("exception", ex);
// 跳轉(zhuǎn)到錯(cuò)誤頁(yè)面
mv.setViewName("error");
return mv;
}
}2. 前后端分離(重點(diǎn))
適用于RESTful API,返回JSON格式數(shù)據(jù):
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 處理所有異常
*/
@ExceptionHandler(Exception.class)
public Result handleException(Exception e) {
// 記錄日志
log.error("系統(tǒng)異常: ", e);
// 返回統(tǒng)一格式
return Result.error("系統(tǒng)異常,請(qǐng)聯(lián)系管理員");
}
/**
* 處理業(yè)務(wù)異常
*/
@ExceptionHandler(BusinessException.class)
public Result handleBusinessException(BusinessException e) {
return Result.error(e.getMessage());
}
/**
* 處理參數(shù)驗(yàn)證異常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result handleValidException(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
return Result.error(message);
}
}
// 統(tǒng)一返回結(jié)果類(lèi)
@Data
public class Result<T> {
private Integer code;
private String message;
private T data;
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage("操作成功");
result.setData(data);
return result;
}
public static <T> Result<T> error(String message) {
Result<T> result = new Result<>();
result.setCode(500);
result.setMessage(message);
return result;
}
}二、SpringBoot整合JUnit
1. 添加依賴(lài)
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>2. 編寫(xiě)測(cè)試類(lèi)
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* 測(cè)試演進(jìn)歷程:
* 1. 傳統(tǒng)方式:main方法啟動(dòng)Spring
* new ClassPathXmlApplicationContext("applicationContext.xml");
*
* 2. Spring整合JUnit4:
* @RunWith(SpringJUnit4ClassRunner.class)
* @ContextConfiguration("applicationContext.xml")
*
* 3. SpringBoot整合JUnit5(推薦):
* @SpringBootTest
*/
@SpringBootTest
class UserServiceTest {
@Autowired
private UserService userService;
@Test
void testGetUserById() {
// 模擬測(cè)試
User user = userService.getUserById(1L);
assertNotNull(user);
assertEquals("張三", user.getName());
}
@Test
@Transactional
@Rollback
void testSaveUser() {
User user = new User();
user.setName("李四");
user.setAge(25);
User savedUser = userService.save(user);
assertNotNull(savedUser.getId());
}
// Mock測(cè)試示例
@Test
void testWithMock() {
// 使用Mockito模擬依賴(lài)
UserRepository mockRepo = mock(UserRepository.class);
when(mockRepo.findById(1L)).thenReturn(Optional.of(new User(1L, "王五")));
UserService service = new UserService(mockRepo);
User user = service.getUserById(1L);
assertEquals("王五", user.getName());
}
}三、SpringBoot多環(huán)境配置
1. 多環(huán)境配置語(yǔ)法
- 主配置文件:
application.yml - 環(huán)境配置文件:
application-{profile}.yml
2. 創(chuàng)建多套環(huán)境配置
application-dev.yml(開(kāi)發(fā)環(huán)境):
server:
port: 8081
servlet:
context-path: /dev-api
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/dev_db?useSSL=false&serverTimezone=Asia/Shanghai
username: dev_user
password: dev123
logging:
level:
com.example: debugapplication-test.yml(測(cè)試環(huán)境):
server:
port: 8082
servlet:
context-path: /test-api
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://test-server:3306/test_db?useSSL=false&serverTimezone=Asia/Shanghai
username: test_user
password: test123
logging:
level:
com.example: infoapplication-prod.yml(生產(chǎn)環(huán)境):
server:
port: 8083
servlet:
context-path: /api
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://prod-master:3306/prod_db?useSSL=false&serverTimezone=Asia/Shanghai
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
logging:
level:
com.example: warn
file:
name: logs/application.log3. 激活環(huán)境
方式一:在application.yml中指定
# application.yml
spring:
profiles:
active: dev方式二:?jiǎn)?dòng)參數(shù)指定
# 命令行啟動(dòng) java -jar myapp.jar --spring.profiles.active=prod # 或使用系統(tǒng)屬性 java -Dspring.profiles.active=test -jar myapp.jar
方式三:通過(guò)環(huán)境變量
# 設(shè)置環(huán)境變量 export SPRING_PROFILES_ACTIVE=prod
方式四:使用分組(Spring Boot 2.4+)
# application.yml
spring:
profiles:
active: dev,audit
group:
dev: dev,debug
prod: prod,audit,metrics四、SpringBoot整合Logback日志
1. 添加依賴(lài)(已包含在starter中)
SpringBoot默認(rèn)使用Logback,無(wú)需額外配置依賴(lài)。
2. Logback配置文件
創(chuàng)建logback-spring.xml在resources目錄下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 定義日志輸出格式 -->
<property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
<!-- 控制臺(tái)輸出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 文件輸出 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天歸檔,保存30天 -->
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<!-- 錯(cuò)誤日志單獨(dú)輸出 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/error.log</file>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!-- 多環(huán)境配置 -->
<springProfile name="dev">
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
</root>
<logger name="com.example" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE"/>
</logger>
</springProfile>
<springProfile name="test">
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</springProfile>
<springProfile name="prod">
<root level="WARN">
<appender-ref ref="FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
<logger name="com.example" level="INFO" additivity="false">
<appender-ref ref="FILE"/>
</logger>
</springProfile>
</configuration>3. 在代碼中使用日志
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
public User getUser(Long id) {
// 不同級(jí)別的日志
logger.trace("trace級(jí)別日志");
logger.debug("debug級(jí)別日志,用戶(hù)ID: {}", id);
logger.info("info級(jí)別日志");
logger.warn("warn級(jí)別日志");
logger.error("error級(jí)別日志");
// 使用占位符,避免字符串拼接
logger.info("用戶(hù)查詢(xún): id={}, time={}", id, System.currentTimeMillis());
return userService.getUserById(id);
}
}五、完整項(xiàng)目結(jié)構(gòu)示例
src/main/java/
├── com.example.demo
│ ├── config/
│ │ └── GlobalExceptionHandler.java
│ ├── controller/
│ │ └── UserController.java
│ ├── service/
│ │ └── UserService.java
│ └── DemoApplication.java
├── resources/
│ ├── application.yml
│ ├── application-dev.yml
│ ├── application-test.yml
│ ├── application-prod.yml
│ └── logback-spring.xml
└── test/java/
└── com.example.demo
└── UserServiceTest.java總結(jié)要點(diǎn)
- 異常處理:前后端分離項(xiàng)目使用
@RestControllerAdvice+@ExceptionHandler - 單元測(cè)試:使用
@SpringBootTest注解,支持依賴(lài)注入 - 多環(huán)境配置:通過(guò)
application-{profile}.yml和spring.profiles.active管理 - 日志配置:使用
logback-spring.xml,支持多環(huán)境不同日志級(jí)別 - 最佳實(shí)踐:生產(chǎn)環(huán)境關(guān)閉調(diào)試日志,使用文件日志并配置滾動(dòng)策略
到此這篇關(guān)于Spring Boot整合全局異常處理器、junit、多環(huán)境、logback的過(guò)程的文章就介紹到這了,更多相關(guān)Spring Boot全局異常處理器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解AngularJs與SpringMVC簡(jiǎn)單結(jié)合使用
本篇文章主要介紹了AngularJs與SpringMVC簡(jiǎn)單結(jié)合使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06
springboot?vue接口測(cè)試HutoolUtil?TreeUtil處理樹(shù)形結(jié)構(gòu)
這篇文章主要介紹了springboot?vue接口測(cè)試HutoolUtil?TreeUtil處理樹(shù)形結(jié)構(gòu),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Spring Security 實(shí)現(xiàn)用戶(hù)名密碼登錄流程源碼詳解
在服務(wù)端的安全管理使用了Spring Security,用戶(hù)登錄成功之后,Spring Security幫你把用戶(hù)信息保存在Session里,但是具體保存在哪里,要是不深究你可能就不知道,今天小編就帶大家具體了解一下Spring Security實(shí)現(xiàn)用戶(hù)名密碼登錄的流程2021-11-11
idea中MavenWeb項(xiàng)目不能創(chuàng)建Servlet的解決方案
這篇文章主要介紹了idea中MavenWeb項(xiàng)目不能創(chuàng)建Servlet的解決方案,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
MyBatis使用<foreach>標(biāo)簽like查詢(xún)報(bào)錯(cuò)解決問(wèn)題
這篇文章主要介紹了MyBatis使用<foreach>標(biāo)簽like查詢(xún)報(bào)錯(cuò)解決問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
淺談spring boot使用thymeleaf版本的問(wèn)題
這篇文章主要介紹了spring boot使用thymeleaf版本的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
使用Java動(dòng)態(tài)創(chuàng)建Flowable會(huì)簽?zāi)P偷氖纠a
動(dòng)態(tài)創(chuàng)建流程模型,尤其是會(huì)簽(Parallel Gateway)模型,是提升系統(tǒng)靈活性和響應(yīng)速度的關(guān)鍵技術(shù)之一,本文將通過(guò)Java編程語(yǔ)言,深入探討如何在運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建包含會(huì)簽環(huán)節(jié)的Flowable流程模型,需要的朋友可以參考下2024-05-05
visual studio2022 JNI開(kāi)發(fā)流程的實(shí)現(xiàn)
本文主要介紹了通過(guò)IDEA創(chuàng)建Maven項(xiàng)目并生成JNI頭文件,使用Visual Studio 2022構(gòu)建DLL,最后在Java中加載并調(diào)用C++實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2025-07-07

