JAX-WS客户端:访问本地WSDL的正确途径是什么? [英] JAX-WS client : what's the correct path to access the local WSDL?

查看:111
本文介绍了JAX-WS客户端:访问本地WSDL的正确途径是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是我需要从我提供的文件构建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)
公共类SOAService
扩展服务
{

私有最终静态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 =新网址(baseUrl,file:/ C:/local/path/to/wsdl/SOAService.wsdl);
} catch(MalformedURLException e){
logger.warning(无法为wsdl位置创建URL:'file:/ C:/local/path/to/wsdl/SOAService.wsdl',正在重试作为本地文件);
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
*返回SOAServiceSoap
* /
@WebEndpoint(name =SOAServiceSOAP)
public SOAServiceSoap getSOAServiceSOAP(){
return super.getPort(new QName(http://soaservice.eci.ibm.com/,SOAServiceSOAP),SOAServiceSoap.class);
}

/ **
* @param features
*要在代理上配置的{@link javax.xml.ws.WebServiceFeature}列表。支持的功能不在< code>功能< / code>中参数将具有其默认值。
* @return
*返回SOAServiceSoap
* /
@WebEndpoint(name =SOAServiceSOAP)
public SOAServiceSoap getSOAServiceSOAP(WebServiceFeature ... features){
return super.getPort(new QName(http://soaservice.eci.ibm.com/,SOAServiceSOAP),SOAServiceSoap.class,features);
}

}



这是我使用代理的代码:

  WebServiceClient annotation = SOAService.class.getAnnotation(WebServiceClient.class); 
//尝试复制代理设置
URL baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(); //注意:代理使用。
URL url =新网址(baseUrl,/ WEB-INF / wsdl / lclient / 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(); * /
//更新服务端点
Map< String,Object> ctxt =((BindingProvider)proxy).getRequestContext();
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE,8192);
ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,WebServiceUrl);

NetBeans将WSDL的副本放在 web-inf / wsdl / client / SOAService ,所以我也不想将它添加到 META-INF 。服务类位于 WEB-INF / classes / com / ibm / eci / soaservice / 中,baseurl变量包含文件系统的完整路径(c:\ path\to \\\\ 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应用程序类路径?

解决方案

最好的选择是使用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 =新网址(baseUrl,file:/ C:/local/path/to/wsdl/SOAService.wsdl);
} catch(MalformedURLException e){
logger.warning(无法为wsdl位置创建URL:'file:/ C:/local/path/to/wsdl/SOAService.wsdl',正在重试作为本地文件);
logger.warning(e.getMessage());
}
SOASERVICE_WSDL_LOCATION = url;
}

  static {
URL url = null;
try {
URL baseUrl;
baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(。);
url =新网址(baseUrl,http://localhost/wsdl/SOAService.wsdl);
} catch(MalformedURLException e){
logger.warning(无法为wsdl位置创建URL:'http://localhost/wsdl/SOAService.wsdl',重试为本地文件) ;
logger.warning(e.getMessage());
}
SOASERVICE_WSDL_LOCATION = url;
}

注意文件://在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:catalogprefer =system> 
< system systemId =http://localhost/wsdl/SOAService.wsdl
uri =wsdl / SOAService.wsdl/>
< / catalog>

你正在做的是告诉jax-ws什么时候需要从<$ p加载WSDL $ p> 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



希望有所帮助


The problem is I need to build a web service client from a file I'm been provided. I've stored this file on the local file system and, while I keep the WSDL file in the correct file system folder, everything is fine. When I deploy it to a server or remove the WSDL from the file system folder the proxy can't find the WSDL and rises an error. I've searched the web and I've found the following posts yet I'm not been able to make it work:
JAX-WS Loading WSDL from jar
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

I'm using NetBeans 6.1 (this is a legacy application I've to update with this new web service client). Below is the JAX-WS proxy class :

    @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);
    }

}


This is my code to use the proxy :

   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);

NetBeans put a copy of the WSDL in web-inf/wsdl/client/SOAService, so I don't want to add it to META-INF too. Service classes are in WEB-INF/classes/com/ibm/eci/soaservice/ and baseurl variable contains the filesystem full path to it (c:\path\to\the\project...\soaservice ). The above code raises the error:

javax.xml.ws.WebServiceException: Failed to access the WSDL at: file:/WEB-INF/wsdl/client/SOAService.wsdl. It failed with: \WEB-INF\wsdl\client\SOAService.wsdl (cannot find the path)

So, first of all, shall I update the wsdllocation of the proxy class? Then how do I tell the SOAService class in WEB-INF/classes/com/ibm/eci/soaservice to search for the WSDL in \WEB-INF\wsdl\client\SOAService.wsdl?

EDITED: I've found this other link - http://jianmingli.com/wp/?cat=41, which say to put the WSDL into the classpath. I'm ashamed to ask: how do I put it into the web application classpath?

解决方案

The best option is to use jax-ws-catalog.xml

When you compile the local WSDL file , override the WSDL location and set it to something like

http://localhost/wsdl/SOAService.wsdl

Don't worry this is only a URI and not a URL , meaning you don't have to have the WSDL available at that address.
You can do this by passing the wsdllocation option to the wsdl to java compiler.

Doing so will change your proxy code from

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;
}

to

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;
}

Notice file:// changed to http:// in the URL constructor.

Now comes in jax-ws-catalog.xml. Without jax-ws-catalog.xml jax-ws will indeed try to load the WSDL from the location

http://localhost/wsdl/SOAService.wsdl

and fail, as no such WSDL will be available.

But with jax-ws-catalog.xml you can redirect jax-ws to a locally packaged WSDL whenever it tries to access the WSDL @

http://localhost/wsdl/SOAService.wsdl

.

Here's 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>

What you are doing is telling jax-ws that when ever it needs to load WSDL from

http://localhost/wsdl/SOAService.wsdl

, it should load it from local path wsdl/SOAService.wsdl.

Now where should you put wsdl/SOAService.wsdl and jax-ws-catalog.xml ? That's the million dollar question isn't it ?
It should be in the META-INF directory of your application jar.

so something like this

ABCD.jar  
|__ META-INF    
    |__ jax-ws-catalog.xml  
    |__ wsdl  
        |__ SOAService.wsdl  

This way you don't even have to override the URL in your client that access the proxy. The WSDL is picked up from within your JAR, and you avoid having to have hard-coded filesystem paths in your code.

More info on jax-ws-catalog.xml http://jax-ws.java.net/nonav/2.1.2m1/docs/catalog-support.html

Hope that helps

这篇关于JAX-WS客户端:访问本地WSDL的正确途径是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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