4.springboot-异常处理

springboot-异常处理

1 创建一个响应类

​ 用于封装数据。

public class Msg<T> implements Serializable {
    private String status;
    private String message;
    private T data;

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Msg() {
    }

    public Msg(String status, String message, T data) {
        this.status = status;
        this.message = message;
        this.data = data;
    }

    @Override
    public String toString() {
        return "Msg{" +
                "status='" + status + '\'' +
                ", message='" + message + '\'' +
                ", data=" + data +
                '}';
    }
}

2 创建一个异常类

public class LoginException extends RuntimeException{
    public LoginException() {
    }

    public LoginException(String message){
        super(message);
    }
}

3 创建一个异常处理类

@ControllerAdvice
public class MyExceptionHandler {

    @ExceptionHandler(LoginException.class)
    @ResponseBody
    public Msg<String> loginExceptionHandler(Exception e){
        System.out.println("出现了异常"+e.getMessage());
        return new Msg<>("400", "出现了异常", e.getMessage());
    }
}

4 创建controller

这里用到的person,大家可以自己创建。

@Controller
public class HelloController {
    @Autowired
    private Person person;

    @ResponseBody
    @GetMapping("/hello")
    public String hello(){
        System.out.println(person);
        return "hello,Spring Boot!";
    }

    @ResponseBody
    @GetMapping("/login")
    public Msg<Person> login(String username){
        System.out.println("开始进行登陆检测");
        if (!"admin".equals(username)){
            throw new LoginException("用户或者密码错误");
        }
        return new Msg<Person>("200", "登陆成功", person);
    }
}

5 访问测试

image-20201020115901097

image-20201020115922579

<think>好的,我现在需要解决用户提到的关于@ControllerAdvice("com.example.springboot.controller")和org.example.springboot.common.Result包名冲突导致异常处理器未生效的问题。首先,我得理解用户的问题背景。 用户在使用Spring Boot时,可能自定义了一个全局异常处理类,并使用了@ControllerAdvice注解指定了基础包。同时,项目中导入了Result类,这个类的包名可能与控制器所在的包有重叠,导致Spring在扫描组件时出现问题,使得异常处理器没有被正确注册。 接下来,我需要分析可能的原因。首先,@ControllerAdvice的basePackages参数如果设置不正确,可能会限制异常处理器的生效范围。如果指定的包名"com.example.springboot.controller"下没有异常处理类,或者Result类所在的包org.example.springboot.common与这个基础包有冲突,可能会导致组件扫描时漏掉异常处理器。 另外,包名冲突的问题可能是指Result类所在的包路径和控制器所在的包路径有部分重叠,导致Spring在扫描时出现混淆。例如,如果@ControllerAdvice指定的包和Result类的包有共同的父包,但结构不同,可能会导致组件扫描未能正确识别异常处理类。 然后,我需要考虑解决方案。首先,检查@ControllerAdvice注解的包路径是否正确,确保它包含了异常处理类所在的包。如果异常处理类不在指定的包下,调整basePackages参数的值。其次,如果Result类所在的包与控制器包有冲突,可能需要重构包结构,将通用类如Result放在独立的包中,避免与业务代码的包重叠。此外,检查组件扫描的配置,确保Spring能够正确扫描到所有必要的包。 最后,可能需要验证异常处理器是否生效,可以通过触发一个异常来测试,或者检查Spring启动时的日志,查看是否有异常处理器的注册信息。如果还存在问题,可能需要检查是否有其他配置干扰,比如重复的@ComponentScan注解或者过滤器、拦截器的影响。 总结起来,解决步骤应该是:确认注解包路径正确性、调整包结构避免冲突、检查组件扫描配置、验证异常处理器注册情况。通过这些步骤逐步排查,应该能解决用户的问题。</think>关于@ControllerAdvice("com.example.springboot.controller")与Result类包名冲突导致异常处理器失效的问题,以下是详细分析及解决方案: 🔍 问题本质分析: 1. 包扫描范围冲突:`@ControllerAdvice("com.example.springboot.controller")`会将扫描范围限定在指定包内 2. 类路径混淆:`org.example.springboot.common.Result`的父包`org.example.springboot`与`com.example.springboot`存在首段包名差异 3. 组件扫描机制:Spring默认扫描主启动类所在包及其子包,跨包组件需要显式声明 ⚠️ 可能导致的后果: - 异常处理器未被Spring容器扫描到 - 全局异常处理类未被正确注册 - 自定义Result类可能被错误注入 🛠️ 解决方案分步说明: 1. **验证ControllerAdvice配置** ```java // 正确指定控制器所在包(注意实际包路径) @ControllerAdvice(basePackages = "com.example.springboot.controller") public class GlobalExceptionHandler { // 异常处理方法... } ``` 2. **检查包结构合理性** 推荐结构: ``` src/main/java ├── com.example.springboot // 主包 │ ├── controller // 控制器层 │ ├── service // 服务层 │ ├── common // 通用类(建议) │ │ └── Result.java // 统一响应体 └── org.example.springboot // 冲突包(建议重构) ``` 3. **调整Result类位置(推荐)** ```java // 将Result类迁移到项目主包下 package com.example.springboot.common; public class Result<T> { // 响应体实现... } ``` 4. **配置显式组件扫描(可选)** ```java @SpringBootApplication @ComponentScan({ "com.example.springboot.controller", "com.example.springboot.common" }) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 5. **验证异常处理器生效** ```java // 在控制器中制造测试异常 @RestController @RequestMapping("/test") public class TestController { @GetMapping("/error") public Result testError() { throw new RuntimeException("测试异常"); } } ``` 📝 排查清单: 1. 检查启动日志中是否出现全局异常处理器的注册信息 2. 确认`GlobalExceptionHandler`类是否被Spring管理(查看`/actuator/beans`端点) 3. 验证包名是否严格匹配(注意大小写敏感) 4. 检查是否存在多个`@ComponentScan`注解冲突 💡 替代方案: 如果Result类不可修改包路径,可尝试: ```java // 使用全限定名指定扫描包 @ControllerAdvice( basePackages = { "com.example.springboot.controller", "org.example.springboot.common" } ) ``` 建议优先保持项目包结构的统一性,将通用组件放在主包下的common子包中,可以避免此类包路径冲突问题。如果使用第三方Result类,建议通过maven/gradle依赖方式引入而不是直接复制源码。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值