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>