Как правильно выкинуть и обнаружить это исключение - PullRequest
1 голос
/ 02 марта 2020

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

Пытаюсь вызвать исключение при создании класса:

    public void setStatus(String status) throws InvalidInputStatusException{
       if(checkIfStatusIsAllowed(status)) {
           this.status = status;
       } else {
           throw new InvalidInputStatusException();
       }

    }

Пытаюсь поймать ошибку:

@ControllerAdvice
public class RekvisisjonRESTControllerExceptionHandler {

    //TODO: Add logger here!

    @ExceptionHandler
    public final ResponseEntity<RekvisisjonRESTErrorResponse> handleException(InvalidInputStatusException e, WebRequest request) {
        //TODO: Do some logging
        return new ResponseEntity<>(new RekvisisjonRESTErrorResponse(HttpStatus.BAD_REQUEST.toString(),
                e.getClass().getName(),
                e.getMessage(), LocalDateTime.now()), HttpStatus.BAD_REQUEST);
    }
}

Мне нужен возвращаемый объект, указанный выше, но вместо этого я получаю вот эту ерунду:

  "error": "Bad Request",
    "message": "JSON parse error: Ugyldig status som input; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Ugyldig status som input\n at [Source: (PushbackInputStream); line: 2, column: 12] (through reference chain: no.pasientreiser.atom.rekvisisjon.controller.dto.UpdateRekvisisjonStatusRequest[\"status\"])",
    "trace": "org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Ugyldig status som input; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Ugyldig status som input\n at [Source: (PushbackInputStream); line: 2, column: 12] (through reference chain: no.pasientreiser.atom.rekvisisjon.controller.dto.UpdateRekvisisjonStatusRequest[\"status\"])\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:245)\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:227)\n\tat org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:205)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:158)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:131)\n\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)\n\tat org.springframework.web.me

Я предполагаю, что не удается обнаружить предполагаемое исключение, поскольку другое бросили перед этим, но это не то, что я хочу.

Любые рекомендации?

Ответы [ 3 ]

2 голосов
/ 02 марта 2020

Обработчик исключений обрабатывает исключения, возникающие в ваших методах обработчика (см. https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc). Исключение, которое вы видите, происходит раньше, когда Spring пытается превратить тело запроса JSON в UpdateRekvisisjonStatusRequest. Десериализатор Джексона JSON вызывает метод setStatus и встречает исключение, которое, по мнению Spring, означает, что тело HTTP не читается (поскольку Джексон не смог его десериализовать).

Посмотрите, как Spring MVC вместо этого обрабатывает проверку: https://spring.io/guides/gs/validating-form-input/

0 голосов
/ 02 марта 2020

Сначала ваш RekvisisjonRESTControllerExceptionHandler должен расширяться от ResponseEntityExceptionHandler. Если вы вернете ResponseEntity, он обернет ваш класс значений (RekvisisjonRESTErrorResponse). Здесь ваше исключение генерируется после рекомендации, когда json сериализовано.

0 голосов
/ 02 марта 2020

Исключение происходит не в вашем бизнес-коде, а во время синтаксического анализа запроса в объект представления вашего запроса. Spring Web рассматривает любое исключение, которое произошло во время синтаксического анализа запроса, как ошибку уровня представления, а не ошибку бизнес-уровня, следовательно, ваш обработчик исключений не вызывается.

Поскольку вы пытаетесь принудительно применить бизнес-правило здесь, я бы предложил убрать его из метода сеттера объекта презентации и найти для него лучшее место. Например, поместите эту логику c в бизнес-объект, или в одну из ваших служб, или, по крайней мере, в метод контроллера, который принимает запрос.

...