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返回的是自定义的结果对象,需要定义一个异常结果封装类ExceptionResult

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ExceptionResult {
    private Integer code;
    private String msg;
}

启动项目,不输入价格访问,返回错误的提示结果;

{
  "code": 400,
  "msg": "价格不能为空!"
}

完结撒花!

posted @   Meer_zyh  阅读(147)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示