繁体   English   中英

如何用Java创建一个stubless Web服务客户端?

[英]How to make a stubless Web Service Client in Java?

我们目前在我们的企业中使用Axis2。 我们的项目涉及调用多个Web服务进行故障诊断。 问题是我们经常对WSDL进行更改(这些更改是非生命危险的,因为新的数据类型和服务只是被添加,很少会被删除),因此我们也必须升级我们的应用程序。 基本上,我们有一个获取WSDL的新副本,通过WSDL2java运行它并使用新的jar,运行我们的单元测试并打包新的jar并在生产中安装。

虽然在编译团队中生成存根的能力为我们提供了可以在我们的Java DAO层代码中轻松工作的xmlbeans,但由于WSDL而导致的编译部署周期消耗了团队的时间。 我想知道是否有可能改变? 是否有任何Java API可以在运行时生成存根或提供无存根的Web服务调用,但仍然能够使用java对象而不是手工处理请求文档? 这个肥皂测试网​​站的东西。 我应该能够指定一个WSDL位置,我应该只获取一个可以访问该文档的对象(请求和响应),还能够在运行时更改WSDL位置?

不确定在Java中是否可以使用这种类型的运行时行为,因为在运行时生成的对象会有不同的类型等? 不确定...我已经看到一些Groovy示例接近我想要的但是使用Groovy意味着我们的体系结构改变......这有点难度......有没有可用的Java库/ API?

Eclipse Web Service Explorer动态构建任意WSDL的UI客户端。 所以,如果您已准备好让您的应用程序使用一些反射来调用服务,那么我想您可以做的事情是可能的。

由于Eclipse是开源的,您可以研究如何实现资源管理器并使用创意?

另一方面,你可以使用ant自动化你的构建,这样如果一个新的WSDL到达它只是自动处理,良性的变化将被默默地吸收。 我的箴言是这是一种更好的方法。

不完全是stubless,而是更独立的Spring的JaxWsPortProxyFactoryBean 您使用代码实际使用的方法提供服务接口。 您可以提供用于连接到使用属性的URL。 如果服务的位置发生更改,或者添加了更多方法(您的代码尚未使用),则无需重新生成,编译或打包。

如果您想要更新代码以使用新操作的WSDL的新版本,请像现在一样重新运行wsdl2java以获得新的bean和新的服务接口。 因此,只有在更改代码时才需要使用新功能。

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

/**
 * This class creates SOAP clients from WDSL and a Java interface.
 * See http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JAXRPC5.html
 * <p>
 * Consider the following sample usage:
 * <pre>
    URL            wsdl = new URL("http://localhost:8080/calc/calc?wsdl");
    String  serviceName = "CalculatorWSService";
    String nameSpaceURI = "http://calculator.me.org/";
    String     portName = "CalculatorWSPort";
    Calculator     calc = SOAPClient.newInstance(wsdl, nameSpaceURI, serviceName, portName, Calculator.class);
 * </pre>
 * @author Curt
 */
public final class SOAPClient {

    /**
     * Create a new SOAPClient, given the specified parameters.
     * @param url where the WSDL is
     * @param nameSpaceUri
     * @param serviceName
     * @param portName
     * @param face interface to use
     * @return an object that implements the interface and is connected to the server
     */
    public static <T> T newInstance(
        URL url, String nameSpaceUri, String serviceName,
        String portName, Class<T> face)
        throws RemoteException
    {
        try {
            QName portQname    = new QName(nameSpaceUri, portName);
            QName serviceQname = new QName(nameSpaceUri, serviceName);
            Service service = Service.create(url, serviceQname);
            T remote = service.getPort(portQname,face);
            T proxy = face.cast(remote);
            return proxy;
        } catch (Throwable t) {
            String message =
                "Connecting to URL=" + url +
                " name space URI= "+ nameSpaceUri +
                " service name=" + serviceName +
                " interface=" + face +
                " port=" + portName;
            throw new RemoteException(message,t);
        }
    }

    /**
     * Don't specify the portName and trust that the service will do it.
     */
    public static <T> T newInstance(
        URL url, String nameSpaceUri, String serviceName, Class<T> face)
        throws MalformedURLException, RemoteException
    {
        QName serviceQname = new QName(nameSpaceUri, serviceName);
        Service service = Service.create(url, serviceQname);
        T remote = service.getPort(face);
        T proxy = face.cast(remote);
        return proxy;
    }
}

未充分利用的Service类可能会提供您正在寻找的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM