RESTful 异常统一管理

本文介绍如何为 RESTful API 设计统一的响应格式,包括定义返回对象、异常处理及工具类封装等,确保 API 响应的一致性和易读性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们采用RESTful API 时,为了让接口看起来更清晰,更优雅,我们需要对一些特殊情况进行一些处理。

1.统一返回格式

有时由于,返回的数据不一样,造成返回json数据的格式不一样,看起来很别扭,例如:

DELETE http://localhost:8080/hero

//什么也没有返回

POST http://localhost:8080/hero

{
    "id": 6,
    "name": "刘备"
}

能不能,一眼就看出来执行有没有成功:例如POST接口我想返回类似这样的数据:

POST http://localhost:8080/hero

//状态码,提示信息,数据
{
  "code": 1,
  "msg": "成功",
  "data": {
    "id": 7,
    "name": "刘备"
  }
}
1.1定义一个统一返回对象
public class Result<T> {

    private Integer code;//错误码

    private String msg;//提示信息

    private T data;//具体的数据内容

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}
1.2 Controller层
@PostMapping(value="/hero")
    public Result<Hero> addHero(@Valid Hero hero , BindingResult bindingResult){
    if(bindingResult.hasErrors()){          
        return ResultUtil.error(0, bindingResult.getFieldError().getDefaultMessage());
    }
    hero.setName(hero.getName());
    heroService.addHero(hero);      
    return ResultUtil.success(hero);
}

在这里我对返回成功或者失败进行了封装,封装成了ResultUtil 工具类

public class ResultUtil {

    public static Result success(Object object){
        Result result = new Result();
        result.setCode(1);
        result.setMsg("成功");
        result.setData(object);
        return result;
    }

    public static Result success(){
        return success(null);
    }

    public static Result error(Integer code , String msg){
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}
1.3 结果测试

现在在对新增方法进行测试发现,已经实现了预期的效果,返回json数据格式如下:

image

2 现在发生了异常将会返回什么

2.1 在Service 抛出异常
public int addHero(Hero hero){
    String name = hero.getName();
    if(name.equals("张飞")){
        throw new HeroException(100, "这个是刘备的三弟");
    } else if(name.equals("关羽")){
        throw new HeroException(101, "这个是刘备的二弟");
    }
    return heroDao.addHero(hero);
}

传递name=”张飞”看看结果

image

发现我们设置的Result类不在起作用,返回的json数据又乱了。现在我们需要对Exception进行捕获处理。

2.2 自定义Exception

在自定义异常时,一定要注意Spring 只回滚RuntimeException 异常,如果继承Exception spring是不回滚的

public class HeroException extends RuntimeException{

    private Integer code;

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

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
}
2.3 捕获异常

对自己抛出的异常进行捕获处理,对系统异常进行提示,并写入日志。

@ControllerAdvice
public class ExceptionHandle {
    private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result handle(Exception e){
        if(e instanceof HeroException){
            HeroException heroException = (HeroException) e;
            return ResultUtil.error(heroException.getCode(), heroException.getMessage());
        } else {
            logger.error("【系统异常】{}",e);
            return ResultUtil.error(-1, "未知错误");
        }       
    }
}
2.4 测试结果

image

现在的效果就是我们所预期的了

参考资料:http://www.imooc.com/video/14341

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CiBa-YAO

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

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

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

打赏作者

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

抵扣说明:

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

余额充值