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

时间:2010-01-07 06:42:57

标签: java service

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

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

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

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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类可能会提供您正在寻找的内容。