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

查看:134
本文介绍了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 arg to 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");

我很确定应该没有问题指向存储在网络中的jar内的资源/ example / resources包,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加载WSDL还是从文件或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处理程序和自己的前缀,否则不能在WSDL中具有跨JAR运行的导入基于类路径的导入解析。如果您的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天全站免登陆