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

WebSphere 9中SOAP客户端首调成功后续失败的UnmarshalException问题

问题:WebSphere 9.0.5.13中SOAP客户端首次调用正常,后续调用反序列化失败

现象与异常信息

首次调用WebService服务正常,但后续所有调用均抛出反序列化异常:

[javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.mycompany.com", local:"MyOCRFileRequestRs"). Expected elements are (none)]

当前环境配置

  • 应用类加载器设置为parent last(父类最后)
  • 已添加JVM参数:-Djavax.xml.bind.JAXBContext=com.sun.xml.internal.bind.v2.ContextFactory
  • 尝试添加JVM自定义属性com.ibm.xml.xlxp.jaxb.opti.level=0,问题仍未解决

核心调用代码

private MyOCRFileRequestRsType callMyOCRService(MyOCRFileRequestRqType MyOCRRequest) throws Exception {
        String headerValue = "Bearer "+MyTokenClient.getToken();
        MyOCRFileRequest port= esbOcrSerice.getMyOCRFileRequestSOAP11();
        Map<String, Object> requestContext = ((BindingProvider) port).getRequestContext();

        requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,ConfigManager.getMyOCRRequestUrl().split("[?]")[0]);
        requestContext.put("javax.xml.ws.http.request.headers", 
            Collections.singletonMap("Authorization", Collections.singletonList(headerValue)));
        
        try {
            return port.MyOCRFileRequest(MyOCRRequest);
        } catch (Exception e) {
                throw e;
        }
}

相关接口定义

@WebService(name = "MyOCRFileRequest", targetNamespace = "http://www.mycompany.com")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@XmlSeeAlso({
    ObjectFactory.class
})
public interface MyOCRFileRequest {


    /**
     * 
     * @param MyOCRFileRequestRq
     * @return
     *     returns com.mycompany.idrak.MyOCRFileRequestRsType
     */
    @WebMethod(operationName = "MyOCRFileRequest", action = "MyOCRFileRequest")
    @WebResult(name = "MyOCRFileRequestRs", targetNamespace = "http://www.mycompany.com", partName = "MyOCRFileRequestRs")
    public MyOCRFileRequestRsType MyOCRFileRequest(
        @WebParam(name = "MyOCRFileRequestRq", targetNamespace = "http://www.mycompany.com", partName = "MyOCRFileRequestRq")
        MyOCRFileRequestRqType MyOCRFileRequestRq);

}

相关实体类定义

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MyOCRFileRequestRs_Type", propOrder = {
    "msgRsHdr",
    "body"
})
public class MyOCRFileRequestRsType {

    @XmlElement(name = "MsgRsHdr", required = true)
    protected MsgRsHdrType msgRsHdr;
    @XmlElement(name = "Body")
    protected MyOCRFileRequestRsBodyType body;

    public MsgRsHdrType getMsgRsHdr() {
        return msgRsHdr;
    }

    public void setMsgRsHdr(MsgRsHdrType value) {
        this.msgRsHdr = value;
    }

    public MyOCRFileRequestRsBodyType getBody() {
        return body;
    }


    public void setBody(MyOCRFileRequestRsBodyType value) {
        this.body = value;
    }
}

解决方案:调整WebSphere配置及代码优化

1. 修正JAXB上下文类加载器隔离

在WebSphere控制台中进入应用的类加载器设置页面:

  • 开启**"为应用使用隔离类加载器"**(对应英文:Use an isolated class loader for this application)
  • 确保应用自身的JAXB实现类(com.sun.xml.bind.*)优先加载,避免与WebSphere内置JAXB组件冲突

2. 调整JVM参数,指定正确的JAXB上下文工厂

替换原有的JAXBContext参数为:

-Djavax.xml.bind.JAXBContextFactory=com.sun.xml.bind.v2.ContextFactory

注:原参数javax.xml.bind.JAXBContext为旧版配置,WebSphere对javax.xml.bind.JAXBContextFactory的识别更准确。

3. 禁用WebSphere的JAXB上下文缓存

保留com.ibm.xml.xlxp.jaxb.opti.level=0的同时,添加以下JVM参数:

-Dcom.ibm.ws.jaxb.cache.context=false

该参数会阻止WebSphere复用错误的JAXB上下文实例,避免后续调用时出现反序列化匹配问题。

4. 代码优化:复用Port实例并重置上下文

当前代码每次调用创建新Port实例,可能引发类加载上下文混乱。可将Port实例缓存为线程安全的单例,并在每次调用时重置请求上下文:

// 线程安全的单例Port缓存
private static volatile MyOCRFileRequest cachedPort;

private MyOCRFileRequestRsType callMyOCRService(MyOCRFileRequestRqType MyOCRRequest) throws Exception {
    String headerValue = "Bearer "+MyTokenClient.getToken();
    MyOCRFileRequest port;
    
    // 双重检查锁定创建单例Port
    if (cachedPort == null) {
        synchronized (this.getClass()) {
            if (cachedPort == null) {
                port = esbOcrSerice.getMyOCRFileRequestSOAP11();
                cachedPort = port;
            } else {
                port = cachedPort;
            }
        }
    } else {
        port = cachedPort;
    }

    Map<String, Object> requestContext = ((BindingProvider) port).getRequestContext();
    // 重置请求地址和头部,避免复用旧数据
    requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, ConfigManager.getMyOCRRequestUrl().split("[?]")[0]);
    requestContext.put("javax.xml.ws.http.request.headers", 
        Collections.singletonMap("Authorization", Collections.singletonList(headerValue)));
    
    try {
        return port.MyOCRFileRequest(MyOCRRequest);
    } catch (Exception e) {
        throw e;
    }
}

5. 验证ObjectFactory的元素映射

确保wsimport生成的ObjectFactory类包含MyOCRFileRequestRs元素的正确映射,示例如下:

@XmlElementDecl(namespace = "http://www.mycompany.com", name = "MyOCRFileRequestRs")
public JAXBElement<MyOCRFileRequestRsType> createMyOCRFileRequestRs(MyOCRFileRequestRsType value) {
    return new JAXBElement<MyOCRFileRequestRsType>(_MyOCRFileRequestRs_QNAME, MyOCRFileRequestRsType.class, null, value);
}

若缺少该映射,需重新生成客户端代码,确保WSDL的命名空间和元素名称与实体类注解完全匹配。


内容的提问来源于stack exchange,提问作者Mahmoud Saleh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 15:44:54