java项目自定义异常处理
本文记录java项目中如何实现异常处理,由于刚入坑java,不知道是不是这样处理的,先总结记录一下。
场景:新增一个商品,新增时可能会出现异常,将自定义异常信息返回给前端,只简单的模拟几个字段。
实体类Item
@Data
public class Item {
private int id;
private String name;
private Long price;
}
service
@Service
public class ItemService {
Item backItem = new Item();
backItem.setId(null);
backItem.setName(item.getName());
backItem.setPrice(item.getPrice());
return backItem;
}
controller
@RestController
@RequestMapping("item")
public class ItemController {
@Autowired
private ItemService itemService;
@PostMapping
public ResponseEntity<Item> saveItem(Item item){
// 价格校验
if(item.getPrice() == null){
// 抛出异常
throw new RuntimeException("价格不能为空");
}
Item backItem = itemService.saveItem(item);
return ResponseEntity.status(HttpStatus.CREATED).body(backItem)
}
}
// ResponseEntity<Item> 返回的是entity,泛型传的是返回的内容
// ResponseEntity.status().body()
// .status() 设置http状态码
// .body() 设置返回的内容
当价格校验异常时,throw new RuntimeException(),前端会接收到如下结果,500服务器异常,显然不太对,所以需要优化
{
"timestamp": "2023-06-30T01:14:47.393+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "价格不能为空",
"path": "/item"
}
使用自定义异常处理MyException,继承RuntimeException
public class MyException extends RuntimeException{
private ExceptionEnum exceptionEnum;
public MyException() {
}
public MyException(ExceptionEnum exceptionEnum) {
this.exceptionEnum = exceptionEnum;
}
public ExceptionEnum getExceptionEnum() {
return exceptionEnum;
}
}
定义一个枚举类,定义报错的枚举信息
@Getter // 只需要get
@NoArgsConstructor
@AllArgsConstructor
public enum ExceptionEnum {
PRICE_CANNOT_BE_NULL(400,"价格不能为空!"),
PAGE_NOT_FOUND(404,"找不到页面啦");
private int code;
private String msg;
}
修改ItemController
// 价格校验
if(item.getPrice() == null){
// 抛出自定义的异常,传入枚举对象
throw new MyException(ExceptionEnum.PRICE_CANNOT_BE_NULL);;
}
最后需要定义一个异常处理拦截器,拦截所有的异常,将自定义信息返回给前端
@ControllerAdvice // 默认情况下拦截所有的controller,处理异常
public class ExceptionHandler {
// 拦截自定义异常
@ExceptionHandler(MyException.class)
public ResponseEntity<ExceptionResult> handleException(Throwable e){
ExceptionEnum em = e.getExceptionEnum();
return ResponseEntity.status(em.getCode()).body(new ExceptionResult(em));
}
// 特别注意: ItemApplication启动类需要放在ExceptionHandler类所在的包外面,否则会拦截不到,不注意这个bug会找很久
}
ResponseEntity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ExceptionResult {
private Integer code;
private String msg;
}
启动项目,不输入价格访问,返回错误的提示结果;
{
"code": 400,
"msg": "价格不能为空!"
}
完结撒花!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话