SpringMVC(四、统一异常处理

导学 ==> 项目异常统一处理:

  • 异常处理器

  • 自定义异常

  • 自定义异常编码

一、异常处理器 

平时开发可能出现的异常及其原因

  • 框架内抛出异常:因使用规范不一致导致
  • 数据层(Repository)抛出异常:因外部服务器故障导致
  • 业务层(Service)排除异常:因业务逻辑书写错误导致
  • 表现层(Controller)抛出异常:因数据手机,效验规则导致
  • 工具类(Utils)抛出异常:因工具类书写不严谨、不健壮导致

各个层级均有可能抛出异常,如果我们每层都处理异常,代码过于冗余

我们可以将各层的异常统统抛出,到表现层(Controller)对这些异常进行统一的处理 

那我们如何在表现层处理这些异常呢?每个方法都去单独书写异常处理方案?这样不仅书写量巨大且耗时,又不利于维护。我们可以采用AOP思想 ,SpringMvc已经为我们造好了轮子

1,在Controller层下新建ProjectException类

@RestControllerAdvice
public class ProjectException {

    @ExceptionHandler(Exception.class)
    public void executeException(Exception e){
        System.out.println("异常被我处理啦");
    }
    
}

2,在SpringMvc配置类下扫描当前类

package com.brrbaii.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@ComponentScan("com.brrbaii.controller")
//Json数据转对象
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
    //过滤静态资源,防止被SpringMvc拦截
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
}

3,测试

我们在Service层手动制造一个异常 

访问这个方法,观察控制台输出结果

4,设置异常处理统一格式 

新建Result类

package com.brrbaii.controller;


import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class Result<T> {
    //数据
    T data;
    //消息
    String msg;
    //状态码
    Integer code;

    public Result(Integer code,T data, String msg) {
        this.data = data;
        this.msg = msg;
        this.code = code;
    }

    public Result(Integer code,T data) {
        this.data = data;
        this.code = code;
    }
}

修改ProjectException类,使其方法返回Result


前端收到的结果: 

二、自定义异常 

项目遇到的异常分类:

  • 业务异常(BusinessException)
    • 规范的用户行为产生的异常
    • 不规范的用户行为操作产生的异常
  • 系统异常(SystemException)
    • 项目运行过程中可预计但无法避免的异常
  • 其他异常(Exception)
    • 编程人员未预期到的异常 

上述异常处理方案: 

  • 业务异常(BusinessException)
    • 发送对应的消息传递给客户,题型规范操作
  • 系统异常(SystemException)
    • 发送固定消息传递给用户,安抚用户
    • 发送特定的消息给运维人员,提醒维护
    • 记录日志
  • 其他异常(Exception)
    • 发送固定消息传递给用户,安抚用户
    • 发送特定的消息给编程人员,提醒维护(纳入后续预期范围)
    • 记录日志

我们对可能出现的种种异常集中为上面三类异常,分别创建对应的类

1,BusinessException

package com.brrbaii.controller.exception;

import lombok.Data;

@Data
public class BusinessException extends RuntimeException{

    //自定义异常编码
    private Integer code;


    public BusinessException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public BusinessException(Integer code, String message, Throwable cause ) {
        super(message, cause);
        this.code = code;
    }
}

2,SystemException

package com.brrbaii.controller.exception;

import lombok.Data;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Data
public class SystemException extends RuntimeException{

    private Integer code;


    public SystemException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public SystemException(Integer code, String message, Throwable cause ) {
        super(message, cause);
        this.code = code;
    }

}

3,修改我们的异常处理器(ProjectException),然它处理上述两异常异常 

package com.brrbaii.controller.exception;

import com.brrbaii.controller.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class ProjectException {

    //处理系统异常
    @ExceptionHandler(SystemException.class)
    public Result executeSystemException(SystemException e){
//        1,发送固定消息传递给用户,安抚用户
//        2,发送特定的消息给运维人员,提醒维护
//        3,记录日志
//        4,返回异常消息
        return new Result(e.getCode(),null,e.getMessage());
    }

    //处理业务异常
    @ExceptionHandler(BusinessException.class)
    public Result executeBusinessException(BusinessException e){
//        1,发送固定消息传递给用户,安抚用户
//        2,发送特定的消息给开发人员,提醒维护(后续纳入可预期异常范畴)
//        3,记录日志
//        4,返回异常消息
        return new Result(e.getCode(),null,e.getMessage());
    }

}

 接下来我们对可能出现异常的代码进行包装,将异常转换为我们上述自定义的异常

三、自定义异常编码

 对于返回的异常编码,我们不想固定写死

可以创建一个Code类,对异常编码进行统一

package com.brrbaii.controller;

public class Code {

    //系统异常
    public static final Integer SYSTEM_ERR = 50001;
    //业务异常
    public static final Integer BUSINESS_ERR = 50006;

    //请求成功
    public static final Integer SAVE_OK = 20011;
    public static final Integer DELETE_OK = 20021;
    public static final Integer UPDATE_OK = 20031;
    public static final Integer SELECT_OK = 20041;

    //请求失败
    public static final Integer SAVE_ERR = 20010;
    public static final Integer DELETE_ERR = 20020;
    public static final Integer UPDATE_ERR = 20030;
    public static final Integer SELECT_ERR = 20040;
}

 修改方法返回的异常编码

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在 Spring MVC 中,我们可以通过实现一个异常处理器来统一处理控制器抛出的异常。具体步骤如下: 1. 实现一个异常处理器类,并添加 @ControllerAdvice 注解。 2. 在异常处理器类中定义处理不同类型异常的方法,并使用 @ExceptionHandler 注解标记。 3. 在方法中编写异常处理逻辑,例如将异常信息记录到日志中、返回错误信息等。 4. 如果需要返回 JSON 格式的错误信息,可以使用 @ResponseBody 注解。 以下是一个简单的示例: ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) @ResponseBody public Map<String, Object> handleException(Exception e) { Map<String, Object> errorMap = new HashMap<>(); errorMap.put("code", "500"); errorMap.put("message", e.getMessage()); return errorMap; } @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseBody public Map<String, Object> handleValidationException(MethodArgumentNotValidException e) { Map<String, Object> errorMap = new HashMap<>(); errorMap.put("code", "400"); errorMap.put("message", "参数校验失败"); List<String> errors = e.getBindingResult() .getFieldErrors() .stream() .map(FieldError::getDefaultMessage) .collect(Collectors.toList()); errorMap.put("errors", errors); return errorMap; } } ``` 在上述示例中,我们定义了两个处理异常的方法:handleException 和 handleValidationException。handleException 方法处理所有未被其他方法处理异常,返回一个包含错误码和错误信息的 Map 对象;handleValidationException 方法处理参数校验失败的异常,并将校验失败的所有错误信息返回。 最后,需要注意的是,如果同时存在多个异常处理方法,Spring MVC 会按照异常类型匹配最合适的处理方法。如果没有找到合适的处理方法,则会将异常抛给 Servlet 容器进行处理

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白日日白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值