没有WSDL文档文件的JAX-WS客户端

13

我正在使用NetBeans(JAX-WS)自动生成客户端消费一个SOA Web服务,一切都运行良好,但是当客户端运行时,我发现WSDL文件总是在下载。

在生产环境中,我不想暴露WSDL文件,并尝试修改客户端以不需要WSDL文件,但我的所有尝试都失败了,我找到了这个:

WebService_Service svc = new WebService_Service(
  null,
  new QName("http://www.example.com/ws", "WebService"));
WebService port = svc.getPort(WebService.class);
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext()
  .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
    "http://www.example.com/real_endpoint_url_goes_here");

但当执行第一行时,我发现了这个异常:

Message: El contenido no está permitido en el prólogo.
    at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.wrapException(Unknown Source)
    at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.next(Unknown Source)
    at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.nextContent(Unknown Source)
    at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.nextElementContent(Unknown Source)
    at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.hasWSDLDefinitions(Unknown Source)
    at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
    at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
    at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(Unknown Source)
    at javax.xml.ws.Service.<init>(Unknown Source)

有什么办法可以忽略WSDL吗?


最终我把客户端迁移到了CXF,现在一切都很顺利。 - mls_dev
4个回答

22

有几种方法,我将告诉您其中两种:

  1. 在本地使用WSDL文档文件

    将WSDL文档文件和模式文件的副本保存到您的项目中。

ClassLoader classloader = Thread.currentThread().getContextClassLoader();
URL wsdlLocation = classloader.getResource("MyHelloService.wsdl");
QName serviceName= new QName("http://test.com/", "MyHelloService");

MyHelloService service = new MyHelloService(wsdlLocation, serviceName);
service.sayHello("Test");

您可以合并WSDL文档文件和模式文件。

  • 没有WSDL文档文件

    这种解决方案需要生成客户端。

  • QName qname = new QName("http://thenamespace", "FooService");
    FooService service = new FooService(null, qname); // null for ignore WSDL
    Foo port = service.getFooPort();
    BindingProvider bindingProvider = (BindingProvider) port;
    bindingProvider.getRequestContext()
        .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
        "http://foo.com/soap/fooBean");
    
    // Use the service
    String result = port.doSomething(param);
    

    谢谢你的回答,我正在尝试使用第二种方法,但是我遇到了第一篇帖子(问题)的异常。 - mls_dev
    我试图在这篇文章中总结所有内容:https://medium.com/@nieldw/setting-the-target-endpoint-url-on-java-soap-web-service-clients-d5079da7816 - Niel de Wet
    我曾经遇到过类似的问题,想要将其与Dispatch结合使用,但在Apache CXF中并不起作用。帮助我很多的是一些旧的IBM文档:https://www.ibm.com/support/knowledgecenter/en/SSEQTP_8.5.5/com.ibm.websphere.base.doc/ae/twbs_jaxwsdynclient.html - Ice09
    我尝试了第二种解决方案,但它没有忽略wsdl。它试图使用从我使用wsimport生成类的原始位置的wsdl。最终采用第一种解决方案,并将wsdl保存在源代码中。 - Alexandru Severin

    6

    最终我使用了CXF库,并成功实现了Paul Vargas的答案:

    无需WSDL文档文件

    该解决方案需要生成客户端。

    QName qname = new QName("http://thenamespace", "FooService");
    FooService service = new FooService(null, qname); // null for ignore WSDL
    Foo port = service.getFooPort();
    BindingProvider bindingProvider = (BindingProvider) port;
    bindingProvider.getRequestContext()
        .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
        "http://foo.com/soap/fooBean");
    
    // Use the service
    String result = port.doSomething(param);
    

    使用标准的jaw-ws,这个解决方案不起作用,需要使用CXF。

    1

    我也需要类似的东西。

    在我的情况下,我将一个没有端点地址的虚拟wsdl放置在我的Web应用程序类路径中。之后,在运行时设置了一个有效的地址,如下所示:

        String WSDL = "/config/ws/Main_default.wsdl";
        Main service = new Main(Main.class.getResource(WSDL), new QName(
                "http://www.example.com/", "Main"));
        MainWS port = service.getMainWSPort();
    
        BindingProvider bindingProvider = (BindingProvider) port;
        bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
                "http://app.example.com/ws/services/main");
    
        Object result = port.someMethod("some param");
    

    请确认此解决方案是否与jax-ws兼容,谢谢。 - boly38

    0

    这个异常是由于您的xml文件中存在解析错误,并且在指定的行和列出现了问题。请检查您的xml文件。


    是的,我认为异常发生是因为我将null传递给服务构造函数,它尝试下载wsdl但没有找到任何内容。但我不知道如何强制客户端不下载wsdl。 - mls_dev
    尝试使用无参数构造函数:WebService_Service svc = new WebService_Service() - constantlearner
    谢谢您的回答,但在这种情况下,默认构造函数调用wsdl,因为它内部有一个对它的引用。我尝试删除对wsdl的内部引用,但问题仍然存在。难道不能在没有wsdl的情况下使用客户端吗? - mls_dev
    你是在使用cxf还是axis?如果是cxf,那么提到的方法可以正常工作。 - constantlearner
    我正在使用NetBeans附带的默认库(jax-ws),并遵循此教程:http://martcode.com/tipsGallery/Webservice-Client-2-min-using-Netbeans.php?id=42 - mls_dev

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接