Пример, который я пишу, находится в весенней загрузке с использованием org.springframework.web.bind.annotation.ExceptionHandler annotation
Это прекрасно работает для меня
Предположим, я сделал Get запрос к https://example.com/user-api/users/a535c777-c906-45e2-b1c3-940965a507f2q, тогда наш API проверяет, существует ли этот идентификатор пользователя или нет, и если нет, выдает правильное сообщение, в том числе о том, какие параметры недопустимы или имеет ошибки.
Ответ ex 1:
{
"apierror": {
"dateTime": "2020-02-13T06:24:14.985",
"timestamp": "1581603854985",
"status": 404,
"error": "Not Found",
"message": "User not found",
"debugMessage": null,
"errors": [
{
"field": "userId",
"rejectedValue": "a535c777-c906-45e2-b1c3-940965a507f2q",
"message": "User not found with userId:a535c777-c906-45e2-b1c3-940965a507f2q"
}
]
}
}
Ответ ex2:
{
"apierror": {
"dateTime": "2020-02-13T06:43:23.377",
"timestamp": "1581605003377",
"status": 400,
"error": "Bad Request",
"message": "Validation error",
"debugMessage": null,
"errors": [
{
"field": "userName",
"rejectedValue": "Ash",
"message": "Username should have at least 6 characters"
},
{
"field": "userName",
"rejectedValue": "Ash",
"message": "Invalid username"
},
{
"field": "password",
"rejectedValue": "shutosh@",
"message": "Invalid password"
}
]
}
}
Исключительное сообщение "Пользователь не найден с userId: a535c777-c906-45e2-b1c3-940965a507f2q" согласно api. Ниже приведен пример использования.
Контроллер:
@PrivilegeMapper.HasPlaceUserPrivilege
@GetMapping(value = "/{userId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<?> getUserProfile(@NotBlank @PathVariable String userId) {
return myService.buildUserProfile(userId);
}
Служба:
@Override
public ResponseEntity<?> buildUserProfile(final String userId) {
ApiUser apiUser = userRepository.findById(userId)
.orElseThrow(() -> new ApiUserNotFoundException("userId",userId));
return ResponseEntity.ok(sirfUser);
}
Классы исключений:
@Getter
@Setter
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ApiUserNotFoundException extends NotFoundException {
public ApiUserNotFoundException(String msg, Throwable t) {
super(msg, t);
}
public ApiUserNotFoundException(String msg) {
super(msg);
}
public ApiUserNotFoundException(String key, String value) {
super(key, value);
}
public ApiUserNotFoundException(String key, String value, List<Error> errors) {
super(key, value, errors);
}
}
@Getter
@Setter
@ResponseStatus(code = HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {
private String key;
private String value;
private List<Error> errors;
public NotFoundException(String msg, Throwable t) {
super(msg, t);
}
public NotFoundException(String msg) {
super(msg);
}
public NotFoundException(String key, String value) {
this.key = key;
this.value = value;
}
public NotFoundException(String key, String value, List<Error> errors) {
this.key = key;
this.value = value;
this.errors = errors;
}
}
Обработчик исключений:
@ExceptionHandler(ApiUserNotFoundException.class)
protected ResponseEntity<Object> handleSirfUserNotFound(ApiUserNotFoundException ex) {
log.error(String.format("User not found with %s:%s",ex.getKey(),ex.getValue()));
ApiError apiError = new ApiError(NOT_FOUND);
apiError.setMessage("User not found");
List<Error> errors = new ArrayList<>();
Error error = new ApiValidationError(SirfUser.class.getSimpleName());
((ApiValidationError) error).setMessage(String.format("User not found with %s:%s",ex.getKey(),ex.getValue()));
((ApiValidationError) error).setField(ex.getKey());
((ApiValidationError) error).setRejectedValue(ex.getValue());
errors.add(error);
apiError.setErrors(errors);
return buildResponseEntity(apiError);
}
И это все. Вы сделали. такой тип обработки всегда полезен как для ведения журнала, так и для перспективы пользовательского интерфейса.