RESTful API 极懒笔记之二 [响应篇3--异常返回]

1. RESTful 异常处理设计

具体设计思路可以参考 响应篇1–理论
正常返回可以参考 响应篇2–正常返回

// 异常响应
// 响应头
HTTP/1.1 400 Bad Request
Content-Type: application/json

// 响应体
{
	"code": 1000,// 业务状态码
	"msg": "验证失败",// 业务详细信息
	"errors": [// 多个错误信息(如验证)
		{"code": 2000, "msg": "错误信息"},
		{"code": 2001, "msg": "错误信息"}
	]
}

2. 核心类

2.1. RestfulResult (统一返回格式)

/**
 * @Author geek_lazy
 */
// 篇幅原因,使用 @Data 省略 getter 和 setter 方法
@Data
public class RestfulResult<T> {
	private T data;// 响应数据
	private int code;// 业务状态码
	private String msg;// 业务详细信息
	private Page paging;// 分页信息
	private String links;// 相关链接
	private Object errors;// 多个错误信息(如验证)
    
	public RestfulResult() {
		// 无参构造的时候给一个成功的默认值
		this.code = ResultCode.SUCCESS.code();
		this.msg = ResultCode.SUCCESS.msg();
		this.data = data;
	}
    
	// 这里我只写一个构造方法,根据情况可以自己定义
	public RestfulResult(ResultCode code, T data) {
		this.code = code.code();
		this.msg = code.msg();
		this.data = data;
	}
}

2.2. ResultCode (业务状态码)

/**
 * @Author geek_lazy
 */
@Data
public enum ResultCode {
	UNKNOWN_ERROR(0, "未知错误"),// 默认错误
	SUCCESS(1, "成功"),
	PARAM_IS_INVALID(10001, "参数无效"),
	USER_NOT_LOGGED_IN(20001, "用户未登录"),
    // ...
    ;
	private int code;// 业务状态码
	private String msg;// 业务详细信息
	private HttpStatus httpStatus;// 业务对应 HTTP 状态码
    
	ResultCode(int code, String msg, HttpStatus httpStatus) {
		this.code = code;
		this.msg = msg;
		this.httpStatus = httpStatus;
	}
}

2.3. BizException (业务异常)

/**
 * @Author geek_lazy
 */
public class BizException extends RuntimeException{
	private int bizCode;// 业务状态码
	private HttpStatus httpStatus;// HTTP 状态码

	public BizException(ResultCode resultCode){
		super(resultCode.msg());
		this.bizCode = resultCode.code();
		this.httpStatus = resultCode.httpStatus();
	}

	public BizException(int code, String message) {
		super(message);
		this.bizCode = code;
		this.httpStatus = HttpStatus.BAD_REQUEST;
	}
}

2.4. GlobalExceptionHandler (全局异常处理)

这里使用的是 Spring 的 @ControllerAdvice@ExceptionHandler 来进行全局异常处理

/**
 * @Author geek_lazy
 */
@RestController
@ControllerAdvice
public class GlobalExceptionHandler {
	private static final String DEFAULT_MESSAGE = "No message available";// 没有错误信息时默认返回
	/**
	 * 处理业务异常
	 * @param e
	 * @return
	 */
	@ExceptionHandler(value = BizException.class)
	public Object bizExceptionHandler(BizException e) {
		RestfulResult restfulResult = new RestfulResult();
		restfulResult.setCode(e.getBizCode());
		restfulResult.setMsg(e.getMessage());
		return ResponseEntity.status(e.getHttpStatus()).body(restfulResult);
	}

	/**
	 * 默认异常处理
	 * @param e
	 * @return
	 */
	@ExceptionHandler(value = Exception.class)
	public Object defaultExceptionHandler(Exception e) {
		RestfulResult restfulResult = new RestfulResult();
		restfulResult.setMsg(e.getMessage());
		return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(restfulResult);
	}
}

3. 实践

完成上面的几个关键类后, 异常处理就基本完成了, 一般controller抛出异常大致如下:

controller

/**
 * @Author geek_lazy
 */
@RestController
@RequestMapping("/statistics")
public class StatisticController {
	// service层我就不写了,理解为上
	@Autowired
	private IStatisticService iss;
	/**
	 * 获取一个Statistic对象
	 */
	@GetMapping("{statisticId}")
	public Statistic getStatisticById(@PathVariable("statisticId") String statisticId) {
        if (statisticId == null) {
			throw new BizException(ResultCode.PARAM_IS_INVALID);
		} 
		return iss.getStatisticById(statisticId);
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值