Перехват исключительной ситуации при преобразовании данных HTTP-запроса в enum - PullRequest
0 голосов
/ 07 июня 2018

У меня проблема при десериализации значения HTTP-запроса в enum с пользовательской реализацией десериализатора com.fasterxml.jackson.databind.JsonDeserializer:

public class EnvelopeColorJsonDeserializer extends JsonDeserializer<EnvelopeColor> {

    @Override
    public EnvelopeColor deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String val = p.getValueAsString();
        return EnvelopeColor.fromCode(val);
    }
}

Вот как я конвертирую значение в enum:

public static EnvelopeColor fromCode(String code) {
    Assert.notNull(code, "code");
    for (EnvelopeColor type : values()) {
        if (code.equals(type.code)) {
            return type;
        }
    }
    throw new RuntimeException("Not supported color: " + code);
}

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

@PostMapping("/")
    public @ResponseBody
    ResponseEntity add(@RequestBody EnvelopeDto envelope) {
// some stuff goes here...
}

Вопрос

Есть ли способ как а) проверить, является ли значение HTTP-запроса допустимым значением константы перечисления до процесс десериализации или б) как отловить исключение в @ControllerAdvice обработчик исключений?(Я бы хотел не создавать пользовательские исключения в методе fromCode()).

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

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

@ExceptionHandler(org.springframework.http.converter.HttpMessageNotReadableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
protected @ResponseBody handleIncorrectData(HttpMessageNotReadableException ex,
            HttpServletRequest request, HttpServletResponse response){

....

}

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

public class CustomEnumConverter extends EnumConverter {

    @Override
    public Object unmarshal(HierarchicalStreamReader reader,
            UnmarshallingContext context) {
        try {
            return super.unmarshal(reader, context);
        } catch (IllegalArgumentException e) {
            String inputValue = reader.getValue();
            Class contextType = context.getRequiredType();
            StringBuilder sb = new StringBuilder();
            Object[] enumConstants = contextType.getEnumConstants();
            for (Object o : enumConstants) {
                sb.append(o + ",");
            }
            if (sb.length() > 0)
                sb.deleteCharAt(sb.length() - 1);
            throw new InvalidArgumentException(ErrorCode.INVALID_ARGUMENT, inputValue,
                    reader.getNodeName(), sb.toString());
        }
    }

}
0 голосов
/ 07 июня 2018

для исключения перехвата в обработчике исключений @ControllerAdvice, попробуйте это:

@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ApplicationExceptionHandler {

    private static Logger logger = LoggerFactory.getLogger(ApplicationExceptionHandler.class);

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({RuntimeException.class})
    public @ResponseBody Response<Error> handleIllegalArgumentException(Exception e) {
        logger.error("BadRequestException :: ", e);
        return new Response<Error>(new Error("BadRequestException", e.getMessage()));
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...