Сбой пользовательских исключений в загрузочном приложении Spring - PullRequest
0 голосов
/ 02 мая 2020

Я пытаюсь настроить свой объект ответа, когда возникает Исключение (как по умолчанию это откроет путь к контексту и другие технические детали в ответе). Я обнаружил, что мы можем использовать аннотацию @ControllerAdvice для достижения этой цели.

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

@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler(value = {HttpMessageNotReadableException.class})
    protected ResponseEntity<ExceptionResDto> handleException(){
        ExceptionResDto response = new ExceptionResDto();
        .......
        return new ResponseEntity<ExceptionResDto>(response, new HttpHeaders(), HttpStatus.BAD_REQUEST);
    }

Но если я сделал что-то подобное, это работает !!! (Переопределение доступного в настоящее время метода для перехвата HttpMessageNotReadableException)

@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
    .... //customized code
        return new ResponseEntity<Object>(response, new HttpHeaders(), status);
}

Мой вопрос: @ExceptionHandler (value = {CustomException.class}) используется только для пользовательских исключений? Не может быть использован для существующих более общих исключений? Чтобы настроить такие общие исключения, нужно ли нам всегда переопределять их исходные методы обработки исключений?

Ниже приводится результат журнала.

(AbstractAutowireCapableBeanFactory.java:409)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
    ... 49 common frames omitted
2020-05-03 14:38:41.565 [main] ERROR o.s.boot.SpringApplication -
                Application startup failed 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'handlerExceptionResolver' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerExceptionResolver]: Factory method 'handlerExceptionResolver' threw exception; nested exception is java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.http.converter.HttpMessageNotReadableException]: {protected org.springframework.http.ResponseEntity lk.crm.dialog.config.CustomExceptionHandler.myHandleException(), public final org.springframework.http.ResponseEntity org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest)}
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151)
    at lk.crm.dialog.Application.main(Application.java:17)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerExceptionResolver]: Factory method 'handlerExceptionResolver' threw exception; nested exception is java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.http.converter.HttpMessageNotReadableException]: {protected org.springframework.http.ResponseEntity lk.crm.dialog.config.CustomExceptionHandler.myHandleException(), public final org.springframework.http.ResponseEntity org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest)}
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    ... 26 common frames omitted
Caused by: java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.http.converter.HttpMessageNotReadableException]: {protected org.springframework.http.ResponseEntity lk.crm.dialog.config.CustomExceptionHandler.myHandleException(), public final org.springframework.http.ResponseEntity org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest)}
    at org.springframework.web.method.annotation.ExceptionHandlerMethodResolver.addExceptionMapping(ExceptionHandlerMethodResolver.java:109)
    at org.springframework.web.method.annotation.ExceptionHandlerMethodResolver.<init>(ExceptionHandlerMethodResolver.java:76)
    at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.initExceptionHandlerAdviceCache(ExceptionHandlerExceptionResolver.java:269)
    at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.afterPropertiesSet(ExceptionHandlerExceptionResolver.java:245)
    at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.addDefaultHandlerExceptionResolvers(WebMvcConfigurationSupport.java:883)
    at org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration.configureHandlerExceptionResolvers(WebMvcAutoConfiguration.java:428)
    at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.handlerExceptionResolver(WebMvcConfigurationSupport.java:826)
    at org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$901be0b6.CGLIB$handlerExceptionResolver$41(<generated>)
    at org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$901be0b6$$FastClassBySpringCGLIB$$b8bb3bfc.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356)
    at org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$901be0b6.handlerExceptionResolver(<generated>)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 27 common frames omitted

1 Ответ

0 голосов
/ 02 мая 2020

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

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

    public class CustomExceptionModel{

    private String message
    private HttpStatus httpStatus
    private ZonedTime timestamp

    public Custom{ExceptionModel (String message, HttpStatus httpStatus){
this.message = message;
this.httpStatus = httpStatus;
this.timeStamp = ZonedTime.now();
    }
    }

Ваш обработчик будет выглядеть так

@ExceptionHandler(value = {HttpMessageNotReadableException.class})
    protected ResponseEntity<ExceptionResDto> handleException(HttpMessageNotReadableException ex){
       log.severe("Put details here ;) ");
        return new ResponseEntity<CustomExceptionModel>(new CustomExceptionModel(ex.getMessage(), ex.getStatus()), HttpStatus.BAD_REQUEST);
    }

Это исключение Json как исключение именно с содержанием, которое вам нужно. Я рекомендую использовать метку времени, сообщение с довольно общей причиной (я имею в виду не всю трассировку стека. Это вы можете поместить в свой log.severe () для exampe и httpStatuscode. Я знаю, что код состояния также добавляется в объект responseEntity, но Мне нравится, когда он отображается в json.

Обновление: Я только что видел, что вы вызываете свой метод обработки исключений "handleException". Поскольку вы правильно расширяете ResponseEntityExceptionhandler, вы уже метод, который назван таким же образом. Так что Spring запутался. Попробуйте переименовать ваш метод обработки исключений. Я предпочитаю использовать имя исключения и использовать его с указателем, например handleHttpMethodNotReadableException. Надеюсь, это поможет

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