绑定定制生成Java类后,JaxWsProxyFactoryBean创建SOAP客户端报错咨询
解决JAX-WS客户端与自定义JAXB绑定类型不匹配的问题
看起来你遇到的核心问题是:JAX-WS客户端在解析WSDL时,默认期望匹配原始的类型名称,但你通过绑定文件给生成的Java类加了Type后缀,导致系统找不到对应的映射关系。下面给你几个可行的解决方案:
方案1:使用绑定文件生成完整的客户端代码(推荐)
不要手动用JaxWsProxyFactoryBean绑定原始接口,而是直接用wsimport(或Maven的jaxws-maven-plugin)结合你的绑定文件生成全套客户端代码,包括服务类、端口接口和类型类。生成的代码会自动处理类型与WSDL元素的映射,无需额外配置。
举个Maven插件的配置示例(你可以根据自己的项目调整路径):
<plugin> <groupId>org.jvnet.jax-ws-commons</groupId> <artifactId>jaxws-maven-plugin</artifactId> <version>2.3</version> <executions> <execution> <goals> <goal>wsimport</goal> </goals> <configuration> <wsdlUrls> <wsdlUrl>你的WSDL路径</wsdlUrl> </wsdlUrls> <bindingFiles> <bindingFile>你的绑定文件路径</bindingFile> </bindingFiles> <packageName>ru.spi2.javaee.custom.pravoru.classes.egrul</packageName> </configuration> </execution> </executions> </plugin>
生成代码后,直接用生成的服务类创建客户端:
// 生成的服务类 WebServiceService service = new WebServiceService(); WebService port = service.getWebServicePort(); // 设置实际服务地址(如果和WSDL里的地址不同) ((BindingProvider) port).getRequestContext() .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WSDL_URL);
这种方式最稳妥,因为生成的代码已经完全遵循你的绑定规则,不会出现类型不匹配的问题。
方案2:手动给JaxWsProxyFactoryBean配置自定义JAXB上下文
如果你一定要用JaxWsProxyFactoryBean,需要明确告诉它你的自定义JAXB上下文,让系统能找到带Type后缀的类。
步骤如下:
- 确保你使用绑定文件生成的
WebService接口是正确的(接口里的方法参数应该引用带Type后缀的类,比如SearchMagistratesCourtRequestType) - 创建包含你自定义类型包的JAXB上下文,设置到代理工厂:
// 初始化JAXB上下文,指定你的类型所在包 JAXBContext jaxbContext = JAXBContext.newInstance("ru.spi2.javaee.custom.pravoru.classes.egrul"); JaxWsProxyFactoryBean portFactory = new JaxWsProxyFactoryBean(); portFactory.setAddress(WSDL_URL); portFactory.setServiceClass(WebService.class); // 绑定自定义JAXB上下文 portFactory.setJaxbContext(jaxbContext); webService = (WebService) portFactory.create();
方案3:调整绑定文件,避免不必要的元素名称修改
你在绑定文件里设置了elementName suffix="Element",但自己也说这个配置不需要。这个设置会修改WSDL元素对应的Java类名,反而会导致JAX-WS无法匹配原始的WSDL元素名,建议移除这一行:
<jaxb:bindings schemaLocation="../xsd/egrul.xsd"> <jaxb:schemaBindings> <jaxb:package name="ru.spi2.javaee.custom.pravoru.classes.egrul"/> <jaxb:nameXmlTransform> <jaxb:typeName suffix="Type"/> <!-- 移除下面这行,保持元素名称与WSDL一致 --> <!-- <jaxb:elementName suffix="Element"/> --> </jaxb:nameXmlTransform> </jaxb:schemaBindings> </jaxb:bindings>
修改后重新生成Java类,这样WSDL里的元素名(比如SearchMagistratesCourtRequest)就能通过生成的ObjectFactory正确映射到SearchMagistratesCourtRequestType类。
内容的提问来源于stack exchange,提问作者Kirill
相关产品推荐
相关产品推荐

