当前位置: 代码网 > it编程>编程语言>Java > Spring Boot整合全局异常处理器、junit、多环境、logback的过程

Spring Boot整合全局异常处理器、junit、多环境、logback的过程

2026年04月02日 Java 我要评论
一、springboot整合全局异常处理器1. 非前后端分离(了解)适用于传统mvc应用,返回视图页面:@componentpublic class globalexceptionresolver i

一、springboot整合全局异常处理器

1. 非前后端分离(了解)

适用于传统mvc应用,返回视图页面:

@component
public class globalexceptionresolver implements handlerexceptionresolver {
    @override
    public modelandview resolveexception(httpservletrequest request, 
                                       httpservletresponse response, 
                                       object handler, 
                                       exception ex) {
        modelandview mv = new modelandview();
        // 设置错误信息
        mv.addobject("message", ex.getmessage());
        mv.addobject("exception", ex);
        // 跳转到错误页面
        mv.setviewname("error");
        return mv;
    }
}

2. 前后端分离(重点)

适用于restful api,返回json格式数据:

@restcontrolleradvice
public class globalexceptionhandler {
    /**
     * 处理所有异常
     */
    @exceptionhandler(exception.class)
    public result handleexception(exception e) {
        // 记录日志
        log.error("系统异常: ", e);
        // 返回统一格式
        return result.error("系统异常,请联系管理员");
    }
    /**
     * 处理业务异常
     */
    @exceptionhandler(businessexception.class)
    public result handlebusinessexception(businessexception e) {
        return result.error(e.getmessage());
    }
    /**
     * 处理参数验证异常
     */
    @exceptionhandler(methodargumentnotvalidexception.class)
    public result handlevalidexception(methodargumentnotvalidexception e) {
        string message = e.getbindingresult().getfielderrors().stream()
            .map(fielderror::getdefaultmessage)
            .collect(collectors.joining(", "));
        return result.error(message);
    }
}
// 统一返回结果类
@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. 添加依赖

<!-- pom.xml -->
<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-test</artifactid>
    <scope>test</scope>
</dependency>

2. 编写测试类

import org.junit.jupiter.api.test;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.boot.test.context.springboottest;
/**
 * 测试演进历程:
 * 1. 传统方式:main方法启动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() {
        // 模拟测试
        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测试示例
    @test
    void testwithmock() {
        // 使用mockito模拟依赖
        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多环境配置

1. 多环境配置语法

  • 主配置文件:application.yml
  • 环境配置文件:application-{profile}.yml

2. 创建多套环境配置

application-dev.yml(开发环境)

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: debug

application-test.yml(测试环境)

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: info

application-prod.yml(生产环境)

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.log

3. 激活环境

方式一:在application.yml中指定

# application.yml
spring:
  profiles:
    active: dev

方式二:启动参数指定

# 命令行启动
java -jar myapp.jar --spring.profiles.active=prod
# 或使用系统属性
java -dspring.profiles.active=test -jar myapp.jar

方式三:通过环境变量

# 设置环境变量
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. 添加依赖(已包含在starter中)

springboot默认使用logback,无需额外配置依赖。

2. logback配置文件

创建logback-spring.xmlresources目录下:

<?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"/>
    <!-- 控制台输出 -->
    <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>
    <!-- 错误日志单独输出 -->
    <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>
    <!-- 多环境配置 -->
    <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) {
        // 不同级别的日志
        logger.trace("trace级别日志");
        logger.debug("debug级别日志,用户id: {}", id);
        logger.info("info级别日志");
        logger.warn("warn级别日志");
        logger.error("error级别日志");
        // 使用占位符,避免字符串拼接
        logger.info("用户查询: id={}, time={}", id, system.currenttimemillis());
        return userservice.getuserbyid(id);
    }
}

五、完整项目结构示例

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

总结要点

  • 异常处理:前后端分离项目使用@restcontrolleradvice+@exceptionhandler
  • 单元测试:使用@springboottest注解,支持依赖注入
  • 多环境配置:通过application-{profile}.ymlspring.profiles.active管理
  • 日志配置:使用logback-spring.xml,支持多环境不同日志级别
  • 最佳实践:生产环境关闭调试日志,使用文件日志并配置滚动策略

到此这篇关于spring boot整合全局异常处理器、junit、多环境、logback的过程的文章就介绍到这了,更多相关spring boot全局异常处理器内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com