如何强制在 citrus-ws 上发送 XML 声明标记

How to force XML declaration tag to be sent on citrus-ws

我正在尝试使用 citrus-framework 进行简单的 soap 测试,但我无法让服务器接受消息。经过一番挖掘,我发现发送的消息中不包含 xml 声明标记。

根据日志应该发送:

02:06:21,600 DEBUG    xml.XmlConfigurer| Using DOMImplementationLS:
org.apache.xerces.dom.CoreDOMImplementationImpl 02:06:21,623 DEBUG
ingClientInterceptor| Sending SOAP request 02:06:21,624 DEBUG  
Logger.Message_OUT| <?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/> <SOAP-ENV:Body>

但是从TCP/IP监控中我看到经过的是这样的:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/><SOAP-ENV:Body>

所以根据记录器,它应该在那里,但是当检查通过管道的内容时,它不是。

我已经确认缺少的是 xml 声明(), 将带有和不带有它的相同消息直接发送到服务器,服务器使用它处理请求,没有它与我 运行 柑橘测试时的结果相同 (失败)。

有什么办法可以强制发送吗?在柑橘线程和 spring 中搜索但找不到解决方案。

我的 citrus-ws 配置文件:

<citrus-ws:client id="soapClient"
request-url="http://localhost:8880/WS.asmx" timeout="60000"
message-factory="soapMessageFactory"/>

java dsl 块:

soap().client("soapClient")
        .send()
        .name("testsend")
        .charset("UTF-8")
        .contentType("text/xml")
        .payload(new ClassPathResource("com/i/B.xml"));

所以我发现默认情况下不会发送 xml 声明标记。可以通过将 WRITE_XML_DECLARATION 设置为 true 来发送,但无法通过 citrus-context.xml 文件.[= 中的 bean 配置找到方法。 15=]

编辑:我能够通过 citrus 中的 bean 配置来配置它-context.xml,在这个答案的最后解释。

不过,我通过绕过 bean 配置文件并通过 POJO 配置所有内容来更改它。

所以这是一步一步的:

POJO 配置:

1.1。我为配置创建了一个 class,我在其中为消息工厂定义了 bean,并将 WRITE_XML_DECLARATION 设置为 true:

@Bean(name = "messageFactory")
  public SaajSoapMessageFactory messageFactory() {
    SaajSoapMessageFactory smf = new SaajSoapMessageFactory();
    smf.setSoapVersion(org.springframework.ws.soap.SoapVersion.SOAP_11);
    Map<String, String> props = new HashMap<String, String>();
    props.put(SOAPMessage.WRITE_XML_DECLARATION, Boolean.toString(true));
    smf.setMessageProperties(props);
    return smf;
  }

1.2。在同一个 class 上,我使用定义的消息工厂为 soap 客户端配置了 bean:

@Bean
public WebServiceClient tClient() {
    return CitrusEndpoints.soap().client().keepSoapEnvelope(true)
                        .timeout(60000)
                        .messageFactory(messageFactory())
                        .build();
}

2.1。在我的测试 class 中,我使用 ContextConfiguration 注释来引用我创建的 class,加上 CitrusEndpointWebServiceClientConfig 注释:

@ContextConfiguration(classes = { TestConfig.class })
public class MyTest extends TestNGCitrusTestDesigner  {

    @CitrusEndpoint
    @WebServiceClientConfig(requestUrl = "http://localhost:8880/WS.asmx")
    private WebServiceClient soapclient;

2.2。然后是使用配置的客户端的问题:

 soap().client(soapclient)
.send().messageType("XML")
.name("testsend")
.payload(new ClassPathResource("com/i/B.xml"));

之后我确认请求正在发送 xml 声明标记并且服务器正在接受请求。

柑橘-context.xml 配置(新):

在 citrus-context.xml 上,配置消息工厂时插入一个 属性,名称为 messageProperties,类型为 map 并插入 属性 javax.xml.soap.write-xml-声明 并将其设置为 true ( POJO 我们使用 WRITE_XML_DECLARATION,在 citrus-context 中我们直接使用 属性):

<bean id="soapMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
    <property name="soapVersion">
        <util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11" />
    </property>
    <property name="messageProperties">
        <util:map>
            <entry key="javax.xml.soap.write-xml-declaration" value="true"/>
        </util:map>
    </property>
</bean>