81 java client netbeans jax-ws
问题是我需要从我提供的文件构建一个Web服务客户端.我已将此文件存储在本地文件系统中,并且在将WSDL文件保存在正确的文件系统文件夹中时,一切都很好.当我将其部署到服务器或从文件系统文件夹中删除WSDL时,代理无法找到WSDL并出现错误.我在网上搜索过,但我发现了以下帖子但是我无法使它工作:
JAX-WS从jar加载WSDL
http://www.java.net/forum/topic/glassfish/metro -and-jaxb/client-jar-cant-find-local-wsdl-0
http://blog.vinodsingh.com/2008/12/locally-packaged-wsdl.html
我正在使用NetBeans 6.1(这是我要用这个新的Web服务客户端更新的遗留应用程序).下面是JAX-WS代理类:
@WebServiceClient(name = "SOAService", targetNamespace = "http://soaservice.eci.ibm.com/", wsdlLocation = "file:/C:/local/path/to/wsdl/SOAService.wsdl")
public class SOAService
extends Service
{
private final static URL SOASERVICE_WSDL_LOCATION;
private final static Logger logger = Logger.getLogger(com.ibm.eci.soaservice.SOAService.class.getName());
static {
URL url = null;
try {
URL baseUrl;
baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(".");
url = new URL(baseUrl, "file:/C:/local/path/to/wsdl/SOAService.wsdl");
} catch (MalformedURLException e) {
logger.warning("Failed to create URL for the wsdl Location: 'file:/C:/local/path/to/wsdl/SOAService.wsdl', retrying as a local file");
logger.warning(e.getMessage());
}
SOASERVICE_WSDL_LOCATION = url;
}
public SOAService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public SOAService() {
super(SOASERVICE_WSDL_LOCATION, new QName("http://soaservice.eci.ibm.com/", "SOAService"));
}
/**
* @return
* returns SOAServiceSoap
*/
@WebEndpoint(name = "SOAServiceSOAP")
public SOAServiceSoap getSOAServiceSOAP() {
return super.getPort(new QName("http://soaservice.eci.ibm.com/", "SOAServiceSOAP"), SOAServiceSoap.class);
}
/**
* @param features
* A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* @return
* returns SOAServiceSoap
*/
@WebEndpoint(name = "SOAServiceSOAP")
public SOAServiceSoap getSOAServiceSOAP(WebServiceFeature... features) {
return super.getPort(new QName("http://soaservice.eci.ibm.com/", "SOAServiceSOAP"), SOAServiceSoap.class, features);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我使用代理的代码:
WebServiceClient annotation = SOAService.class.getAnnotation(WebServiceClient.class);
// trying to replicate proxy settings
URL baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource("");//note : proxy uses "."
URL url = new URL(baseUrl, "/WEB-INF/wsdl/client/SOAService.wsdl");
//URL wsdlUrl = this.getClass().getResource("/META-INF/wsdl/SOAService.wsdl");
SOAService serviceObj = new SOAService(url, new QName(annotation.targetNamespace(), annotation.name()));
proxy = serviceObj.getSOAServiceSOAP();
/* baseUrl;
//classes\com\ibm\eci\soaservice
//URL url = new URL(baseUrl, "../../../../wsdl/SOAService.wsdl");
proxy = new SOAService().getSOAServiceSOAP();*/
//updating service endpoint
Map<String, Object> ctxt = ((BindingProvider)proxy ).getRequestContext();
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);
ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WebServiceUrl);
Run Code Online (Sandbox Code Playgroud)
NetBeans在Web-inf/wsdl/client/SOAService中放置了WSDL的副本,因此我也不想将它添加到META-INF中.服务类在WEB-INF/classes/com/ibm/eci/soaservice /中,baseurl变量包含文件系统的完整路径(c:\ path\to\the\project ...\soaservice).上面的代码引发了错误:
javax.xml.ws.WebServiceException:无法访问WSDL:file:/WEB-INF/wsdl/client/SOAService.wsdl.它失败了:\ WEB-INF\wsdl\client\SOAService.wsdl(找不到路径)
那么,首先,我应该更新代理类的wsdllocation吗?那么如何告诉WEB-INF/classes/com/ibm/eci/soaservice中的SOAService类在\ WEB-INF\wsdl\client\SOAService.wsdl中搜索WSDL?
编辑:我发现了另一个链接 - http://jianmingli.com/wp/?cat=41,它说将WSDL放入类路径中.我很惭愧地问:我怎么把它放到web应用程序类路径中?
小智 111
最好的选择是使用jax-ws-catalog.xml
编译本地WSDL文件时,覆盖WSDL位置并将其设置为类似的位置
http://localhost/wsdl/SOAService.wsdl
不要担心这只是一个URI而不是一个URL,这意味着您不必在该地址上提供WSDL.
您可以通过将wsdllocation选项传递给wsdl到java编译器来完成此操作.
这样做会改变你的代理代码
static {
URL url = null;
try {
URL baseUrl;
baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(".");
url = new URL(baseUrl, "file:/C:/local/path/to/wsdl/SOAService.wsdl");
} catch (MalformedURLException e) {
logger.warning("Failed to create URL for the wsdl Location: 'file:/C:/local/path/to/wsdl/SOAService.wsdl', retrying as a local file");
logger.warning(e.getMessage());
}
SOASERVICE_WSDL_LOCATION = url;
}
Run Code Online (Sandbox Code Playgroud)
至
static {
URL url = null;
try {
URL baseUrl;
baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(".");
url = new URL(baseUrl, "http://localhost/wsdl/SOAService.wsdl");
} catch (MalformedURLException e) {
logger.warning("Failed to create URL for the wsdl Location: 'http://localhost/wsdl/SOAService.wsdl', retrying as a local file");
logger.warning(e.getMessage());
}
SOASERVICE_WSDL_LOCATION = url;
}
Run Code Online (Sandbox Code Playgroud)
通知文件://在URL构造函数中更改为http://.
现在出现在jax-ws-catalog.xml中.如果没有jax-ws-catalog.xml,jax-ws确实会尝试从该位置加载WSDL
http://localhost/wsdl/SOAService.wsdl并且失败,因为没有这样的WSDL可用.
但是使用jax-ws-catalog.xml,只要它尝试访问WSDL @,就可以将jax-ws重定向到本地打包的WSDL.
http://localhost/wsdl/SOAService.wsdl.
这是jax-ws-catalog.xml
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system">
<system systemId="http://localhost/wsdl/SOAService.wsdl"
uri="wsdl/SOAService.wsdl"/>
</catalog>
Run Code Online (Sandbox Code Playgroud)
你正在做的是告诉jax-ws什么时候需要加载WSDL
http://localhost/wsdl/SOAService.wsdl,它应该从本地路径wsdl/SOAService.wsdl加载它.
现在你应该把wsdl/SOAService.wsdl和jax-ws-catalog.xml放在哪里?这是百万美元的问题不是吗?
它应该位于应用程序jar的META-INF目录中.
所以这样的事情
ABCD.jar |__ META-INF |__ jax-ws-catalog.xml |__ wsdl |__ SOAService.wsdl
这样,您甚至不必覆盖访问代理的客户端中的URL.WSDL是从JAR中获取的,您可以避免在代码中使用硬编码的文件系统路径.
有关jax-ws-catalog.xml的更多信息 http://jax-ws.java.net/nonav/2.1.2m1/docs/catalog-support.html
希望有所帮助
mar*_*ark 17
我们成功采取的另一种方法是使用wsimport(来自Ant,作为Ant任务)生成WS客户端代理代码,并指定wsdlLocation属性.
<wsimport debug="true" keep="true" verbose="false" target="2.1" sourcedestdir="${generated.client}" wsdl="${src}${wsdl.file}" wsdlLocation="${wsdl.file}">
</wsimport>
Run Code Online (Sandbox Code Playgroud)
因为我们为具有多个WSDL的项目运行此脚本,所以该脚本动态地解析$(wsdl.file}值,该值相对于JavaSource位置(或/ src,设置为/META-INF/wsdl/YourWebServiceName.wsdl)取决于您如何设置项目.)在构建过程中,WSDL和XSD文件被复制到此位置并打包在JAR文件中.(类似于上面Bhasakar描述的解决方案)
MyApp.jar
|__META-INF
|__wsdl
|__YourWebServiceName.wsdl
|__YourWebServiceName_schema1.xsd
|__YourWebServiceName_schmea2.xsd
Run Code Online (Sandbox Code Playgroud)
注意:确保WSDL文件对任何导入的XSD使用相对引用,而不是http URL:
<types>
<xsd:schema>
<xsd:import namespace="http://valueobject.common.services.xyz.com/" schemaLocation="YourWebService_schema1.xsd"/>
</xsd:schema>
<xsd:schema>
<xsd:import namespace="http://exceptions.util.xyz.com/" schemaLocation="YourWebService_schema2.xsd"/>
</xsd:schema>
</types>
Run Code Online (Sandbox Code Playgroud)
在生成的代码中,我们发现:
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2-b05-
* Generated source version: 2.1
*
*/
@WebServiceClient(name = "YourService", targetNamespace = "http://test.webservice.services.xyz.com/", wsdlLocation = "/META-INF/wsdl/YourService.wsdl")
public class YourService_Service
extends Service
{
private final static URL YOURWEBSERVICE_WSDL_LOCATION;
private final static WebServiceException YOURWEBSERVICE_EXCEPTION;
private final static QName YOURWEBSERVICE_QNAME = new QName("http://test.webservice.services.xyz.com/", "YourService");
static {
YOURWEBSERVICE_WSDL_LOCATION = com.xyz.services.webservice.test.YourService_Service.class.getResource("/META-INF/wsdl/YourService.wsdl");
WebServiceException e = null;
if (YOURWEBSERVICE_WSDL_LOCATION == null) {
e = new WebServiceException("Cannot find '/META-INF/wsdl/YourService.wsdl' wsdl. Place the resource correctly in the classpath.");
}
YOURWEBSERVICE_EXCEPTION = e;
}
public YourService_Service() {
super(__getWsdlLocation(), YOURWEBSERVICE_QNAME);
}
public YourService_Service(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
/**
*
* @return
* returns YourService
*/
@WebEndpoint(name = "YourServicePort")
public YourService getYourServicePort() {
return super.getPort(new QName("http://test.webservice.services.xyz.com/", "YourServicePort"), YourService.class);
}
/**
*
* @param features
* A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* @return
* returns YourService
*/
@WebEndpoint(name = "YourServicePort")
public YourService getYourServicePort(WebServiceFeature... features) {
return super.getPort(new QName("http://test.webservice.services.xyz.com/", "YourServicePort"), YourService.class, features);
}
private static URL __getWsdlLocation() {
if (YOURWEBSERVICE_EXCEPTION!= null) {
throw YOURWEBSERVICE_EXCEPTION;
}
return YOURWEBSERVICE_WSDL_LOCATION;
}
}
Run Code Online (Sandbox Code Playgroud)
也许这也可能有所帮助.这只是一种不使用"目录"方法的不同方法.
对于那些仍然在这里寻求解决方案的人来说,最简单的解决方案是使用<wsdlLocation>
,而不更改任何代码。工作步骤如下:
src/main/resource
在pom文件中,添加wsdlDirectory和wsdlLocation(不要错过wsdlLocation开头的/),如下所示。wsdlDirectory 用于生成代码,而 wsdlLocation 在运行时用于创建动态代理。
<wsdlDirectory>src/main/resources/mydir</wsdlDirectory>
<wsdlLocation>/mydir/my.wsdl</wsdlLocation>
Run Code Online (Sandbox Code Playgroud)然后在你的java代码中(使用无参数构造函数):
MyPort myPort = new MyPortService().getMyPort();
Run Code Online (Sandbox Code Playgroud)为了完整起见,我在这里提供完整的代码生成部分,并在生成的代码中提供流畅的 api。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.5</version>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-fluent-api</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-tools</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>wsdl-to-java-generator</id>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<xjcArgs>
<xjcArg>-Xfluent-api</xjcArg>
</xjcArgs>
<keep>true</keep>
<wsdlDirectory>src/main/resources/package</wsdlDirectory>
<wsdlLocation>/package/my.wsdl</wsdlLocation>
<sourceDestDir>${project.build.directory}/generated-sources/annotations/jaxb</sourceDestDir>
<packageName>full.package.here</packageName>
</configuration>
</execution>
</executions>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
158106 次 |
最近记录: |