Spring 通过 JAXB 或其他工具集成动态 XML
Spring Integration Dynamic XML through JAXB or other tool
目前我有一个 Spring 集成 XML 文件,它使用 JAXB 将 Java POJO 编组到 XML,然后将它们作为 JMS 消息发送。但是,我不想编组 Java POJO 并通过 JMS 发送,而是想将 XML 字符串发送到下面同一集成文件中的 JMS,该字符串将在 Java 文件内动态生成。所以我想这可能会通过替换下面文件中现有的 Marshaller 和 transformer 来完成,但我不知道具体如何。
简而言之,我想知道如何使用动态 XML 字符串发送和替换 Java POJO 的编组。
更新
我研究并发现 DOMSource 非常适合生成动态 XML。我可以轻松地将 Java 文件中的 DOM 转换为字符串,但我无法通过 Spring 集成来完成。我需要使用下面的 spring 集成文件将字符串编组到 XML 而不是 Java 对象到 XML。
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = document.createElement("Root");
document.appendChild(root);
Element foo = document.createElement("Foo");
foo.appendChild(document.createTextNode("Bar"));
root.appendChild(foo);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(document), result);
System.out.println("XML IN String format is: \n" + writer.toString());
我的要求是通过下面XML 中的Spring 集成将DOMSource 的结果转换为String。更改可能必须在 bean id 中完成:Verify_Flight_Detail_Req_MarshallingTransformer 下面可能在 XML 某处。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
xsi:schemaLocation="
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Queue names -->
<util:constant id="Verify_Flight_Detail_SEND_QUEUE"
static-field="cipac.integration.mq.flight.VerifyFlightDetailGateway.SEND_QUEUE" />
<util:constant id="Verify_Flight_Detail_RECEIVE_QUEUE"
static-field="cipac.integration.mq.flight.VerifyFlightDetailGateway.RECEIVE_QUEUE" />
**<!-- Request Marshaller and Transformer -->
<bean id="Verify_Flight_Detail_Req_Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound"
value="cipac.integration.mq.flight.messages.verifyflightdtl.VerifyFlightDetailReq" />
<property name="marshallerProperties" ref="MQ_MARSHALLER_PROPERTIES" />
</bean>
<bean id="Verify_Flight_Detail_Req_MarshallingTransformer"
class="cipac.integration.mq.common.marshalling.MarshallingTransformerFactory"
factory-method="buildMarshallingTransformer">
<constructor-arg ref="Verify_Flight_Detail_Req_Marshaller" />
<constructor-arg>
<ref bean="resultToStringTransformer" />
</constructor-arg>
</bean>**
<!-- Reply Marshaller and Transformer -->
<bean id="Verify_Flight_Detail_Rply_Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound"
value="cipac.integration.mq.flight.messages.verifyflightdtl.VerifyFlightDetailRply" />
<property name="marshallerProperties" ref="MQ_MARSHALLER_PROPERTIES" />
</bean>
<bean id="Verify_Flight_Detail_Rply_UnmarshallingTransformer"
class="cipac.integration.mq.common.marshalling.UnmarshallingTransformerFactory"
factory-method="buildUnmarshallingTransformer">
<constructor-arg ref="Verify_Flight_Detail_Rply_Marshaller" />
</bean>
<int:channel id="Verify_Flight_Detail_Req">
<int:interceptors>
<int:ref bean="cipacOutInterceptor" />
</int:interceptors>
</int:channel>
<int:channel id="Verify_Flight_Detail_Req_Raw">
<int:interceptors>
<int:wire-tap channel="request-response-jms-logger" />
</int:interceptors>
</int:channel>
<int:channel id="Verify_Flight_Detail_Rply_Raw">
<int:interceptors>
<int:wire-tap channel="request-response-jms-logger" />
</int:interceptors>
</int:channel>
<int:channel id="Verify_Flight_Detail_Rply">
<int:interceptors>
<int:ref bean="cipacInInterceptor" />
</int:interceptors>
</int:channel>
<!-- inbound -->
<int:gateway service-interface="cipac.integration.mq.flight.VerifyFlightDetailGateway">
<int:method name="requestReply" request-channel="Verify_Flight_Detail_Req"
reply-channel="Verify_Flight_Detail_Rply" />
</int:gateway>
<int:chain id="Verify_Flight_Detail_Req_Chain"
input-channel="Verify_Flight_Detail_Req"
output-channel="Verify_Flight_Detail_Req_Raw" >
<!-- transform -->
<int:transformer ref="Verify_Flight_Detail_Req_MarshallingTransformer" />
</int:chain>
<!-- outbound -->
<int-jms:outbound-gateway
request-channel="Verify_Flight_Detail_Req_Raw"
reply-channel="Verify_Flight_Detail_Rply_Raw"
request-destination-name="#{Verify_Flight_Detail_SEND_QUEUE}"
reply-destination-name="#{Verify_Flight_Detail_RECEIVE_QUEUE}"
idle-reply-listener-timeout="${integration.mq.iddleTimeout}"
connection-factory="connectionFactory"
message-converter="cipacMessageConverter"
header-mapper="cipacHeaderMapper"
destination-resolver="cipacDestinationResolver"
receive-timeout="${integration.mq.receiveTimeout}"
time-to-live="${integration.mq.timeToLive}"
explicit-qos-enabled="true"
delivery-persistent="false"
/>
<!-- transform -->
<int:transformer input-channel="Verify_Flight_Detail_Rply_Raw"
output-channel="Verify_Flight_Detail_Rply" ref="Verify_Flight_Detail_Rply_UnmarshallingTransformer" />
<bean id="Verify_Flight_Detail_Cards_Rply_Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound"
value="cipac.integration.mq.flight.messages.verifyflightdtl.VerifyFlightDetailRply" />
</bean>
<bean id="Verify_Flight_Detail_Cards_Rply_UnmarshallingTransformer"
class="cipac.integration.mq.common.marshalling.UnmarshallingTransformerFactory"
factory-method="buildUnmarshallingTransformer">
<constructor-arg ref="Verify_Flight_Detail_Cards_Rply_Marshaller" />
</bean>
</beans>
这就是当前正在编组的 POJO 的方式。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Root")
public class VerifyFlightDetailReq {
private static final long serialVersionUID = 1L;
@XmlElement(name = "Flight_Number")
private String flight_number;
@XmlElement(name = "PNR_Number")
private String pnr_number;
@XmlElement(name = "Cust_Full_Name")
private String customerFullName;
更新2:
请参阅下面对我有用的答案。
经过一番挣扎,我弄清楚了自己。我使用 DomSource 生成 XML 字符串,然后通过 Custom Transformer 而不是 JaxB Transformer 将其传递给 JMS。
在服务/存储库中class
VerifyFlightReqID req = VerifyFlightReqID();
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = document.createElement("Root");
document.appendChild(root);
Element foo = document.createElement("Foo");
foo.appendChild(document.createTextNode("Bar"));
root.appendChild(foo);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
req.setXmlPayload(writer.toString());
verifyFlightDetailGateway.requestreply(req);
在变压器中class
public class DynamicXmlTransformer {
@Transformer
public Message<String> buildTransformer(Message message) {
//Your Data Type which you send through gateway or you can use just use string to pass XML from your service interface
VerifyFlightReqID req = (VerifyFlightReqID ) message.getPayload();
return MessageBuilder.withPayload(req.xmlpayload).build();
}
Spring整合XML改变
<bean id="DynamicXmlTransformer" class="cipac.integration.mq.common.DynamicXmlTransformer" />
<int:chain id="Verify_Flight_Detail_Req_Chain"
input-channel="Verify_Flight_Detail_Req"
output-channel="Verify_Flight_Detail_Req_Raw" >
<!-- transform -->
ref="DynamicXmlTransformer" method="buildTransformer"/>
</int:chain>
目前我有一个 Spring 集成 XML 文件,它使用 JAXB 将 Java POJO 编组到 XML,然后将它们作为 JMS 消息发送。但是,我不想编组 Java POJO 并通过 JMS 发送,而是想将 XML 字符串发送到下面同一集成文件中的 JMS,该字符串将在 Java 文件内动态生成。所以我想这可能会通过替换下面文件中现有的 Marshaller 和 transformer 来完成,但我不知道具体如何。
简而言之,我想知道如何使用动态 XML 字符串发送和替换 Java POJO 的编组。
更新
我研究并发现 DOMSource 非常适合生成动态 XML。我可以轻松地将 Java 文件中的 DOM 转换为字符串,但我无法通过 Spring 集成来完成。我需要使用下面的 spring 集成文件将字符串编组到 XML 而不是 Java 对象到 XML。
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = document.createElement("Root");
document.appendChild(root);
Element foo = document.createElement("Foo");
foo.appendChild(document.createTextNode("Bar"));
root.appendChild(foo);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(document), result);
System.out.println("XML IN String format is: \n" + writer.toString());
我的要求是通过下面XML 中的Spring 集成将DOMSource 的结果转换为String。更改可能必须在 bean id 中完成:Verify_Flight_Detail_Req_MarshallingTransformer 下面可能在 XML 某处。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
xsi:schemaLocation="
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Queue names -->
<util:constant id="Verify_Flight_Detail_SEND_QUEUE"
static-field="cipac.integration.mq.flight.VerifyFlightDetailGateway.SEND_QUEUE" />
<util:constant id="Verify_Flight_Detail_RECEIVE_QUEUE"
static-field="cipac.integration.mq.flight.VerifyFlightDetailGateway.RECEIVE_QUEUE" />
**<!-- Request Marshaller and Transformer -->
<bean id="Verify_Flight_Detail_Req_Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound"
value="cipac.integration.mq.flight.messages.verifyflightdtl.VerifyFlightDetailReq" />
<property name="marshallerProperties" ref="MQ_MARSHALLER_PROPERTIES" />
</bean>
<bean id="Verify_Flight_Detail_Req_MarshallingTransformer"
class="cipac.integration.mq.common.marshalling.MarshallingTransformerFactory"
factory-method="buildMarshallingTransformer">
<constructor-arg ref="Verify_Flight_Detail_Req_Marshaller" />
<constructor-arg>
<ref bean="resultToStringTransformer" />
</constructor-arg>
</bean>**
<!-- Reply Marshaller and Transformer -->
<bean id="Verify_Flight_Detail_Rply_Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound"
value="cipac.integration.mq.flight.messages.verifyflightdtl.VerifyFlightDetailRply" />
<property name="marshallerProperties" ref="MQ_MARSHALLER_PROPERTIES" />
</bean>
<bean id="Verify_Flight_Detail_Rply_UnmarshallingTransformer"
class="cipac.integration.mq.common.marshalling.UnmarshallingTransformerFactory"
factory-method="buildUnmarshallingTransformer">
<constructor-arg ref="Verify_Flight_Detail_Rply_Marshaller" />
</bean>
<int:channel id="Verify_Flight_Detail_Req">
<int:interceptors>
<int:ref bean="cipacOutInterceptor" />
</int:interceptors>
</int:channel>
<int:channel id="Verify_Flight_Detail_Req_Raw">
<int:interceptors>
<int:wire-tap channel="request-response-jms-logger" />
</int:interceptors>
</int:channel>
<int:channel id="Verify_Flight_Detail_Rply_Raw">
<int:interceptors>
<int:wire-tap channel="request-response-jms-logger" />
</int:interceptors>
</int:channel>
<int:channel id="Verify_Flight_Detail_Rply">
<int:interceptors>
<int:ref bean="cipacInInterceptor" />
</int:interceptors>
</int:channel>
<!-- inbound -->
<int:gateway service-interface="cipac.integration.mq.flight.VerifyFlightDetailGateway">
<int:method name="requestReply" request-channel="Verify_Flight_Detail_Req"
reply-channel="Verify_Flight_Detail_Rply" />
</int:gateway>
<int:chain id="Verify_Flight_Detail_Req_Chain"
input-channel="Verify_Flight_Detail_Req"
output-channel="Verify_Flight_Detail_Req_Raw" >
<!-- transform -->
<int:transformer ref="Verify_Flight_Detail_Req_MarshallingTransformer" />
</int:chain>
<!-- outbound -->
<int-jms:outbound-gateway
request-channel="Verify_Flight_Detail_Req_Raw"
reply-channel="Verify_Flight_Detail_Rply_Raw"
request-destination-name="#{Verify_Flight_Detail_SEND_QUEUE}"
reply-destination-name="#{Verify_Flight_Detail_RECEIVE_QUEUE}"
idle-reply-listener-timeout="${integration.mq.iddleTimeout}"
connection-factory="connectionFactory"
message-converter="cipacMessageConverter"
header-mapper="cipacHeaderMapper"
destination-resolver="cipacDestinationResolver"
receive-timeout="${integration.mq.receiveTimeout}"
time-to-live="${integration.mq.timeToLive}"
explicit-qos-enabled="true"
delivery-persistent="false"
/>
<!-- transform -->
<int:transformer input-channel="Verify_Flight_Detail_Rply_Raw"
output-channel="Verify_Flight_Detail_Rply" ref="Verify_Flight_Detail_Rply_UnmarshallingTransformer" />
<bean id="Verify_Flight_Detail_Cards_Rply_Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound"
value="cipac.integration.mq.flight.messages.verifyflightdtl.VerifyFlightDetailRply" />
</bean>
<bean id="Verify_Flight_Detail_Cards_Rply_UnmarshallingTransformer"
class="cipac.integration.mq.common.marshalling.UnmarshallingTransformerFactory"
factory-method="buildUnmarshallingTransformer">
<constructor-arg ref="Verify_Flight_Detail_Cards_Rply_Marshaller" />
</bean>
</beans>
这就是当前正在编组的 POJO 的方式。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Root")
public class VerifyFlightDetailReq {
private static final long serialVersionUID = 1L;
@XmlElement(name = "Flight_Number")
private String flight_number;
@XmlElement(name = "PNR_Number")
private String pnr_number;
@XmlElement(name = "Cust_Full_Name")
private String customerFullName;
更新2:
请参阅下面对我有用的答案。
经过一番挣扎,我弄清楚了自己。我使用 DomSource 生成 XML 字符串,然后通过 Custom Transformer 而不是 JaxB Transformer 将其传递给 JMS。
在服务/存储库中class
VerifyFlightReqID req = VerifyFlightReqID();
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = document.createElement("Root");
document.appendChild(root);
Element foo = document.createElement("Foo");
foo.appendChild(document.createTextNode("Bar"));
root.appendChild(foo);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
req.setXmlPayload(writer.toString());
verifyFlightDetailGateway.requestreply(req);
在变压器中class
public class DynamicXmlTransformer {
@Transformer
public Message<String> buildTransformer(Message message) {
//Your Data Type which you send through gateway or you can use just use string to pass XML from your service interface
VerifyFlightReqID req = (VerifyFlightReqID ) message.getPayload();
return MessageBuilder.withPayload(req.xmlpayload).build();
}
Spring整合XML改变
<bean id="DynamicXmlTransformer" class="cipac.integration.mq.common.DynamicXmlTransformer" />
<int:chain id="Verify_Flight_Detail_Req_Chain"
input-channel="Verify_Flight_Detail_Req"
output-channel="Verify_Flight_Detail_Req_Raw" >
<!-- transform -->
ref="DynamicXmlTransformer" method="buildTransformer"/>
</int:chain>