JAX-WS 从 jar 加载 WSDL [英] JAX-WS Loading WSDL from jar

查看:26
本文介绍了JAX-WS 从 jar 加载 WSDL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个胖客户端,它使用 SOAP 服务来实现某些功能(错误报告等)

I'm writing a fat client that makes use of a SOAP service for some features (bug reporting etc.)

我的 JAX-WS 工作正常,但默认情况下(至少在 netbeans 中)每次服务初始化时它都会从远程服务器获取 WSDL.我希望这有助于提供一些版本支持等,但这不是我想要的.

I've got JAX-WS working fine, but by default (in netbeans at least) it fetches the WSDL from the remote server every time the service is initialized. I expect this helps provide some versioning support etc., but it's not what I want.

我已将 wsdllocation 参数添加到 wsimport 以将生成的类指向本地资源.以下代码段是从 ApplicationService.java 加载 WSDL 资源的 URL.

I've added the wsdllocation arg to wsimport to point the generated classes to a local resource. The following snippet is the URL loading for the WSDL resource from ApplicationService.java.

baseUrl = net.example.ApplicationService.class.getResource(".");
url = new URL(baseUrl, "service.wsdl");

我很确定指向存储在 net/example/resources 包中的 jar 中的资源应该没有问题,并且 jar 本身是按预期构造的.但是该服务不会加载......具体来说,当我调用 ApplicationService.getPort(); 时,我得到一个 NullPointerException;

I'm pretty sure that should have no problems pointing to a resource stored inside a jar in the net/example/resources package, and the jar itself is constructed as expected. However the service will not load... specifically, I get a NullPointerException when I call ApplicationService.getPort();

这可能吗?还是只是一场野鹅追逐?

Is this possible? or just a wild goose chase?

推荐答案

是的,这绝对是可能的,因为我在通过 javax.xml.ws.EndpointReference(一个 WS-A 相关类)创建客户端时已经做到了.我已经将 WSDL 的类路径引用添加到 WS-A EndPointReference 并且 JAX-WS 的 Metro 实现加载它就好了.无论是从 WS-A EndPointReference 还是从文件或 http URL 加载 WSDL,您的 JAX-WS 实现都应该使用相同的 WSDL 解析代码,因为您所做的只是解析 URL.

Yes this is most definitely possible as I have done it when creating clients through javax.xml.ws.EndpointReference, a WS-A related class. I have added a classpath reference to the WSDL to the WS-A EndPointReference and the Metro implementation of JAX-WS loaded it just fine. Whether loading the WSDL from the WS-A EndPointReference or from a file or http URL, your JAX-WS implementation should use the same WSDL parsing code as all you are doing is resolving URLs.

最适合您的方法可能是执行以下操作:

The best approach for you is probably to do something like the following:

URL wsdlUrl = MyClass.class.getResource(
            "/class/path/to/wsdl/yourWSDL.wsdl");

Service yourService= Service.create(
            wsdlUrl,
            ...);

其中 ... 表示 WSDL 中 WSDL 服务的 QName.现在要记住的重要一点是您的 WSDL 需要完整且有效.这意味着如果您的 WSDL 导入 XSD 文件或其他 WSDL,则 URL 必须正确.如果您将导入的 WSDL 和 XSD 包含在与 WSDL 文件相同的 JAR 中,您应该使用相对 URL 进行导入并将所有导入保存在同一个 JAR 文件中.JAR URL 处理程序不会将相对 URL 视为相对于类路径的相对 URL,而是相对于 JAR 文件中的相对 URL,因此除非您实现自定义 URL 处理程序和您自己的前缀,否则您不能在跨 JAR 的 WSDL 中导入基于类路径的导入解析.如果您的 WSDL 导入外部资源,那没问题,但是如果这些资源移动了,您就会为维护问题而签名.即使使用类路径中 WSDL 的静态副本也有悖于 WSDL、Web 服务和 JAX-WS 的精神,但有时也需要这样做.

Where ... represents the QName of a WSDL service inside of your WSDL. Now the important thing to remember is that your WSDL needs to be complete and valid. This means that if your WSDL imports XSD files or other WSDLs, the URLs must be correct. If you included your imported WSDL and XSDs in the same JAR as the WSDL file, you should use relative URLs for the imports and keep all of your imports in the same JAR file. The JAR URL handler does not treat the relative URLs as relative with respect to the classpath but rather to relative within the JAR file so you cannot have imports in your WSDL that run across JARs unless you implement a custom URL handler and your own prefix to do classpath based resolution of the imports. If your WSDL imports external resources, that is OK, but you are signing yourself up for maintenance issues if those resources ever move. Even using a static copy of the WSDL from your classpath is contrary to the spirit of WSDL, Web services, and JAX-WS, but there are times when it is necessary.

最后,如果您嵌入静态 WSDL,我建议您至少使服务端点可配置以用于测试和部署目的.重新配置 Web 服务客户端端点的代码如下:

Finally, if you embed a static WSDL, I suggest that you at least make the service endpoint configurable for testing and deployment purposes. The code to reconfigure the endpoint of your Web service client is as follows:

  YourClientInterface client = yourService.getPort(
            new QName("...", "..."),
            YourClientInterface.class);
  BindingProvider bp = (BindingProvider) client;
  bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
                "http://localhost:8080/yourServiceEndpoint");

这篇关于JAX-WS 从 jar 加载 WSDL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆