使用 Java 创建 Web 服务客户端时出错
我在网上到处都看到了这个问题,但仍然没有找到对我有用的明确解决方案。问题是:
我正在尝试用 Java 创建一个 Web 服务客户端。客户端需要是一个控制台应用程序,将放置在服务器上并以一定的时间间隔自动运行。我尝试使用的 Web 服务是由第三方公司编写和托管的。该服务是用 ASP.NET 编写的。我们点击了该公司的多项服务。它们都是用 ASP.NET 编写的。我从未处理过这些服务,直到 2 天前,当时我的任务是使用其中 2 个服务并根据数据构建 Excel 电子表格。在继续之前,让我描述一下我的开发环境。其中一些相关,一些不相关,但我想包括所有内容:
- Windows 7 Professional 32 位
- NetBeans IDE 6.9.1
- Java JDK 1.6.0_17
- jre6
- Glassfish 3 开源全平台版本
- 所有软件均已应用所有可用更新
说到问题。当我将第一个 Web 服务客户端添加到控制台应用程序时,我对整个过程的顺利进行感到惊讶。我编写 Web 服务应用程序的大部分经验都是在 .NET 中完成的。我能够导入 WSDL,并且 NetBeans 在第一次尝试时生成了所有类。 5 分钟内,我第一次致电该服务并得到了预期的响应,让我知道我的尝试成功了。然后,我使用我需要的第二个 WSDL 的地址将第二个 Web 服务客户端添加到控制台应用程序。这是我遇到一个大问题的地方。
导入 WSDL 后,NetBeans 向我发出错误警报,指出:
无法通过 JAXWS:wsimport 实用程序创建 Web 服务客户端。
原因:未定义的元素声明's:schema'
在滥用 Google 了一小时寻找解决方案之后,我最终决定进行一些尝试和错误。查看 NetBeans 中的“输出”窗口,我可以看到它抱怨 3 条特定的行。当我查看 WSDL 时,我发现这 3 行是完全相同的,如下所示:
<s:element ref="s:schema" />
这 3 行是从 WSDL 的顶部到大约一半的随机位置找到的。我从 Web Service References 文件夹中找到的 WSDL 中删除了这些行,只将 WSDL 保留在 META-INF 文件夹中。然后,我刷新了服务引用,令我惊讶的是,NetBeans 解析了 WSDL 并像以前一样生成了我的类。太棒了,对吧?好吧,这就是问题#2 发挥作用的地方。
现在我能够毫无错误地编译我的应用程序,我必须尝试访问该服务以查看我的黑客攻击是否有效。但事实并非如此。由于 JAXWS 中的另一个错误,我必须在创建服务对象时在构造函数中提供 WSDL 的 URL。这意味着我修复的 WSDL 将被忽略,服务现在又恢复使用无法解析的 WSDL。当我尝试提供我在项目中本地编辑的 WSDL 的位置时,我遇到了另一个编译错误,指出我遇到了 NullPointerException。它说我需要在使用它之前初始化该对象。
我研究了该网站上似乎无数的主题,寻找并尝试已提供的任何解决方案。我还尝试了网络上所有的解决方案,但都没有成功。如果有人对我有任何建议、任何提示、技巧、窍门,请告诉我。目前我愿意接受任何建议。
预先感谢您提供的任何帮助。
I've seen this problem all over the Web, but still haven't found a clear solution that has worked for me. Here's the issue:
I am trying to create a Web service client in Java. The client needs to be a console app that will be placed on a server and automatically run at a certain time interval. The Web service I am trying to consume was written and is hosted by a third party company. The service was written in ASP.NET. The company in question has several services that we hit. All of them are written in ASP.NET. I have never dealt with these services until 2 days ago when I was tasked with consuming 2 of the services and building an Excel spreadsheet from the data. Before I continue, let me describe my development environment. Some of this is relevant, some is not, but I want to include everything:
- Windows 7 Professional 32-bit
- NetBeans IDE 6.9.1
- Java JDK 1.6.0_17
- jre6
- Glassfish 3 Open Source Full-Platform Release
- All software has had all available updates applied
On to the problem. When I added the first Web Service Client to my console app, I was surprised at how smoothly the process went. Most of my experience writing Web Service apps is in .NET. I was able to import the WSDL and NetBeans generated all classes on the first try. Within 5 minutes, I was able to make my first call to the service and was greeted with the expected response, letting me know that my attempt was successful. I then added the second Web Service Client to the console app using the address to the second WSDL I needed. This is where I ran into a major problem.
Upon importing the WSDL, I was alerted to an error by NetBeans stating:
Web Service Client can not be created by JAXWS:wsimport utility.
Reason: undefined element declaration 's:schema'
After abusing Google for the next hour looking for a solution, I finally decided to apply some trial and error. Looking at the Output window in NetBeans, I could see that it was complaining about 3 specific lines. Once I took a look at the WSDL, I could see that those 3 lines were exactly the same, as follows:
<s:element ref="s:schema" />
These 3 lines were found in random places from the top of the WSDL, down to about half-way through. I removed these lines from the WSDL found in the Web Service References folder, leaving the WSDL in the META-INF folder alone. I then did a refresh on the service reference and much to my surprise, NetBeans parsed the WSDL and generated my classes just as before. Great, right? Well, here's where problem #2 comes into play.
Now that I was able to compile my app with no errors, I had to try to hit the service to see if my hack had worked. It did not. Because of another bug in JAXWS, I have to provide the URL to the WSDL in the constructor when creating a service object. This means that the WSDL I fixed is being ignored and the service is now back to using the WSDL that can not be parsed. When I tried to provide the location of WSDL I edited locally within my project, I was greeted with another compilation error stating that I had a NullPointerException. It said that I needed to initialize the object before using it.
I have researched what seems like an infinite amount of topics on this site looking for and trying any solutions that have been provided. I have also tried solutions from all over the Web, all with no luck. If anyone has any advice for me, any tips, tricks, hacks, please let me know. I'm open to any suggestions at this point.
Thanks in advance for any assistance provided.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
单方面的合同变更可能会导致问题。
假设
s
前缀引用http://www.w3.org/2001/XMLSchema
命名空间,看起来您的 WSDL 引用了 XML 架构类型。在生成 JAXB 绑定时,JAX-WS 可能无法解决此问题。您可以从 http://www.w3.org/2001/XMLSchema.html;您至少需要
XMLSchema.xsd
、XMLSchema.dtd
和datatypes.dtd
。由此生成 Java 类型可能需要修改您的 JAXB 绑定配置。或者,使用 动态 JAX-WS 客户端代码。您可以使用soapUI 等工具来创建/测试示例XML 请求。
如果您决定编辑 WSDL,则生成的服务代码应该具有
Foo_Service(URL, QName)
形式的构造函数,该构造函数允许您在本地配置 WSDL(例如,从类路径)。One-sided contract changes may lead to problems.
Assuming the
s
prefix refers to thehttp://www.w3.org/2001/XMLSchema
namespace, it looks like your WSDL references XML schema types. JAX-WS is probably unable to resolve this when generating the JAXB bindings.You can download the XSD from http://www.w3.org/2001/XMLSchema.html; at a minimum, you'll need
XMLSchema.xsd
,XMLSchema.dtd
anddatatypes.dtd
. Generating Java types from this may require fiddling with your JAXB binding configuration.Alternatively, it may be easier to just use dynamic JAX-WS client code. You can use a tool like soapUI to create/test sample XML requests.
If you do decide to edit the WSDL, the generated service code should have a constructor of the form
Foo_Service(URL, QName)
that allows you to provision the WSDL locally (e.g. from your classpath).我要做的第一件事是尝试在用于测试 SOAP 服务的工具(例如 SoapUI)中打开它。如果您的架构无法解析,则可能会有您可能需要的代码片段也不会生成。我最近就遇到过这样的情况,一家供应商提供了“网络服务”,经过一番拆解后,他们“奇迹般地”找到了一套运行良好的替代服务。
您还可以尝试 Jax-W 的一些替代方案,例如 CXF 或 Axis。
The first thing I'd do is try to open it in one of the tools meant for testing SOAP services, like SoapUI. If you have schema not resolving, that is possible there will be pieces of code that you may need that won't be generated as well. I had that happen recently with a vendor supplied "web service", and after much dissembling they "miraculously" found an alternative set of services that worked fine.
You could also try some of the alternatives to Jax-Ws, like CXF or Axis.