简体   繁体   English

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

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

We are using Axis2 in our enterprise currently. 我们目前在我们的企业中使用Axis2。 Our project involves making call to multiple webservices for fault diagnostics. 我们的项目涉及调用多个Web服务进行故障诊断。 The problem is that very frequently we have changes in WSDLs (which are non-life threatening as in new data-types and services just get added, very rarely is something dropped) due to which we have to upgrade our application as well. 问题是我们经常对WSDL进行更改(这些更改是非生命危险的,因为新的数据类型和服务只是被添加,很少会被删除),因此我们也必须升级我们的应用程序。 Basically, we have a to get a new copy of the WSDL, run it through WSDL2java and use the new jars, run our unit tests and package the new jars and install on production. 基本上,我们有一个获取WSDL的新副本,通过WSDL2java运行它并使用新的jar,运行我们的单元测试并打包新的jar并在生产中安装。

Although the capability of generating the stubs at compile team gives us xmlbeans with which we can work easily in our java DAO layer code, this compile-deploy cycle due to WSDLs consume the team's time. 虽然在编译团队中生成存根的能力为我们提供了可以在我们的Java DAO层代码中轻松工作的xmlbeans,但由于WSDL而导致的编译部署周期消耗了团队的时间。 I was wondering whether there is any change possible? 我想知道是否有可能改变? Is there any Java APIs which can generate stubs at run-time or provide stub-less web service invocation, but still give us ability to work with java objects rather than handcrafting request documents? 是否有任何Java API可以在运行时生成存根或提供无存根的Web服务调用,但仍然能够使用java对象而不是手工处理请求文档? Something like this soap test site . 这个肥皂测试网​​站的东西。 I should just be able to specify a WSDL location and I should just get an object with which I can access the document (both request and response) and also be able to change the WSDL location at run-time? 我应该能够指定一个WSDL位置,我应该只获取一个可以访问该文档的对象(请求和响应),还能够在运行时更改WSDL位置?

Not sure whether this type of run-time behavior is possible in Java since objects generated at run-time would have different types etc?? 不确定在Java中是否可以使用这种类型的运行时行为,因为在运行时生成的对象会有不同的类型等? not sure... I have seen some Groovy examples which come close to what I want but using Groovy means an architectural change for us.. and that's a bit tough... Is there any Java library/API available? 不确定...我已经看到一些Groovy示例接近我想要的但是使用Groovy意味着我们的体系结构改变......这有点难度......有没有可用的Java库/ API?

The Eclipse Web Service Explorer builds a UI client of an arbitrary WSDL on the fly. Eclipse Web Service Explorer动态构建任意WSDL的UI客户端。 So I guess that what you want to do is possible if you're prepared for your app to use a bit of reflection to invoke the services. 所以,如果您已准备好让您的应用程序使用一些反射来调用服务,那么我想您可以做的事情是可能的。

As Eclipse is open source you may be able to study how the explorer is implemented and use ideas? 由于Eclipse是开源的,您可以研究如何实现资源管理器并使用创意?

On the other hand, can you automate your build with ant so that if a new WSDL arrives it just gets processed automatically, benign changes would just be silently absorbed. 另一方面,你可以使用ant自动化你的构建,这样如果一个新的WSDL到达它只是自动处理,良性的变化将被默默地吸收。 My instict is that this is a better approach. 我的箴言是这是一种更好的方法。

Not entirely stubless, but a bit more independent Spring's JaxWsPortProxyFactoryBean . 不完全是stubless,而是更独立的Spring的JaxWsPortProxyFactoryBean You supply the service interface with the methods your code actually uses. 您使用代码实际使用的方法提供服务接口。 You can supply the URL to connect to using a property. 您可以提供用于连接到使用属性的URL。 If the service's location changes, or more methods are added (that your code does not use yet), no regeneration, compile or packaging is needed. 如果服务的位置发生更改,或者添加了更多方法(您的代码尚未使用),则无需重新生成,编译或打包。

If you get a new version of the WSDL that you want to change your code to use the new operations just re-run wsdl2java like you do today to get new beans and a new service interface. 如果您想要更新代码以使用新操作的WSDL的新版本,请像现在一样重新运行wsdl2java以获得新的bean和新的服务接口。 So you only need to do that work when you are changing your code anyway use new features. 因此,只有在更改代码时才需要使用新功能。

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

The underdocumented Service class might provide what you're looking for. 未充分利用的Service类可能会提供您正在寻找的内容。

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

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