gpt4 book ai didi

java - 如何在 Spring 集成中解码 Xml 负载后保留 JMS header

转载 作者:行者123 更新时间:2023-11-30 05:29:34 27 4
gpt4 key购买 nike

我正在发送带有 XML 负载和一些自定义 header 的 JMS 消息 contentType值为 text/jsontext/xml使用 Jmeter。

我的 Spring 集成配置如下所示:

<jms:message-driven-channel-adapter channel="jmsInChannel" destination-name="queue.demo" connection-factory="jmsConnectionFactory1" />
<int:channel id="jmsInChannel" />

<int:header-value-router input-channel="jmsInChannel" header-name="contentType" default-output-channel="nullChannel">
<int:mapping value="text/json" channel="jsonTransformerChannel" />
<int:mapping value="text/xml" channel="xmlTransformerChannel" />
</int:header-value-router>

到目前为止,一切正常,消息已成功路由到各自的转换器。

我的问题是,当它是 XML 有效负载时,我首先使用 JAXB Unmarshaller 和 <ixml:unmarshalling-transofmer ../>http://www.springframework.org/schema/integration/xml提供.

我可以获取有效负载,但之后无法将消息作为 JMS 消息进行处理,它变成了纯 POJO。所以我丢失了标题,并且无法使用 <int: ../>组件而不序列化 POJO,这不是我想要实现的。

我找到了一种解决方法,我在 java 中定义了自己的 Unmarshalling bean,如下所示:

<int:channel id="xmlTransformerChannel" />
<int:transformer input-channel="xmlTransformerChannel" ref="xmlMsgToCustomerPojoTransformer" output-channel="enrichInChannel" />

方法:

@SuppressWarnings("rawtypes")
public Message transform(String message) {

logger.info("Message Received \r\n" + message);

try {
MyModel myModel = (MyModel) unmarshaller.unmarshal(new StreamSource(new StringReader(message)));
return MessageBuilder.withPayload(myModel).build();

} catch (XmlMappingException e) {
return MessageBuilder.withPayload(e).build();
} catch (Exception e) {
return MessageBuilder.withPayload(e).build();
}
}

我可以成功地将消息作为 Spring 集成消息进行处理,但我丢失了原始的自定义 JMS header 。

相比之下,我所要做的就是转换 json 有效负载并保留消息格式并保留我的自定义 header 就是以下 xml 配置:

<int:channel id="jsonTransformerChannel" />
<int:json-to-object-transformer input-channel="jsonTransformerChannel" output-channel="enrichInChannel" type="com.alrawas.ig5.MyModel" />

我的问题是,在解码 xml 负载后如何保留原始的自定义 JMS header ?

更新:

我确实尝试以这种方式编写 xml 转换器,将 Message 作为输入而不是仅将字符串作为输入,它在此方法中没有抛出异常,但在稍后的路由阶段却抛出了异常

public Message<?> transform(Message<String> message) {

logger.info("Message Received \r\n" + message);

try {
MyModel myModel = (MyModel) unmarshaller.unmarshal(new StreamSource(new StringReader(message.getPayload())));
return (Message<MyModel>) MessageBuilder.withPayload(myModel).copyHeaders(message.getHeaders()).build();

} catch (XmlMappingException e) {
return MessageBuilder.withPayload(e).build();
} catch (Exception e) {
return MessageBuilder.withPayload(e).build();
}
}

我在此流程中稍后使用的组件中遇到了问题:

<int:object-to-json-transformer input-channel="outr" output-channel="outch" />
<int:router method="route" input-channel="outch" default-output-channel="nullChannel">
<bean class="com.alrawas.ig5.MyCustomRouter" />
</int:router>

在我的路由方法中抛出 Cannot cast String to com.alrawas.ig5.MyModel 异常:

public class MyCustomRouter {

public String route(Message<MyModel> myModel) {

Integer tenNumber = myModel.getPayload().getNumber(); // <-- Cast Exception here
System.out.println(myModel);
return (tenNumber % 10 == 0) ? "stayLocal" : "goRemote";

}
}

此转换异常仅在解码 xml 之后发生,JSON 有效负载可以正常工作,不会丢失 header 或引发转换异常。

更新:

检查下面我的答案:contentType was not really a custom header

最佳答案

当您开发自定义transformer时,您需要记住返回 Message<?>使您能够完全控制其内容。

当转换器函数返回 Message 时,它不会填充任何请求 header 。

所以,你的public Message transform(String message) {必须期待 Message作为输入,您需要将请求消息中的所有 header 复制到回复消息。 MessageBuilder上有合适的方法.

另一方面,完全不清楚为什么您需要返回 Message在这里,因为 Spring Integration 中的所有内容都将被包装到 Message在发送到输出 channel 之前。

关于java - 如何在 Spring 集成中解码 Xml 负载后保留 JMS header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57849005/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com