Я слышал, что поиск в WeChat для «Java Fish Aberdeen» станет сильнее!
Эта статья включена вJavaStarter, который содержит мою полную серию статей по Java, вы можете прочитать его для изучения или интервью.
(I. Обзор
Обработка исключений — самая важная часть системы.Когда проект становится очень большим, обработка исключений и система ведения журналов позволяют быстро обнаружить проблему. Для пользователей или вызывающих интерфейс элегантная обработка исключений позволяет вызывающему абоненту быстро узнать, в чем заключается проблема. Эта статья покажет вам, как изящно обрабатывать исключения.
(2) Используйте общее тело возврата
Мы хотим, чтобы все ошибки возвращались клиенту в виде Json, поэтому удалите общее тело возврата, написанное в прошлый раз, и создайте новый класс CommonResult для записи тела возврата.
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult {
private int code;
private String message;
private Object data;
}
Создайте новый класс перечисления ResponseCode для интеграции кода и сообщения.
public enum ResponseCode {
// 系统模块
SUCCESS(0, "操作成功"),
ERROR(1, "操作失败"),
SERVER_ERROR(500, "服务器异常"),
// 通用模块 1xxxx
ILLEGAL_ARGUMENT(10000, "参数不合法"),
REPETITIVE_OPERATION(10001, "请勿重复操作"),
ACCESS_LIMIT(10002, "请求太频繁, 请稍后再试"),
MAIL_SEND_SUCCESS(10003, "邮件发送成功"),
// 用户模块 2xxxx
NEED_LOGIN(20001, "登录失效"),
USERNAME_OR_PASSWORD_EMPTY(20002, "用户名或密码不能为空"),
USERNAME_OR_PASSWORD_WRONG(20003, "用户名或密码错误"),
USER_NOT_EXISTS(20004, "用户不存在"),
WRONG_PASSWORD(20005, "密码错误"),
;
ResponseCode(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
private Integer code;
private String msg;
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;
}
}
(3) Пользовательское исключение времени выполнения
Чтобы настроить класс исключений времени выполнения, конструктор может передать параметры исключения.
public class MyException extends RuntimeException{
private String msg;
public MyException(String msg) {
super(msg);
}
}
(4) Напишите унифицированный класс обработки исключений
Класс обработки исключений является ядром всей обработки исключений SpringBoot предоставляет аннотацию ControllerAdvice для перехвата исключений и использует аннотацию RestControllerAdvice для обеспечения возврата в формате Json.
Если перехваченное исключение принадлежит MyException, результат ошибки будет возвращен в формате Json.
@RestControllerAdvice
public class ExceptionController {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = Exception.class)
public CommonResult exceptionHandler(Exception e){
//如果抛出的异常属于自定义异常,就以JSON格式返回
if (e instanceof MyException){
return new CommonResult(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getMsg(),"自定义的错误为:"+e.getMessage());
}
//如果都不是就打印出异常的信息
return new CommonResult(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getMsg(),"错误的信息为:"+e.getMessage());
}
}
(5) Тест
Чтобы увидеть первоначальный эффект, здесь вручную создается исключение для тестирования, создания нового IndexController и создания исключения вручную.
@RestController
public class IndexController {
@RequestMapping(value = "/index",method = RequestMethod.GET)
public String index(){
throw new MyException("测试");
}
}
Посмотреть результат звонка:
(6) Проверка классов сущностей
Есть такой сценарий.При входе и регистрации имя пользователя и пароль имеют ограничение по длине, а номер мобильного телефона имеет ограничение по формату.Если требования не соблюдены, регистрация не может быть выполнена. Внешний интерфейс этой функции может быть ограничен, но для внутреннего интерфейса он также должен быть ограничен, если внешний интерфейс не ограничен.
Импортируйте две зависимости проверки:
<!--校验-->
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
Напишите класс сущности и добавьте параметры проверки пакета проверки к каждому атрибуту.
@Data
public class Register {
@Length(max = 20,min = 4,message = "用户名长度需要在4到20个字符之间")
@NotBlank(message = "用户名不能为空")
private String username;
@NotBlank(message = "手机号不能为空")
@Pattern(regexp = "^1[3|4|5|8][0-9]\\d{8}$",message = "电话号码格式不正确")
private String phone;
@Length(max = 20,min = 4,message = "密码长度需要在4到20个字符之间")
@NotBlank(message = "密码不能为空")
private String password;
}
Добавляем аннотацию @Valid к методу, который нужно использовать для проверки, например, я хочу проверить в этом пост-запросе.
@PostMapping("/register")
public CommonResult register(@Valid @RequestBody Register register){
//一连串注册的业务
userService.registerUser(register);
return new CommonResult(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMsg(),"");
}
@Valid сообщит об исключении, что параметр является недопустимым, когда проверка не пройдена, или перехватит исключение в унифицированном классе обработки исключений.Если это MethodArgumentNotValidException, соответствующие данные сообщения будут удалены.
@RestControllerAdvice
public class ExceptionController {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = Exception.class)
public CommonResult exceptionHandler(Exception e){
//如果属于参数校验异常,就抛出校验的错误
if (e instanceof MethodArgumentNotValidException){
MethodArgumentNotValidException methodArgumentNotValidException= (MethodArgumentNotValidException) e;
return new CommonResult(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getMsg(),
"校验错误:"+methodArgumentNotValidException.getBindingResult().getFieldError().getDefaultMessage());
}//如果是自定义的异常,就给出具体的异常原因
else if (e instanceof MyException){
return new CommonResult(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getMsg(),"自定义的错误为:"+e.getMessage());
}
//如果都不是就打印出异常的信息
return new CommonResult(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getMsg(),"错误的信息为:"+e.getMessage());
}
}
(7) Тестовая проверка
Далее вы можете протестировать функцию проверки и получить к ней доступ через почтальона.
Если входные параметры не соответствуют предыдущим настройкам, будет выдано конкретное сообщение об ошибке. Вместо того, чтобы выдавать неприемлемую ошибку:
(8) Резюме
Последнее, о чем многие думают при написании кода, — это обработка исключений: достаточно просто реализовать требования, так появится много непредсказуемых багов. Ну, вот и все для этой статьи, увидимся в следующий раз.