You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用WebService时JAXBElement无法转为ShowPendingFilesResponse异常

问题:WebService空响应编组失败,抛出JAXBElement类型转换异常

调用WebService后返回200 OK,响应XML是无待下载文件的正确空结构,但Spring的marshalSendAndReceive方法无法正确编组响应,抛出javax.xml.bind.JAXBElement cannot be cast to download.iris.models.ShowPendingFilesResponse异常。

相关代码及响应信息

请求代码

JAXBElement<ShowPendingFiles> jAXBElement = new ObjectFactory().createShowPendingFiles(showPendingFilesRequest);

CustomEnvelopeDetails customEnvelopeDetails = new CustomEnvelopeDetails(
    CcrConstants.ACTION_PENDING_FILES,
    new SecurityHeader(isSecurityEnabled, username, password)
        );

final Object marshalled = (ShowPendingFilesResponse) createServiceTemplate(jaxb2Marshaller)
//return (ShowPendingFilesResponse) createServiceTemplate(jaxb2Marshaller)
    .marshalSendAndReceive(soapServer, jAXBElement,
          new SoapRequestHeaderModifier(customEnvelopeDetails));
return (ShowPendingFilesResponse) marshalled;

响应XML

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <ns2:showPendingFilesResponse
            xmlns:ns2="http://iris.somewhere.com/web_services/external/downloadFile"
            xmlns:ns3="http://iris.somewhere.gr/web_services/external/uploadFile"/>
    </soapenv:Body>
</soapenv:Envelope>

WSDL自动生成的ShowPendingFilesResponse类

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "showPendingFilesResponse", propOrder = {
    "showPendingFilesResult"
})
public class ShowPendingFilesResponse {

    @XmlElement(nillable = true)
    protected List<TransferableFile> showPendingFilesResult;

   
    public List<TransferableFile> getShowPendingFilesResult() {
        if (showPendingFilesResult == null) {
            showPendingFilesResult = new ArrayList<TransferableFile>();
        }
        return this.showPendingFilesResult;
    }

}

原因分析

  • 当响应XML中的根元素(showPendingFilesResponse)没有子元素时,JAXB会将其封装为JAXBElement<ShowPendingFilesResponse>实例,而非直接返回ShowPendingFilesResponse对象
  • 自动生成的ShowPendingFilesResponse类缺少@XmlRootElement注解,导致JAXB无法直接将空元素映射为实体类实例,只能通过JAXBElement进行包装

解决方案

方案1:直接处理返回的JAXBElement

修改代码,先判断返回对象的类型,再提取内部的实体实例:

final Object marshalled = createServiceTemplate(jaxb2Marshaller)
    .marshalSendAndReceive(soapServer, jAXBElement, new SoapRequestHeaderModifier(customEnvelopeDetails));

if (marshalled instanceof JAXBElement) {
    return ((JAXBElement<ShowPendingFilesResponse>) marshalled).getValue();
} else {
    return (ShowPendingFilesResponse) marshalled;
}

方案2:给实体类添加@XmlRootElement注解

如果允许修改自动生成的实体类,添加@XmlRootElement注解,注意命名空间要和响应XML中的ns2一致:

@XmlRootElement(name = "showPendingFilesResponse", namespace = "http://iris.somewhere.com/web_services/external/downloadFile")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "showPendingFilesResponse", propOrder = {
    "showPendingFilesResult"
})
public class ShowPendingFilesResponse {
    // 原有代码保持不变
}

方案3:配置Jaxb2Marshaller支持JAXBElement

在创建Jaxb2Marshaller实例时,设置supportJaxbElementClass属性为true,让Marshaller自动处理JAXBElement包装:

Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setSupportJaxbElementClass(true);
marshaller.setContextPath("download.iris.models"); // 替换为你的实体类上下文路径
// 其他必要配置

内容的提问来源于stack exchange,提问作者Grafana Next

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:25:34