我需要调用返回附件的 SOAP 服务。
定义“附加”数据的 XSD 是
<xs:complexType name="transferableFileData">
<xs:complexContent>
<xs:extension base="tns:transferableFile">
<xs:sequence>
<xs:element name="fileData" type="xs:base64Binary" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
我在 pom.xml 文件中使用此插件从 WSDL 和 XSD 文件生成类
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.15.1</version>
</plugin>
自动生成的类是这样的
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "transferableFileData", propOrder = {
"fileData"
})
public class TransferableFileData
extends TransferableFile
{
protected byte[] fileData;
public byte[] getFileData() {
return fileData;
}
public void setFileData(byte[] value) {
this.fileData = value;
}
}
服务器的响应是:
Cache-Control: max-age=0
Cache-Control: no-cache
Cache-Control: no-store
Server-Timing: ak_p; desc="1705942361025_1611673733_335963847_52691_3577_46_71_-";dur=1
Server-Timing: origin; dur=520
Server-Timing: edge; dur=7
Server-Timing: cdn-cache; desc=MISS
Connection: keep-alive
Set-Cookie: LtpaToken2=Jss03JN+gXMYTd; Path=/; HttpOnly
Expires: Mon
Expires: 22 Jan 2024 16:52:41 GMT
Pragma: no-cache
Content-Length: 2912
Content-Language: en-US
Date: Mon
Date: 22 Jan 2024 16:52:41 GMT
Content-Type: Multipart/Related; boundary="----=_Part_11_2001319686.1705942360849"; type="application/xop+xml"; start-info="text/xml"
SOAPAction: ""
Accept: text/xml
------=_Part_11_2001319686.1705942360849
Content-Type: application/xop+xml; charset=utf-8; type="text/xml"
Content-Transfer-Encoding: binary
Content-ID: <[email protected]>
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns2:downloadPendingFileResponse xmlns:ns2="http://iris.somewhere.cp,/web_services/external/downloadFile" xmlns:ns3="http://iris.somewhere.com/web_services/external/uploadFile"><downloadPendingFileResult><fileExchangeNo>1174649</fileExchangeNo><fileName>TEST00001_2024-01-22-18.46.08.00000_APA.zip</fileName><fileData><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:[email protected]"/></fileData></downloadPendingFileResult></ns2:downloadPendingFileResponse></soapenv:Body></soapenv:Envelope>
------=_Part_11_2001319686.1705942360849
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <[email protected]>
�������f��G��v�+p�,����
��K�ɁZt �K�>b�La���^m��_э���1$�t�dqV�A;�ف� F�K�� ��ކO�X![
我的Java代码是这样的:
if (response instanceof JAXBElement) {
DownloadPendingFileResponse downloadPendingFileResponse = ((JAXBElement<DownloadPendingFileResponse>) response).getValue();
if(downloadPendingFileResponse == null) {
及以后
final TransferableFileData transferableData = response.getDownloadPendingFileResult();
...
byte[] bytes = transferableData.getFileData();
log.info("length {}", bytes.length);
但是长度始终为零。看来我无法正确获取文件。
我注意到 WSDL 将 fileData 元素定义为 base64Binary,而 POJO 将它们定义为 byte[]。数据流似乎没有被整理。知道如何解决这个问题吗?
我在 WSDL 服务上获得了完全相同的 XSD
<complexType name="myType">
<sequence>
...
<element name="myFile" type="xsd:base64Binary"/>
...
</sequence>
</complexType>
这由
org.apache.cxf:cxf-codegen-plugin
: 生成
@XmlElement(required = true)
protected byte[] myFile;
但是为了进行解组,我必须将 XSLT 设置为
jaxws:feature
spring 客户端,以便告诉 CXF 理解响应中的 href
(文件 transform.xsl
的内容如下):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" >
<xsl:key name="multiref-by-id" match="multiRef" use="@id"/>
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates select="@*|*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[starts-with(@href, '#')]">
<xsl:copy>
<xsl:apply-templates select="@* |
key('multiref-by-id', substring-after(@href, '#'))/@* |
key('multiref-by-id', substring-after(@href, '#'))/node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@href[starts-with(., '#')] | multiRef[@id] | @soapenc:root"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这是在 XML Spring Config 中定义的 bean :
<bean id="xsltFeature" class="org.apache.cxf.feature.transform.XSLTFeature">
<property name="inXSLTPath" value="transform.xsl" />
<property name="outXSLTPath" value="transform.xsl" />
</bean>
<jaxws:client id="myService" serviceClass="my.web.Service" address="myurl">
<jaxws:features>
<ref bean="xsltFeature" />
</jaxws:features>
</jaxws:client>
通过这样做,我可以通过Java中的
myFile
的getter读取附件的内容,而无需额外的配置。
我认为您可以对其进行调整,以使其在您自己的应用程序上下文中工作。