java 引起:org.springframework.jms.support.converter.MessageConversionException:在消息上找不到类型 id 属性 [_type]
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45526371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Caused by: org.springframework.jms.support.converter.MessageConversionException: Could not find type id property [_type] on message
提问by Imran
I am trying this spring JMS sample, and it gives error.
https://spring.io/guides/gs/messaging-jms/Caused by: org.springframework.jms.support.converter.MessageConversionException: Could not find type id property [_type] on message from destination [queue://mailbox]
Interesting part is, if I clone it and run everything runs fine. If I copy and paste, it gives error.
我正在尝试这个 spring JMS 示例,但它给出了错误。
https://spring.io/guides/gs/messaging-jms/由:org.springframework.jms.support.converter.MessageConversionException: Could not find type id property [_type] on message from destination [queue://mailbox]
有趣的部分是,如果我克隆它并运行一切正常。如果我复制和粘贴,它会出错。
@Bean // Serialize message content to json using TextMessage
public MessageConverter HymansonJmsMessageConverter() {
MappingHymanson2MessageConverter converter = new MappingHymanson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
This piece of code actually causing the error. Searching the web and documentation, I still have no clue how and what to set setTypeIdPropertyName value and with "_type" what it refers in this project to? As the message does not have such property, then where is it coming from ?
这段代码实际上导致了错误。搜索网络和文档,我仍然不知道如何以及如何设置 setTypeIdPropertyName 值以及“_type”在该项目中指的是什么?由于消息没有这样的属性,那么它来自哪里?
回答by Danylo Zatorsky
TypeIdPropertyName
is a name of a property that identifies the entity. Hymanson mapper should know what entity to use when deserializing incoming JSON.
TypeIdPropertyName
是标识实体的属性名称。Hymanson 映射器应该知道在反序列化传入的 JSON 时使用什么实体。
The request should look like the following:
请求应如下所示:
{
"_type" : "hello.Email",
"to" : "Imran",
"from" : "dzatorsky"
}
Btw I think this is not the best solution since JMS already know what type to use (you declare it in your method). Another drawback is that you specify name of your entity and package in the messages which will hard to maintain (every change of a package or entity name will be a pain).
顺便说一句,我认为这不是最好的解决方案,因为 JMS 已经知道要使用什么类型(您在方法中声明它)。另一个缺点是您在消息中指定了实体和包的名称,这将很难维护(包或实体名称的每次更改都会很痛苦)。
Here is more robust config:
这是更强大的配置:
@EnableJms
@Configuration
public class JmsListenerConfig implements JmsListenerConfigurer {
@Bean
public DefaultMessageHandlerMethodFactory handlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setMessageConverter(messageConverter());
return factory;
}
@Bean
public MessageConverter messageConverter() {
return new MappingHymanson2MessageConverter();
}
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
registrar.setMessageHandlerMethodFactory(handlerMethodFactory());
}
}
Also if you use Spring JmsTemplate for sending messages you could add this component to your configuration:
此外,如果您使用 Spring JmsTemplate 发送消息,您可以将此组件添加到您的配置中:
/**
* Used to convert JMS messages from/to JSON. Registered in Spring-JMS automatically via auto configuration
*/
@Component
public class JsonMessageConverter implements MessageConverter {
@Autowired
private ObjectMapper mapper;
/**
* Converts message to JSON. Used mostly by {@link org.springframework.jms.core.JmsTemplate}
*/
@Override
public javax.jms.Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
String json;
try {
json = mapper.writeValueAsString(object);
} catch (Exception e) {
throw new MessageConversionException("Message cannot be parsed. ", e);
}
TextMessage message = session.createTextMessage();
message.setText(json);
return message;
}
/**
* Extracts JSON payload for further processing by HymansonMapper.
*/
@Override
public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException {
return ((TextMessage) message).getText();
}
}
With this configuration you can skip annoying "_type" field in your messages.
使用此配置,您可以跳过消息中烦人的“_type”字段。
回答by MattC
The other answers didn't specify setting the type on the calling side, so I'll point that out. You need a message converter on BOTH the calling and the receiving side (assuming you are not just playing around with a single application):
其他答案没有指定在调用方设置类型,所以我会指出这一点。您在调用方和接收方都需要一个消息转换器(假设您不只是在玩一个应用程序):
@Bean
public MessageConverter HymansonJmsMessageConverter() {
MappingHymanson2MessageConverter converter = new MappingHymanson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
Spring will automatically use this messageConverter with JmsTemplate (if that is what you are using). And "_type" can be anything, but it is supposed to be the same on both sides.
Spring 将自动将此 messageConverter 与 JmsTemplate 一起使用(如果这是您正在使用的)。而“_type”可以是任何东西,但两边应该是一样的。
回答by Michail Alexakis
The custom (i.e. application-level) "_type" property must be a JMS property set on the message (by its producer). The message payload is not littered with type metadata. To learn about JMS Message properties, one should visit https://docs.oracle.com/javaee/7/api/javax/jms/Message.html
自定义(即应用程序级)“_type”属性必须是在消息上设置的 JMS 属性(由其生产者)。消息有效负载没有类型元数据。要了解 JMS 消息属性,应访问https://docs.oracle.com/javaee/7/api/javax/jms/Message.html
This is notto be confused with a JSON property which may be used alternatively and must be configured with Hymanson-based annotations (e.g as polymorphic deserialization). In this case, the actual message payload (the JSON string) is changed and contains a "_type" property at the top-level object.
这是不与可替换地使用,并且必须与基于Hyman逊的注解来配置的JSON属性混淆(例如,如多晶型反序列化)。在这种情况下,实际消息负载(JSON 字符串)已更改,并在顶级对象中包含“_type”属性。