【问题标题】:JAX-WS client without a WSDL document file没有 WSDL 文档文件的 JAX-WS 客户端
【发布时间】:2013-11-17 20:54:07
【问题描述】:

我正在使用 webservice soa,使用 netbeans (jax-ws) 我使用 netbeans 自动生成客户端,一切运行良好,但我看到客户端运行时 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,一切正常

标签: java web-services netbeans client jax-ws


【解决方案1】:

当您的 xml 中存在解析错误并且指定的行和列存在错误时,会发生此异常。检查你的xml

【讨论】:

  • 是的,我认为发生异常是因为我将 null 传递给服务构造函数,它尝试下载 wsdl 却找不到任何东西。但我不知道如何强制客户端不下载 wsdl
  • 尝试使用无参数构造函数 WebService_Service svc = new WebService_Service()
  • 感谢答案,但在这种情况下,默认构造函数调用 wsdl 因为在一个内部引用它。我尝试删除对 wsdl 的内部引用,但问题仍然存在。没有 wsdl 就不能使用客户端吗?
  • 您使用的是 cxf 还是轴?使用 cxf 上述方法有效
  • 我正在使用 netbeans (jax-ws) 附带的默认库,我遵循本教程:martcode.com/tipsGallery/…
【解决方案2】:

有几种方法,我会告诉你两种:

  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");
    

    您可以combine 带有架构文件的 WSDL 文档文件。

  2. 没有 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);
    

【讨论】:

  • 感谢我尝试使用 2 号方式的答案,但我对第一篇文章有​​例外(问题)
  • 我试图在这里的帖子中总结这一切:medium.com/@nieldw/…
  • 我遇到了类似的问题,想将它与 Dispatch 结合起来,在这种情况下它不适用于 Apache CXF。帮助很大的是一些旧的 IBM 文档:ibm.com/support/knowledgecenter/en/SSEQTP_8.5.5/…
【解决方案3】:

最后我使用了 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。

【讨论】:

    【解决方案4】:

    我也需要这样的东西。

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

        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,谢谢