主要利用 spring-webmvc提供的@ControllerAdvice注解和@ExceptionHandler注解,所以springwebmvc的依赖必不可少。 @ControllerAdvice作用在类上,表明使用该类对controller中抛出的异常进行捕获处理。 @ExceptionHandler作用在方法上,需要指定异常的字节码数组,以便说明该方法是用来处理哪些异常。 下面我们按步骤演示一个完整的异常处理。 注:下面的代码为了方便使用了lombok。
1. 定义ExceptionResult类(VO),因为项目是前后端分离,出现异常后,我们需要将一些必要的异常信息返回给前端展示。一般定义一个状态码,异常的提示信息,时间戳等等,这些字段根据自己的需要添加。
@Data
public class ExceptionResult {
private int status
;
private String message
;
private Long timestamp
;
public ExceptionResult(ExceptionEnums exceptionEnums
) {
this.status
= exceptionEnums
.getCode();
this.message
= exceptionEnums
.getMsg();
this.timestamp
= System
.currentTimeMillis();
}
}
2. 自定义ExceptionEnums枚举类,管理我们项目中自定义的异常信息和状态码。
@Getter
@AllArgsConstructor
public enum ExceptionEnums
{
USERNAME_CANNOT_BE_NULL(400,"用户名不能为空"),
PASSWORD_CANNOT_BE_NULL(401,"密码不能为空");
private final int code
;
private final String msg
;
}
3. 自定义CustomException异常类,有了该异常类,我们就可以在全局异常处理器中捕获他,进行处理。该异常类需要继承RuntimeException而不是Exception。因而该自定义异常可以直接抛出,而不用在controller方法上声明。
@Getter
@AllArgsConstructor
public class LyException extends RuntimeException{
private ExceptionEnums exceptionEnums
;
}
4. 创建全局异常处理器,捕获我们第三步自定义的异常,实现通用的异常处理。
@ControllerAdvice
public class CommonExceptionHandler {
@ExceptionHandler(CustomException
.class)
public ResponseEntity
<ExceptionResult> handleException(CustomException customException
) {
ExceptionEnums exceptionEnums
= customException
.getExceptionEnums();
return ResponseEntity
.status(exceptionEnums
.getCode()).body(new ExceptionResult(exceptionEnums
));
}
}
关于ResponseEntity<T>,使用这个类我们可以设置响应行的status,同时可以序列化不同类型的数据到响应体中。
5. 在controller方法中需要的地方抛出异常。如果Service层出现需要捕获的异常,需要抛到controller。
@Controller("user")
public class UserController {
@Autowired
private UserService userService
;
@RequestMapping("login")
public ResponseEntity
<Item> login(User user
) {
if (StringUtils
.isBlank(user
.getUsername
)) {
throw new CustomException(ExceptionEnums
.USERNAME_CANNOT_BE_NULL
);
}
user
= userService
.login(user
);
return ResponseEntity
.ok(user
);
}
}
6.测试我们的接口,不传username,看一下效果。