【问题标题】:Creating custom ErrorWebExceptionHandler fails创建自定义 ErrorWebExceptionHandler 失败
【发布时间】:2019-03-01 01:28:23
【问题描述】:

我正在尝试通过扩展默认的 ErrorWebExceptionHandler 在 Spring Boot 2 中创建自己的 ErrorWebExceptionHandler,但我的应用程序无法启动并显示以下消息:

Caused by: java.lang.IllegalArgumentException: Property 'messageWriters' is required
at org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler.afterPropertiesSet(AbstractErrorWebExceptionHandler.java:214) ~[spring-boot-autoconfigure-2.0.4.RELEASE.jar:2.0.4.RELEASE]

我的处理程序(Kotlin 代码):

@Component
@Order(-2)
class SampleErrorWebExceptionHandler(
    errorAttributes: ErrorAttributes?,
    resourceProperties: ResourceProperties?,
    errorProperties: ErrorProperties?,
    applicationContext: ApplicationContext?
) : DefaultErrorWebExceptionHandler(errorAttributes, resourceProperties, errorProperties, applicationContext) {

    override fun logError(request: ServerRequest, errorStatus: HttpStatus) {
        // do something
    }
}

可能是什么原因?

【问题讨论】:

    标签: spring-boot spring-webflux


    【解决方案1】:

    请尝试在你的构造函数中添加 ServerCodecConfigurer 的依赖

    GlobalErrorWebExceptionHandler(
      ErrorAttributes errorAttributes,
      ResourceProperties resourceProperties,
      ApplicationContext applicationContext,
      ServerCodecConfigurer configurer
    ) {
        super(errorAttributes, resourceProperties, applicationContext);
        this.setMessageWriters(configurer.getWriters());
    }
    

    【讨论】:

      【解决方案2】:

      您需要在该实例上设置messageWriters,因为这里需要它们。您可能应该将其创建为 @Bean,就像 Spring Boot is doing in the dedicated auto-configuration 一样。

      【讨论】:

      • 我已经添加了对 ServerCodecConfigurer 的依赖,我可以从那里获得 messageWritersmessageReaders,它现在可以工作了,谢谢!
      • 你好@MiloszTylenda你能在这里提供答案吗,我也面临同样的问题,解决方案不是很清楚
      【解决方案3】:

      我也这样做了,在查看了 springs 实现之后,我只是将组件添加到构造函数中。

      @Component
      @Order(-2)
      class GlobalErrorWebExceptionHandler(
              errorAttributes: ErrorAttributes,
              resourceProperties: ResourceProperties,
              applicationContext: ApplicationContext,
              viewResolvers: ObjectProvider<ViewResolver>,
              serverCodecConfigurer: ServerCodecConfigurer
      ) : AbstractErrorWebExceptionHandler(
              errorAttributes,
              resourceProperties,
              applicationContext
      ) {
          private val logger = LogFactory.getLog(GlobalErrorWebExceptionHandler::class.java)!!
      
          init {
              setViewResolvers(viewResolvers.orderedStream().collect(Collectors.toList()))
              setMessageWriters(serverCodecConfigurer.writers)
              setMessageReaders(serverCodecConfigurer.readers)
          }
      
          override fun getRoutingFunction(errorAttributes: ErrorAttributes) = RouterFunctions.route(RequestPredicates.all(), HandlerFunction { request ->
              val ex = getError(request)
              logger.error(ex.message)
      
              ServerResponse.ok().build()
          })
      }
      

      【讨论】:

        【解决方案4】:

        如果上述解决方案不是很清楚,请参考以下:

        @Component
        @Order(-2)
        public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
        
            private final ObjectProvider<ViewResolver> viewResolvers;
            private final ServerCodecConfigurer serverCodecConfigurer;
        
        
            public GlobalErrorWebExceptionHandler(ObjectProvider<ViewResolver> viewResolvers, ServerCodecConfigurer serverCodecConfigurer,
                                                  ErrorAttributes errorAttributes, WebProperties.Resources resources, ApplicationContext applicationContext) {
                super(errorAttributes, resources, applicationContext);
                this.viewResolvers = viewResolvers;
                this.serverCodecConfigurer = serverCodecConfigurer;
                super.setMessageWriters(serverCodecConfigurer.getWriters());
                super.setMessageReaders(serverCodecConfigurer.getReaders());
                super.setViewResolvers(viewResolvers.orderedStream().collect(Collectors.toList()));
            }
        
            @Override
            protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
                return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
            }
        
            private Mono<ServerResponse> renderErrorResponse(ServerRequest serverRequest) {
                Map<String, Object> errorPropertiesMap = getErrorAttributes(serverRequest,
                        ErrorAttributeOptions.defaults());
        
                return ServerResponse.status(HttpStatus.BAD_REQUEST)
                        .contentType(MediaType.APPLICATION_JSON)
                        .body(BodyInserters.fromValue(errorPropertiesMap));
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2015-07-21
          • 2021-04-06
          • 2018-06-11
          • 1970-01-01
          • 2014-02-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-30
          相关资源
          最近更新 更多