在开发过程中,对于错误的参数等各种情况,需要抛出异常,然后由上层进行捕获,最终返回
文章目录
1. 编写自定义异常类
从RuntimeException中继承
@Data
public class MyException extends RuntimeException {
private int code;
private String msg;
public MyException(int code, String msg) {
super(msg);
this.code = code;
this.msg = msg;
}
}
2. 定义异常信息枚举接口
public interface ServiceResponse {
// 获取响应code
int getCode();
// 获取响应消息
String getMsg();
}
3. 异常信息接口实现
public enum CommonResponse implements ServiceResponse {
// 操作成功
IS_SUCCESS(10000, "操作成功"),
// 操作失败
IS_ERROR(-10000, "操作失败"),
ILLEGAL_REQUEST(-10001, "非法请求"),
OVER_FLOW_LIMIT(-10002, "访问超限"),
IS_NOT_PRIV(-10003, "权限不足"),
PARAM_ERROR(-10004, "参数错误"),
REPEAT_REQUEST(-10005, "操作过于频繁"),
LOGIN_TIME_OUT(-10006, "登录超时"),
// HttpStatus 相关
BAD_REQUEST(400, "错误的请求"),
UNAUTHORIZED(401, "未经授权"),
FORBIDDEN(403, "被禁止的"),
METHOD_NOT_ALLOWED(405, "不允许的方法"),
UNSUPPORTED_MEDIA_TYPE(415, "不支持的媒体类型"),
INTERNAL_SERVER_ERROR(500, "服务器异常"),
INTERNAL_SERVICE_UNAVAILABLE(503, "服务暂不可用,可能原因为过载或宕机");;
@Getter
private int code;
@Getter
private String msg;
CommonResponse(int code, String msg) {
this.code = code;
this.msg = msg;
}
}
4. 在service层,出现业务异常,则抛出异常
if (check(mobile)) {
log.error("电话号码格式错误: {}", mobile);
throw new MyException(CommonResponse.PARAM_ERROR);
}
5. 在controller层捕获异常(不用)
@PostMapping(value = "/get-user-info")
public RespBody getUserInfo(@RequestBody inputParam param) {
try {
UserInfoResponse userInfoResponse = userService.getUserInfo(param);
return RespBody.succeed(userInfoResponse);
} catch (MyException e1) {
return RespBody.failed(e1.getCode(), e1.getMsg());
} catch (Exception e2) {
log.error("未知异常: {}, {}", e2.getMessage(), e2.getStackTrace());
return RespBody.failed();
}
}
6. 编写全局异常处理类
package com.sam.demo.controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
@ControllerAdvice
public class MyControllerAdvice {
/**
* 全局异常捕捉处理
*/
@ExceptionHandler(value = Exception.class)
public RespBody errorHandler(Exception e) {
log.errer("未知异常:{},{}",e.getMessage(),e.getStackTrace());
return RespBody.failed(CommonResponse.INTERNAL_SERVER_ERROR);
}
/**
* 自定义异常捕获 MyException.class
*/
@ResponseBody
@ExceptionHandler(value = MyException.class)
public RespBody myErrorHandler(MyException ex) {
log.error("业务异常: {}", e.getStackTrace());
return RespBody.failed(e.getCode(), e.getMsg());
}
}
7. controller层优化
@PostMapping(value = "/get-user-info")
public RespBody getUserInfo(@RequestBody inputParam param) {
UserInfoResponse userInfoResponse = userService.getUserInfo(param);
return RespBody.succeed(userInfoResponse);
}
问题1:在微服务调用过程中,serviceA调用serviceB,为了保证服务内部的安全性,serviceB不能够将所有的异常全部传递给前端,但有些又需要向前端说明。
答:可以在serviceA获得servieB的返回信息后,做出判断,只有servicB中满足添加的错误返回才能够返回给前端