自定义通用异常处理

生产级别的通用异常处理

所有的异常都抛出,统一在表现层处理,其余直接抛出就好。

1580218612292-5dac3d0a-8202-482f-8454-1f16f7cd15ee.png

spring定义的错误响应方式如图所示。

使用Java提供的异常类抛出的时候只可以传递string,所以需要自定义一个异常类,继承RuntimeException,抛出的时候同时包含信息和状态码

1580257288867-682fa387-dcbd-44b5-a2bc-e2618f3b59a1.png

新建通用异常处理类

相当于aop里面的通知,起到拦截的作用,要做到通用,状态码不可以写死,这里的设计不对,后面会改进

src/main/java/com/deltaqin/common/advice/CommonExceptionHandler.java

package com.deltaqin.common.advice;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

// aop拦截,相当于aop的通知
@ControllerAdvice
// 此拦截是针对controller的,默认拦截有controller注解的类
public class CommonExceptionHandler {

//    只是拦截处理特定的异常
    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> handleException(RuntimeException e){
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());

    }
}

common模块引入springMVC的依赖

需要controller注解

不需要启动器,只需要spring-webmvc里面的MVC

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
</dependency>

自定义异常类

抛出的时候只抛出自定义的异常

src/main/java/com/deltaqin/common/exception/mallException.java

package com.deltaqin.common.exception;

import com.deltaqin.common.enums.ExceptionEnums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class mallException extends RuntimeException {

    private ExceptionEnums exceptionEnums;
}

异常枚举类

具有固定实例个数的类,不像正常类无限制,类的对象是提前创建好的

src/main/java/com/deltaqin/common/enums/ExceptionEnums.java

package com.deltaqin.common.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum ExceptionEnums {

    PRICE_CANNOT_BE_NALL(400, "价格不能为空"),
    PRICE_CANNOT_BE(400, "价格不能为空")
    ;
    private int code;
    private String msg;
}

item-service模块引入自定义通用异常的依赖

<dependency>
  <groupId>com.deltaqin.common</groupId>
  <artifactId>common</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</dependency>

修改item-service抛出的异常

抛出异常的时候,不仅仅是传递信息还要传递状态码

src/main/java/com/deltaqin/item/web/ItemController.java

package com.deltaqin.item.web;

import com.deltaqin.common.enums.ExceptionEnums;
import com.deltaqin.common.exception.mallException;
import com.deltaqin.item.service.ItemService;
import com.deltaqin.item.pojo.Item;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("item")
public class ItemController {

    @Autowired
    private ItemService itemService;

    @PostMapping
    public ResponseEntity<Item> saveItem(Item item){
        if (item.getPrice() == null) {
//            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
//            throw new RuntimeException("价格不能为空");
            throw new mallException(ExceptionEnums.PRICE_CANNOT_BE_NALL);
        }
        item = itemService.saveItem(item);
        return ResponseEntity.status(HttpStatus.CREATED).body(item);
    }
}

修改通用异常处理类

src/main/java/com/deltaqin/common/advice/CommonExceptionHandler.java

package com.deltaqin.common.advice;

import com.deltaqin.common.exception.mallException;
import com.deltaqin.common.vo.ExceptionResult;
//import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

// aop拦截,相当于aop的通知
@ControllerAdvice
// 此拦截是针对controller的,默认拦截有controller注解的类
public class CommonExceptionHandler {

//    只是拦截处理特定的异常
//    @ExceptionHandler(mallException.class)
//    public ResponseEntity<String> handleException(mallException e){
//        ExceptionEnums em = e.getExceptionEnums();
//        return ResponseEntity.status(em.getCode()).body(em.getMsg());
//
//    }
    @ExceptionHandler(mallException.class)
    public ResponseEntity<ExceptionResult> handleException(mallException e){
        return ResponseEntity.status(e.getExceptionEnums().getCode())
                .body(new ExceptionResult(e.getExceptionEnums()));

    }
}

自定义异常结果集

src/main/java/com/deltaqin/common/vo/ExceptionResult.java

package com.deltaqin.common.vo;

import com.deltaqin.common.enums.ExceptionEnums;
import lombok.Data;

@Data
public class ExceptionResult {
    private int status;
    private String message;
    private Long timestamp;

    public ExceptionResult(ExceptionEnums em){
        this.status = em.getCode();
        this.message = em.getMsg();
        this.timestamp = System.currentTimeMillis();
    }
}

1580257315394-7d210355-bc47-42cf-83c4-1c6cbade5ca2.png

注意

  • 写代码报了一个小时错吗,老是让我定义一个service,我都懵逼了。。。居然是启动类的类名和service的类名一样了
  • 注意启动类的位置决定了可以扫描的包的位置。要放在com.deltaqin里面,不要再往里面放,不然导入common的时候扫不到com.deltaqin.common里面的内容

posted on 2025-10-14 23:53  chuchengzhi  阅读(4)  评论(0)    收藏  举报

导航

杭州技术博主,专注分享云计算领域实战经验、技术教程与行业洞察, 打造聚焦云计算技术的垂直博客,助力开发者快速掌握云服务核心能力。

褚成志 云计算 技术博客