创建Web服务客户端,XML元素错误

时间:2018-07-17 03:31:19

标签: java xml web-services

我正在编写一个简单的Java应用程序,以将消息发送到部署在.NET上的Web服务,但对此我无法控制,我能够创建消息并将其发送到服务,但得到500响应问题是Java创建最终XML的方式,服务器基本上希望这样:

const promises = [];
files.forEach(file => {
    const uploadTask = Storage.ref(`files/${file.name}`).put(file);
    promises.push(uploadTask);

    uploadTask.on('state_changed', snapshot => {
        const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        console.log(progress);
    }, error => { console.log(error) }, () => {
        uploadTask.snapshot.ref.getDownloadURL().then(downloadURL => {
            console.log(downloadURL);
        });
    });
});

Promise.all(promises).then(tasks => {
    console.log('all uploads complete');
});

我的代码生成如下内容:

<a:SourceSystem>FTP</a:SourceSystem>
<a:AuditDateTime>2018-07-14T15:30:06.1180404-05:00</a:AuditDateTime>
<a:AuditAttributes> <a:AuditAttribute>
<a:Name>ReceiveLocationName</a:Name>
<a:Value>UserUpload</a:Value>
</a:AuditAttribute> <a:AuditAttribute>
<a:Name>SendPortName</a:Name>
<a:Value/>
</a:AuditAttribute> <a:AuditAttribute>
<a:Name>FileSize</a:Name>
<a:Value>   0</a:Value>
</a:AuditAttribute> </a:AuditAttributes>

如您所见,第一个问题是XML元素名称被创建为“ ns6:string”,而不是像“ a:SourceSystem”之类的实际名称,并且还添加了“ Array”标签:ArrayOfAuditAttribute。

该应用是通过从WSDL自动生成调度代码创建的,因此例如,要创建第一个参数,我的代码如下:

<ns6:string>FTP</ns6:string>
<AuditDateTime>2018-07-16T21:38:35.626-05:00</AuditDateTime>
<ArrayOfAuditAttribute>
<AuditAttribute>
<ns6:string>FileSize</ns6:string>
<ns6:string>0</ns6:string>
</AuditAttribute>
<AuditAttribute>
<ns6:string>SendPortName</ns6:string>
<ns6:string></ns6:string>
</AuditAttribute>
<AuditAttribute>
</AuditAttribute>
</ArrayOfAuditAttribute>

然后将所有值都设置好,然后打包新事件:

        ObjectFactory factory = new ObjectFactory();
        JAXBElement<String> sourceSystem = factory.createString("SourceSystem");
        sourceSystem.setValue("FTP");

并提交:

        AuditEvent aEvent = new AuditEvent();
        aEvent.setSourceSystem(sourceSystem);
        aEvent.setAuditDateTime(auditDateTime);
        aEvent.setAuditAttributes(arrayAuditAttributesXML);
        aEvent.setSearchableIndexes(arraySearchableIndexXML);
        aEvent.setAuditTypeName(auditTypeName);
        JAXBElement<AuditEvent> aEventXML = factory.createAuditEvent(aEvent);

java创建元素的方式似乎是正确的:

        Long xml = svc.writeAuditEvent(aEvent);

所以我想我可能会缺少将这些名称设置在某个地方的方法,但确实如此。

很抱歉,这似乎到处都是,但我尝试提供尽可能多的信息,如果您需要更多信息,请告诉我。

谢谢

2 个答案:

答案 0 :(得分:0)

将名称空间映射器添加到编组器

        m.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper() {
            @Override
           public String getPreferredPrefix(String arg0, String arg1, boolean arg2) {
               return "a";
           }
       });

在您的实体中,将名称空间声明添加到要属于该名称空间的所有实体。例如SourceSystem元素:

@XmlElement(name = "SourceSystem", namespace = "http://schemas.datacontract.org/2004/07/RCO.Audit.Model.DataTransfer")
public String getSourceSystem() {}

对所有实体执行此操作。

答案 1 :(得分:0)

“问题”似乎是对象工厂,我最终要解决的问题是通过JAXBElement构造函数手动添加名称空间和标记名称:

        String namespace = "http://schemas.datacontract.org/2004/07/RCO.Audit.Model.DataTransfer";
        JAXBElement<String> sourceSystem = new JAXBElement<>(new QName(namespace ,"SourceSystem"), String.class, "FTP");
        JAXBElement<String> auditTypeName = new JAXBElement<>(new QName(namespace ,"AuditTypeName"), String.class, "FileDelivered");

这允许通过引用正确的名称空间来生成xml:

<ns2:WriteAuditEvent xmlns:ns6="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:ns5="http://schemas.datacontract.org/2004/07/RCO.Audit.Service" xmlns:ns4="http://schemas.datacontract.org/2004/07/RCO.Audit.Model" xmlns:ns3="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ns2="http://tempuri.org/" xmlns="http://schemas.datacontract.org/2004/07/RCO.Audit.Model.DataTransfer">
<ns2:auditEvent>
<SourceSystem>
FTP</SourceSystem>
<AuditDateTime>
2018-07-17T10:51:55.767-05:00</AuditDateTime>