使用不断变化的targetNamespace与SOAP Web服务进行通信

时间:2015-04-15 16:55:28

标签: java web-services soap namespaces jax-ws

所以有一个SOAP Web服务。 WSDL中的 targetNamespace 会根据客户的可配置字符串动态更改。把它想象成

targetNamespace="http://myservice."+ [CouldBeAnyString] + "domain.com"

我有两个问题:

  1. 我的基础研究告诉我,这是一个非常奇怪(糟糕的)开发Web服务的实践。想法?

  2. 如何为这样的网络服务编写客户端?我已经使用jax-ws存根进行了测试,当targetNamespace更改时它不兼容。还有其他建议吗?我一直在尝试理解基于wsdl的动态客户端生成。如果存在的话,会更喜欢更好的路径

  3. 更新: 我只是客户。服务由其他人提供。 同一客户有多个环境(例如测试,生产),其中服务托管在不同的targetNamespaces

3 个答案:

答案 0 :(得分:0)

如果即使targetNamespace发生更改,SOAPUI调用仍然有效,您可以使用名为HTTPCLIENT的轻量级HTTP库。

使用此库,您不需要生成客户端,因为您将SOAP envelope作为字符串发送,就像通过 SOAPUI 一样。

缺点是使用字符串。

答案 1 :(得分:0)

理论上,创建这样的Web服务客户端是可行的。 步骤进行:

  • 使用JDK的wsimport.exe基于WSDL创建Java工件(请参阅:http://www.mkyong.com/webservices/jax-ws/jax-ws-wsimport-tool-example作为参考)
  • 出于下面显示的代码的目的,我使用了Microsoft提供的Calculator WSDL
  • 创建一个"动态Web项目"通过Eclipse J2EE
  • 复制步骤1中创建的Java工件,在步骤#2中创建的项目的src文件夹下。
  • 创建一个包含main方法的新类。通常你会有类似的东西:
String wsdlLocation = "127.0.0.1:8088";//Normally you should retrieve that value dynamically
Url url = new URL(wsdlLocation + "?wsdl");// ?wsdl is actually needed
String namespaceURI = "http://Example.org";//Normally you should retrieve that value dynamically
String localPart = "CalculatorService";// as specified in WSDL file (see name attribute of service tag)
QName qname = new QName(namespaceURI, localPart);
CalculatorService service = new CalculatorService(url,qname);
ICalculator iCalculator = service.getICalculator();
int response = iCalculator.add(1, 2);
System.out.println(response);

现在是棘手的部分:

  • 如果您已按照上述WSDL的示例进行操作,那么现在应该有几个具有硬编码命名空间的Annotated Classes(例如,ICalculator注释为:
      

    @WebResult(name =" result",targetNamespace =" ..."))// where ...类似于http:// example .org

  • 使用Java反射在运行时修改所有硬编码值(请参阅此处的示例:https://stackoverflow.com/a/14276270/2625635如何修改注释)

上述解决方案应该可以解决问题。

答案 2 :(得分:0)

大多数客户端框架允许您创建用于调用客户端的接口(即,它们创建合同接口)。它们还为该接口提供了一个实现,它是具有特定注释或扩展“SOAP感知”类的实现,而接口则没有这些细节。

根据您发布的内容,我假设客户端具有相同的接口,它只是实现名称空间不同?如果是,则编写应用程序以使用该接口,然后为每个环境的实现构建一个jar。在测试服务器上部署时,使用测试jar进行部署,同时使用生产jar进行生产部署(即根据环境为同一合同选择不同的实现)。

即使您使用的框架没有为您创建界面,您也可以自己创建一个界面并隐藏某种adapter背后的各种实现。

你也可以做一些像edubriguenti建议的东西,但我不会像使用字符串一样。请改为使用SAAJ