17370845950

解决CXF生成SOAP客户端时缺失ObjectFactory的问题

本文旨在解决使用CXF 3.4.2 Maven插件生成SOAP客户端存根时,遇到的No ObjectFactory with an @XmlElementDecl错误。该错误通常发生在尝试创建服务存根时,提示缺少与特定XML元素关联的ObjectFactory。本文将提供详细的解决方案,通过配置命名空间映射,避免与其他客户端生成的代码冲突,从而解决此问题。

问题描述

在使用CXF Maven插件生成SOAP客户端代码后,在初始化服务时可能会遇到类似以下的错误信息:

There's no ObjectFactory with an @XmlElementDecl for the element {http://tempuri.org/}travelDocumentNumber.
this problem is related to the following location:
    at protected javax.xml.bind.JAXBElement org.tempuri.GetActiveVisasForArrival.travelDocumentNumber
    at org.tempuri.GetActiveVisasForArrival

即使ObjectFactory中已经存在对应的声明,例如:

@XmlElementDecl(namespace = "http://tempuri.org/", name = "travelDocumentNumber", scope = GetActiveVisasForArrival.class)
public JAXBElement createGetActiveVisasForArrivalTravelDocumentNumber(String value) {
    return new JAXBElement(_GetActiveVisasForArrivalTravelDocumentNumber_QNAME, String.class, GetActiveVisasForArrival.class, value);
}

该错误仍然会发生。这通常表明命名空间和Java包之间存在冲突。

解决方案:配置命名空间映射

解决此问题的关键在于确保WSDL中定义的XML命名空间与生成的Java包之间存在明确的映射关系。通过在CXF Maven插件配置中添加命名空间映射,可以避免命名冲突,从而解决No ObjectFactory错误。

在pom.xml文件中,找到CXF Maven插件的配置,并添加元素来指定命名空间与Java包的映射关系。


    org.apache.cxf
    cxf-codegen-plugin
    3.4.2
    
        
            generate-sources
            generate-sources
            
                ./generated/cxf
                
                    
                        ./src/main/resources/wsdl/evisa.wsdl
                        BorderManagementSystemService
                        
                            -client
                            -verbose
                            
                            -p
                            http://tempuri.org/=rw.gov.dgie.gk.integration.evisa.client
                            -p
                            http://schemas.migration.gov.rw/evisa=rw.gov.dgie.gk.integration.evisa
                        
                    
                
            
            
                wsdl2java
            
        
    

解释:

  • -p 参数用于指定命名空间与Java包的映射关系。
  • http://tempuri.org/=rw.gov.dgie.gk.integration.evisa.client 表示将 http://tempuri.org/ 命名空间映射到 rw.gov.dgie.gk.integration.evisa.client Java包。
  • http://schemas.migration.gov.rw/evisa=rw.gov.dgie.gk.integration.evisa 表示将 http://schemas.migration.gov.rw/evisa 命名空间映射到 rw.gov.dgie.gk.integration.evisa Java包。

重要提示:

  • 请根据您的WSDL文件和项目结构,替换示例中的命名空间和Java包名称。
  • 确保为WSDL中所有相关的命名空间都定义了映射关系。

服务初始化

在配置了命名空间映射后,重新生成客户端代码,并按照以下方式初始化服务:

service = (IBorderManagementSystemService) new BorderManagementSystemService(new URL(WSDL_LOCATION)).getBasicHttpBindingIBorderManagementSystemService();

总结

通过配置CXF Maven插件中的命名空间映射,可以有效地解决No ObjectFactory with an @XmlElementDecl错误,确保生成的SOAP客户端代码能够正确地与服务端进行交互。在遇到类似问题时,请仔细检查WSDL文件中的命名空间,并确保它们与生成的Java包之间存在清晰的映射关系。 避免由于命名冲突导致的问题,提高代码的可维护性和可靠性。