如何更改网络服务 url 端点?

Posted

技术标签:

【中文标题】如何更改网络服务 url 端点?【英文标题】:How to change webservice url endpoint? 【发布时间】:2011-01-30 05:59:27 【问题描述】:

我使用 JBoss utils(与 JAX-WS 兼容)生成了一个 Web 服务客户端 使用 Eclipse '来自 wsdl 的 Web 服务客户端'。

所以,我提供的唯一东西就是一个 Web 服务 WSDL 的 URL。

现在,网络服务提供商告诉我更改网络服务的“客户端端点应用程序访问的 URL”。

它是什么以及如何改变它?

【问题讨论】:

你能用同一个 Eclipse 向导和新的 URL 重新创建这个东西吗? 告诉 Web 服务提供商您需要 wsdl 的新 url,然后使用 Eclipse 向导重新生成客户端。 @Thilo @systemputoout 伙计们,问题是他们有相同的 WSDL URL!我不确定,但在我看来,在 Axis 中,您可以在调用 Web 服务时提供 URL。在 JAX-WS 中,您不能更改“运行时客户端端点”。有什么想法吗,伙计们? @Pascal Thivent, @systempuntoout 引用:“用于客户端应用程序访问的 URL 或端点” 嗯,我对这句话的理解是“客户端访问一个服务端点;端点位置发生了变化”。这是有道理的。 【参考方案1】:

IMO,提供商告诉您更改服务端点(即到达 Web 服务的位置),而不是客户端端点(我不明白这可能是什么)。要更改服务端点,您基本上有两种选择。

使用 Binding Provider 设置端点 URL

第一种选择是更改BindingProviderBindingProvider.ENDPOINT_ADDRESS_PROPERTY属性值(每个代理都实现javax.xml.ws.BindingProvider接口):

...
EchoService service = new EchoService();
Echo port = service.getEchoPort();

/* Set NEW Endpoint Location */
String endpointURL = "http://NEW_ENDPOINT_URL";
BindingProvider bp = (BindingProvider)port;
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);

System.out.println("Server said: " + echo.echo(args[0]));
...

缺点是这仅在原始 WSDL 仍可访问时才有效。不推荐。

使用 WSDL 获取端点 URL

第二个选项是从 WSDL 获取端点 URL。

...
URL newEndpoint = new URL("NEW_ENDPOINT_URL");
QName qname = new QName("http://ws.mycompany.tld","EchoService"); 

EchoService service = new EchoService(newEndpoint, qname);
Echo port = service.getEchoPort();

System.out.println("Server said: " + echo.echo(args[0]));
...

【讨论】:

我认为第二个代码块有错误,不应该是URL newEndpoint = new URL("WSDL_URL");在第一行?? 这里是一个教程链接tugdualgrall.blogspot.com/2009/02/… 值得指出的是,现代wsimport 工具不再使用get[Service]Port 方法生成代码。相反,调用get[Service] 并将生成的对象转换为BindingProvider 以设置这些类型的属性。 感谢 @ChristopherSchultz 提供的 wsimport 提示!那个定义。为我们工作 据我了解,从 cxf 生成的存根代码,上面的第二个选项更改 wsdl url,而不是服务 url。我错过了什么吗?【参考方案2】:

为了在此处添加一些说明,当您创建服务时,服务类使用默认的“wsdlLocation”,它是在从 wsdl 构建类时插入其中的。因此,如果您有一个名为 SomeService 的服务类,并且您创建了一个这样的实例:

SomeService someService = new SomeService();

如果您查看 SomeService 内部,您会看到构造函数如下所示:

public SomeService() 
        super(__getWsdlLocation(), SOMESERVICE_QNAME);

因此,如果您希望它指向另一个 URL,您只需使用带有 URL 参数的构造函数(还有 6 个构造函数用于设置 qname 和 features)。例如,如果您设置了一个正在侦听端口 9999 的本地 TCP/IP 监视器,并且您希望重定向到该 URL:

URL newWsdlLocation = new URL("http://theServerName:9999/somePath");
SomeService someService = new SomeService(newWsdlLocation);

这将在服务内部调用这个构造函数:

public SomeService(URL wsdlLocation) 
    super(wsdlLocation, SOMESERVICE_QNAME);

【讨论】:

不一定。我有使用 Apache CXF 的 wsdl2java 生成的服务,即使我们将新的 wsdl 位置传递给构造函数,它的端口仍然尝试绑定到在编译/生成时设置的位置(除了将端口类型转换为 BindingProvider 和在其请求上下文映射中设置新地址。) @Luis - 很难确切知道你看到了什么,但如果你调试你应该看到对 javax Provider 类的调用,然后看到它尝试用你的新 wsdl 位置创建端点(假设您使用的是 JAX-WS 2.0+)。然后在您的服务内部,getPort 调用应该调用 super.getPort,它使用在 serviceDelegate 对象中设置您的新端口。这就是它应该如何在 JAX-WS 2.0 中与 javax.xml.ws.Service 一起工作。我会在超级调用上设置一个断点并从那里进行调查。 @MattC - 即使我们动态更改 URL,我们添加到项目中的 WSDL URL 是否始终需要可访问?你能分享一下这种行为吗?【参考方案3】:

我不会像@Femi 那样更改现有的地址属性。您可以轻松地将新服务添加到定义部分。

<wsdl:service name="serviceMethodName_2">
  <wsdl:port binding="tns:serviceMethodNameSoapBinding" name="serviceMethodName">
    <soap:address location="http://new_end_point_adress"/>
  </wsdl:port>
</wsdl:service>

这不需要将 WSDL 重新编译为 Java,并且进行更新并不比使用 BindingProvider 选项更困难(顺便说一句,这对我不起作用)。

【讨论】:

【参考方案4】:

要更改结束地址属性,请编辑您的 wsdl 文件

<wsdl:definitions.......
  <wsdl:service name="serviceMethodName">
    <wsdl:port binding="tns:serviceMethodNameSoapBinding" name="serviceMethodName">
      <soap:address location="http://service_end_point_adress"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

【讨论】:

在许多情况下,WSDL 是强加给您的,您不应该更改它。更重要的是,从一个环境到另一个环境(测试与实时),端点 url 可能会发生变化。在这种情况下,没有人愿意调整 wsdl 并重新编译。

以上是关于如何更改网络服务 url 端点?的主要内容,如果未能解决你的问题,请参考以下文章

无服务器框架,API 网关 URL 何时更改?

如何使用 ZEEP 更改 SOAP 请求中的端点地址

微服务中的外部 URL 配置

防止更改 Web 服务 URL

GWT-platform 的 Dispatch 如何在 DispathcAsync 接口中指示我的服务的端点 URL?

如何在自定义 URL 上运行 Laravel mix?