java - JAX-WS 客户端 : what's the correct path to access the local WSDL?

标签 java netbeans client jax-ws

问题是我需要从提供的文件中构建 Web 服务客户端。我已将此文件存储在本地文件系统上,并且虽然我将 WSDL 文件保存在正确的文件系统文件夹中,但一切都很好。当我将它部署到服务器或从文件系统文件夹中删除 WSDL 时,代理找不到 WSDL 并出现错误。我在网上搜索了以下帖子,但我无法使其工作:
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

我使用的是 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);
    }

}


这是我使用代理的代码:

   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 将 WSDL 的副本放在 web-inf/wsdl/client/SOAService 中,所以我不想将它也添加到 META-INF 中。服务类位于 WEB-INF/classes/com/ibm/eci/soaservice/ 中,baseurl 变量包含它的文件系统完整路径(c:\path\to\the\project...\服务)。上面的代码引发了错误:

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)

那么,首先,我应该更新代理类的 wsdllocation 吗?那我如何告诉 WEB-INF/classes/com/ibm/eci/soaservice 中的 SOAService 类在\WEB-INF\wsdl\client\SOAService.wsdl 中搜索 WSDL?

已编辑:我找到了另一个链接 - http://jianmingli.com/wp/?cat=41 ,表示将 WSDL 放入类路径中。不好意思问:怎么把它放到web应用的classpath中?

最佳答案

最好的选择是使用 jax-ws-catalog.xml

当您编译本地 WSDL 文件时,覆盖 WSDL 位置并将其设置为类似

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

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

注意 file://在 URL 构造函数中更改为 http://。

现在出现在 jax-ws-catalog.xml 中。如果没有 jax-ws-catalog.xml,jax-ws 确实会尝试从该位置加载 WSDL

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>

你正在做的是告诉 jax-ws 何时需要从

http://localhost/wsdl/SOAService.wsdl
加载 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

希望有帮助

关于java - JAX-WS 客户端 : what's the correct path to access the local WSDL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4163586/

相关文章:

java - if else 语句失败

java - 从逆波兰表示法(RPN)转换为树形式?

java - 使用 MySQL 将 Maven Web 应用程序从 Netbeans 部署到 Tomcat

python - 当客户端没有在Python中写任何内容(我只按Enter)时,如何从服务器验证变量

java - 客户端-服务器应用程序空指针异常

java - Jersey 2.22 : When should I close the Client instance?

java - Camel 按长度而不是按标记拆分 InputStream

java - HashSet 的 Hashing 是如何工作的?

netbeans - 将基于 ANT 的 NetBeans 项目转换为 Gradle 项目?

java - log4j 属性 DailyRollingFileAppender 不起作用