Как вернуть пользовательское сообщение об ошибке для неверного значения перечисления в Spring Boot RequestBody?

Моя конечная точка размещения принимает requestBody типа UpdateUserDTO. Свойство роли должно иметь тип roleEnum. Я ищу способ вернуть пользовательское сообщение, если предоставленное свойство роли не является roleEnum.

конечная точка:

@PutMapping("/administrate/{id}")
public UserDTO administrateUser(@PathVariable Long id, @RequestBody UpdateUserByAdminDTO requestBody) {}

ДТО:

@Getter
@Setter
@NoArgsConstructor
public class UpdateUserByAdminDTO {
    private Boolean isBanned;
    private RoleEnum role;
}

Например, если тело запроса задано неправильно:

{
   "isBanned": false,
   "role":"USzdER"
}

Я хочу получить ошибку статуса 400 с сообщением «роль недействительна». Я не уверен, что смогу добиться этого с помощью проверки. В настоящее время я не понимаю, почему я получаю ошибку 403, когда пользователь зарегистрирован и имеет соответствующее разрешение.

Ошибка в журналах: `Я получаю ошибку:

DefaultHandlerExceptionResolver: решено [org.springframework.http.converter.HttpMessageNotReadableException: Ошибка анализа JSON: невозможно десериализовать значение типа com.wcs.mtgbox.auth.domain.dto.RoleEnum из строки «s»: ни один из значения, принятые для класса Enum: [USER, ADMIN]]

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Во-первых, исключение 403 может быть связано с проблемами с правами пользователя. Было бы лучше проверить объект UserDetails и код Spring Security, чтобы определить точную причину.

Вот ссылка на проблему, которую я решил; может быть полезно взглянуть.


Во-вторых, возврат специального сообщения, когда значение не является перечислением, можно реализовать двумя способами.

Первый способ — настроить ExceptionHandler для HttpMessageNotReadableException.

@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException ex) {
    Throwable cause = ex.getCause();
    if (cause instanceof InvalidFormatException invalidFormatException) {
        if (invalidFormatException.getTargetType().isEnum()) {
            return new ResponseEntity<>("role is invalid", HttpStatus.BAD_REQUEST);
        }
    }
    return new ResponseEntity<>("Invalid request body", HttpStatus.BAD_REQUEST);
}

HttpMessageNotReadableException возникает в процессе чтения и сопоставления тела HTTP-запроса в Spring MVC.

InvalidFormatException — это исключение, возникающее при десериализации данных JSON.

Таким образом, вы можете реализовать собственную обработку исключений для случаев, когда указана недопустимая роль.


Второй способ — получить значение в виде строки, проверить его и вызвать исключение, если оно не совпадает.

@Getter
@AllArgsConstructor
public enum RoleEnum {
    MEMBER("MEMBER"),
    ADMIN("ADMIN"),
    MANAGER("MANAGER");
    private final String provider;

    public static RoleEnum translateStringToRole(String role) {
        return switch (role.toLowerCase()) {
            case "member" -> RoleEnum.MEMBER;
            case "admin" -> RoleEnum.ADMIN;
            case "manager" -> RoleEnum.MANAGER;
            default -> throw new RoleEnumException("role is invalid.");
        };
    }
}

Обработка исключений

public class RoleEnumException extends RuntimeException {
    private final String message;

    public RoleEnumException(final String message) {
        this.message = message;
    }
}

@ExceptionHandler({
    RoleEnumException.class
})
public ResponseEntity<ExceptionResponse> handleRoleEnumException(final RoleEnumException e) {
    return ResponseEntity.status(HttpStatus.BAD_REQUEST)
        .body(new ExceptionResponse(e.getMessage()));
}

@Getter
@RequiredArgsConstructor
public class ExceptionResponse {
    private final String message;
}

Думаю эта статья будет вам полезна.

Хорошего дня - Кевин

Спасибо за эти 2 решения. Попробую реализовать второй. Что касается ошибки 403, я не уверен, что это связано с разрешением. Часть «ROLE_» правильно установлена ​​в методе getAuthorities() и работает нормально. Это больше похоже на возврат кода состояния по умолчанию при возникновении ошибки. То же самое происходит со всеми маршрутами.

Ryley38 16.06.2024 18:24

Было бы полезно увидеть код и сообщения, связанные с ошибкой 403 :)

Kevin 16.06.2024 18:34

Как мне использовать TranslateStringToOAuthProvider? Похоже, это не оказывает никакого влияния. Я все еще получаю ту же ошибку. Я отредактировал вопрос с ошибкой из журналов, связанной с ошибкой 403.

Ryley38 16.06.2024 19:57

Не могли бы вы показать мне, как вы использовали метод translateStringToRole? Судя по логам, похоже, что произошло исключение, потому что строка s не найдена в RoleEnum.

Kevin 17.06.2024 02:17

Другие вопросы по теме