Spring JMS MappingJackson2MessageConverter - 无法处理错误
Spring JMS MappingJackson2MessageConverter - No way to handle errors
我正在使用 Spring JMS 和 ActiveMQ,我正在使用 MappingJackson2MessageConverter
在各个组件之间传递消息。
我的核心问题是,当 MappingJackson2MessageConverter
遇到内部反序列化错误时,将字符串反序列化为某个对象时,这些异常不会以我可以响应的任何方式引发。我的错误处理程序逻辑永远不会被调用,也不会抛出我有权访问的异常。这些反序列化错误似乎被完全吞没了,当它们记录在控制台中时,我没有机会执行自定义逻辑来响应它们。
我定义我的 MappingJackson2MessageConverter
bean 如下:
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
我定义一个 JMS Listener 工厂如下:
@Bean
public JmsListenerContainerFactory<?> jmsListenerQueueFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer, JmsErrorHandler jmsErrorHandler) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setErrorHandler(jmsErrorHandler); // <-- I expect this to be used
configurer.configure(factory, connectionFactory);
return factory;
}
上一行中重要的是 setErrorHandler
调用。我已经定义了一个简单的 ErrorHandler
对象,它试图捕获我的 @JmsListener
方法可能抛出的错误。这个简单的错误处理程序如下所示:
public class JmsErrorHandler implements ErrorHandler {
@Override
public void handleError(Throwable t) {
System.out.println("WE HAVE THE ERROR!");
}
}
我的监听器也很简单,如下:
@JmsListener(id = MY_ID, destination = MY_DEST)
public void processMessage(MyPojoMessage myPojoMessage) {
// This code is obviously never reached, since the serialization error occurs.
总的来说,这是一个非常简单和基本的设置。现在,当我发送无效消息时,Jackson 将无法 解析,我在控制台中收到以下错误:
19-10-2020 09:05:33.933 [35m[DefaultMessageListenerContainer-1][0;39m [31mWARN [0;39m o.s.j.l.DefaultMessageListenerContainer.invokeErrorHandler - Execution of JMS message listener failed, and no ErrorHandler has been set.
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void com.example.processMessage(com.example.MyPojoMessage)' threw exception; nested exception is org.springframework.jms.support.converter.MessageConversionException: Failed to convert JSON message content; nested exception is com.fasterxml.jackson.databind.JsonMappingException
此异常是预期的 - 因为我提供了 Jackson 无法序列化的无效负载。但是,我似乎没有办法 配置代码以我可以响应的方式实际捕获此异常。我在上面的代码中设置错误处理程序。然而日志抱怨 no ErrorHandler has been set
这似乎是错误的。
我看不出有其他方法可以引用这个 Jackson 内部异常。有什么办法吗?
看起来 ConditionalOnMissingBean 自动配置已开启 bean name
所以你应该有这样的东西。
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer, JmsErrorHandler jmsErrorHandler) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setErrorHandler(jmsErrorHandler); // <-- I expect this to be used
configurer.configure(factory, connectionFactory);
return factory;
}
我正在使用 Spring JMS 和 ActiveMQ,我正在使用 MappingJackson2MessageConverter
在各个组件之间传递消息。
我的核心问题是,当 MappingJackson2MessageConverter
遇到内部反序列化错误时,将字符串反序列化为某个对象时,这些异常不会以我可以响应的任何方式引发。我的错误处理程序逻辑永远不会被调用,也不会抛出我有权访问的异常。这些反序列化错误似乎被完全吞没了,当它们记录在控制台中时,我没有机会执行自定义逻辑来响应它们。
我定义我的 MappingJackson2MessageConverter
bean 如下:
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
我定义一个 JMS Listener 工厂如下:
@Bean
public JmsListenerContainerFactory<?> jmsListenerQueueFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer, JmsErrorHandler jmsErrorHandler) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setErrorHandler(jmsErrorHandler); // <-- I expect this to be used
configurer.configure(factory, connectionFactory);
return factory;
}
上一行中重要的是 setErrorHandler
调用。我已经定义了一个简单的 ErrorHandler
对象,它试图捕获我的 @JmsListener
方法可能抛出的错误。这个简单的错误处理程序如下所示:
public class JmsErrorHandler implements ErrorHandler {
@Override
public void handleError(Throwable t) {
System.out.println("WE HAVE THE ERROR!");
}
}
我的监听器也很简单,如下:
@JmsListener(id = MY_ID, destination = MY_DEST)
public void processMessage(MyPojoMessage myPojoMessage) {
// This code is obviously never reached, since the serialization error occurs.
总的来说,这是一个非常简单和基本的设置。现在,当我发送无效消息时,Jackson 将无法 解析,我在控制台中收到以下错误:
19-10-2020 09:05:33.933 [35m[DefaultMessageListenerContainer-1][0;39m [31mWARN [0;39m o.s.j.l.DefaultMessageListenerContainer.invokeErrorHandler - Execution of JMS message listener failed, and no ErrorHandler has been set.
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void com.example.processMessage(com.example.MyPojoMessage)' threw exception; nested exception is org.springframework.jms.support.converter.MessageConversionException: Failed to convert JSON message content; nested exception is com.fasterxml.jackson.databind.JsonMappingException
此异常是预期的 - 因为我提供了 Jackson 无法序列化的无效负载。但是,我似乎没有办法 配置代码以我可以响应的方式实际捕获此异常。我在上面的代码中设置错误处理程序。然而日志抱怨 no ErrorHandler has been set
这似乎是错误的。
我看不出有其他方法可以引用这个 Jackson 内部异常。有什么办法吗?
看起来 ConditionalOnMissingBean 自动配置已开启 bean name
所以你应该有这样的东西。
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer, JmsErrorHandler jmsErrorHandler) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setErrorHandler(jmsErrorHandler); // <-- I expect this to be used
configurer.configure(factory, connectionFactory);
return factory;
}