自定义通用异常处理
生产级别的通用异常处理
所有的异常都抛出,统一在表现层处理,其余直接抛出就好。
spring定义的错误响应方式如图所示。
使用Java提供的异常类抛出的时候只可以传递string,所以需要自定义一个异常类,继承RuntimeException,抛出的时候同时包含信息和状态码
新建通用异常处理类
相当于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();
}
}
注意
- 写代码报了一个小时错吗,老是让我定义一个service,我都懵逼了。。。居然是启动类的类名和service的类名一样了
- 注意启动类的位置决定了可以扫描的包的位置。要放在com.deltaqin里面,不要再往里面放,不然导入common的时候扫不到com.deltaqin.common里面的内容
posted on 2025-10-14 23:53 chuchengzhi 阅读(4) 评论(0) 收藏 举报