Cog*_*gsy 44 wsdl jar jax-ws wsimport
我正在编写一个胖客户端,它利用SOAP服务来实现某些功能(错误报告等)
我有JAX-WS工作正常,但默认情况下(至少在netbeans中)它每次初始化服务时从远程服务器获取WSDL.我希望这有助于提供一些版本支持等,但这不是我想要的.
我已将wsdllocationarg 添加到wsimport以将生成的类指向本地资源.以下代码段是ApplicationService.java中WSDL资源的URL加载.
baseUrl = net.example.ApplicationService.class.getResource(".");
url = new URL(baseUrl, "service.wsdl");
Run Code Online (Sandbox Code Playgroud)
我很确定在net/example/resources包中指向存储在jar中的资源应该没有问题,并且jar本身按预期构造.但是服务不会加载...具体来说,当我调用ApplicationService.getPort()时,我得到一个NullPointerException;
这可能吗?还是只是一场疯狂的追逐?
Dav*_*eri 48
是的,这绝对是可能的,因为我在通过javax.xml.ws.EndpointReference(一个与WS-A相关的类)创建客户端时已经这样做了.我已经将WSDL的类路径引用添加到WS-A EndPointReference,并且JAX-WS的Metro实现加载它就好了.无论是从WS-A EndPointReference还是从文件或http URL加载WSDL,您的JAX-WS实现应使用相同的WSDL解析代码,因为您所做的只是解析URL.
对您而言,最好的方法可能是执行以下操作:
URL wsdlUrl = MyClass.class.getResource(
"/class/path/to/wsdl/yourWSDL.wsdl");
Service yourService= Service.create(
wsdlUrl,
...);
Run Code Online (Sandbox Code Playgroud)
where ...表示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的精神,但有时候它是必要的.
最后,如果您嵌入了静态WSDL,我建议您至少使服务端点可配置用于测试和部署目的.重新配置Web服务客户端的端点的代码如下:
YourClientInterface client = yourService.getPort(
new QName("...", "..."),
YourClientInterface.class);
BindingProvider bp = (BindingProvider) client;
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://localhost:8080/yourServiceEndpoint");
Run Code Online (Sandbox Code Playgroud)
Ada*_*ent 14
如果您将WSDL放在JAR中,然后将wsimport设置为JAR中WSDL wsdlLocation的相对资源路径,则最近的JAX-WS您不需要执行任何模式目录或编程的wsdl位置设置.那就是JAX-WS使用Java的内置Class.getResource来加载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>
<!-- Following configuration will invoke wsimport once for each wsdl. -->
<configuration>
<!--- VERY IMPORTANT THAT THE PATH START WITH '/' -->
<wsdlLocation>/com/adamgent/ws/blah.wsdl</wsdlLocation>
<wsdlDirectory>${basedir}/src/main/resources/com/adamgent/ws</wsdlDirectory>
<wsdlFiles><wsdlFile>blah.wsdl</wsdlFile></wsdlFiles>
</configuration>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
对于上面的示例,您将在此处使用Maven项目布局放置WSDL src/main/resources/com/adamgent/ws.
确保WSDL进入Maven的JAR,如:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources> ....
Run Code Online (Sandbox Code Playgroud)
现在你的wsimport生成的代码和WSDL都在一个自包含的JAR中.要使用该服务,您不必设置WSDL位置,并且非常简单:
BlahService myService = new BlayService_Service().getBlahServicePort();
Run Code Online (Sandbox Code Playgroud)
将此映射到ANT的wsimport应该是微不足道的.
也许有点晚了,但我找到了一个非常简单的解决方案来解决这个问题,但这涉及到Service类生成代码的变化:
如果Service类中有以下行
baseUrl = net.example.ApplicationService.class.getResource(".");
Run Code Online (Sandbox Code Playgroud)
改为
baseUrl = net.example.ApplicationService.class.getResource("");
Run Code Online (Sandbox Code Playgroud)
即使使用JAR中打包的WSDL,它也能正常工作.在这两种情况下都不确定getResource()的确切假设行为,但到目前为止,我在多个操作系统和Java版本上没有遇到任何问题.
您所描述的是JAX-WS中的错误:JAX_WS-888 - 用于解析自定义wsdlLocation的URL的错误代码.
它已针对V2.2进行了修复,因此在wsdlLocation您编写时,只需进行设置即可.
这是我的 hack-y 解决方法。
我从 jar 中解压 WSDL 并将其写入 jar 附近的文件中:
File wsdl = new File("../lib/service.wsdl");
InputStream source = getClass().getResource("resources/service.wsdl").openStream();
FileOutputStream out = new FileOutputStream(wsdl);
byte[] buffer = new byte[512];
int read;
while((read = source.read(buffer)) >= 0) {
out.write(buffer, 0, read);
}
Run Code Online (Sandbox Code Playgroud)
然后将服务类指向file:../lib/service.wsdl。
这可行,但如果有人能向我展示更优雅的解决方案,我将不胜感激。