实战CXF调用Webxml天气预报服务
实战CXF调用Webxml天气预报服务
今晚群里的kasasis同学问我会不会使用CXF调用
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
这个天气预报的WebService服务;
我也是初学者, 在尝试调用的过程中发现不少问题, 也有一些小心得, 希望与大家分享, 更希望大家可以帮我解惑.
一.初探:通过wsdl2java生成调用远程服务所需要的java类
因为还没有成功使用dynamic-clients(http://cxf.apache.org/docs/dynamic-clients.html)的方式动态调用过WebService服务, 所以决定使用CXF提供的wsdl2java来生成调用WebService服务所必须的java类, 进而使用JaxWsServerFactoryBean来调用WebService服务:
遗憾的是, CXF wsdl2java报错了:
undefined element declaration 's:schema'
at line 85 column 41 of schema
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
将该wsdl下载下来, 使用MyEclipse 9.0打开并查看, 也提示了这一错误:
src-resolve.4.2: Error resolving component 's:schema'.
It was detected that 's:schema' is in namespace 'http://www.w3.org/2001/XMLSchema', but components from this namespace are not referenceable from schema document 'file:///D:/workspace/workspace_j2ee/CXFWeatherTest/src/WeatherWebService.asmx.original.wsdl'.
If this is the incorrect namespace, perhaps the prefix of 's:schema' needs to be changed.
If this is the correct namespace, then an appropriate 'import' tag should be added to 'file:///D:/workspace/workspace_j2ee/CXFWeatherTest/src/WeatherWebService.asmx.original.wsdl'.
wsdl报错部分内容如下(下边代码红色部分):
- <s:element name="getSupportDataSetResponse">
- <s:complexType>
- <s:sequence>
- <s:element
- minOccurs="0"
- maxOccurs="1"
- name="getSupportDataSetResult">
- <s:complexType>
- <s:sequence>
- <s:element ref="s:schema" />
- <s:any />
- </s:sequence>
- </s:complexType>
- </s:element>
- </s:sequence>
- </s:complexType>
- </s:element>
作为初学者, 曾在风中叶老师的视频中学习过关于schema及DTD的一些知识, 但还没修炼到能解决这一错误的程度, 也期待各位同学的积极探索并给出答案;
问题催人奋进, 折衷的办法总是有的:
<s:any/>既然可以代表任何元素, 为什么不能代表<s:element ref="xxx"/>元素呢? 于是乎, 愤然删除<s:element ref="s:schema" />, 勉强算是通过了CXF提供的wsdl验证工具wsdlvalidator的验证;
Ok, 继续之前的步骤, 通过wsdl2java来生成调用远程WebService服务所需要的java类;
一切顺利, 生成的类的目录结构如下:
二.使用JaxWsProxyFactoryBean调用天气服务
本工程使用的jar包如下图示:
通过JaxWsProxyFactoryBean调用webService服务的过程相信大家都很熟悉了, 具体代码如下:
- package cn.com.client;
- import java.util.List;
- import org.apache.cxf.interceptor.LoggingInInterceptor;
- import org.apache.cxf.interceptor.LoggingOutInterceptor;
- import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
- import cn.com.webxml.ArrayOfString;
- import cn.com.webxml.WeatherWebServiceSoap;
- public class Test {
- public static void main(String[] args) throws Exception {
- JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
- factory.getInInterceptors().add(new LoggingInInterceptor());
- factory.getOutInterceptors().add(new LoggingOutInterceptor());
- factory.setAddress(
- "http://www.webxml.com.cn/WebServices/WeatherWebService.asmx");
- factory.setServiceClass(WeatherWebServiceSoap.class);
- WeatherWebServiceSoap client =
- (WeatherWebServiceSoap) factory.create();
- ArrayOfString o = client.getWeatherbyCityName("南阳");
- List<String> strList = o.getString();
- for (String str : strList) {
- System.out.println(str);
- }
- }
- }
运行还算顺利, 得到的结果如下:
信息: Outbound Message
---------------------------
ID: 1
Address: http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
Encoding: UTF-8
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=["http://WebXml.com.cn/getWeatherbyCityName"]}
Payload:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getWeatherbyCityName xmlns="http://WebXml.com.cn/">
<theCityName>南阳</theCityName>
</getWeatherbyCityName>
</soap:Body>
</soap:Envelope>
河南
南阳
57178
57178.jpg
2012-4-5 22:58:11
11℃/24℃
4月6日 晴
无持续风向微风
0.gif
0.gif
今日天气实况:气温:16℃;风向/风力:北风 0级;湿度:53%;空气质量:较差;紫外线强度:中等
穿衣指数:建议着薄型套装等春秋过渡装。年老体弱者宜着套装。但昼夜温差较大,注意适当增减衣服。
感冒指数:昼夜温差较大,较易发生感冒,请适当增减衣服。体质较弱的朋友请注意防护。
运动指数:天气较好,赶快投身大自然参与户外运动,尽情感受运动的快乐吧。
洗车指数:适宜洗车,未来持续两天无雨天气较好,适合擦洗汽车,蓝天白云、风和日丽将伴您的车子连日洁净。
晾晒指数:天气不错,适宜晾晒。赶紧把久未见阳光的衣物搬出来吸收一下太阳的味道吧!
旅游指数:天气晴朗,风和日丽,温度适宜,是个好天气哦。这样的天气很适宜旅游,您可以尽情地享受大自然的风光。
路况指数:天气较好,路面比较干燥,路况较好。
舒适度指数:温度适宜,风力不大,您在这样的天气条件下,会感到比较清爽和舒适。
空气污染指数:气象条件较不利于空气污染物稀释、扩散和清除,请适当减少室外活动时间。
紫外线指数:属中等强度紫外线辐射天气,外出时建议涂擦SPF高于15、PA+的防晒护肤品,戴帽子、太阳镜。
11℃/24℃
4月7日 晴
无持续风向微风
0.gif
0.gif
10℃/23℃
4月8日 阴转多云
无持续风向微风
2.gif
1.gif
南阳市位于河南省西南部,北靠伏牛山,东扶桐柏山,西依秦岭,南临汉江。..................
三.使用JaxWsDynamicClientFactory调用天气服务
CXF关于Dynamic-clients的介绍文档见:
http://cxf.apache.org/docs/dynamic-clients.html
很简洁的一段官方示例代码:
- JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
- Client client = dcf.createClient("echo.wsdl");
- Object[] res = client.invoke("echo", "test echo");
- System.out.println("Echo response: " + res[0]);
但具体的调用过程并非一帆风顺; 让人不解的是, 即使调用自己所创建的WebService, 使用动态方式调用也不能成功, 总会提示一个异常:
Exception in thread "main" java.lang.IllegalStateException: Unable to write generated Java files for schemas: null
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:351)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:234)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:227)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:182)
at com.client.Test.dynamicStudent(Test.java:30)
at com.client.Test.main(Test.java:38)
Caused by: java.lang.reflect.UndeclaredThrowableException
at $Proxy29.build(Unknown Source)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:349)
... 5 more
Caused by: java.lang.NoSuchMethodException:
com.sun.codemodel.internal.JCodeModel.build(java.lang.Object)
at java.lang.Class.getMethod(Class.java:1605)
at org.apache.cxf.common.util.ReflectionInvokationHandler.invoke(ReflectionInvokationHandler.java:50)
... 7 more
异常信息的最后一个Caused by给了我线索:
java.lang.NoSuchMethodException:
com.sun.codemodel.internal.JCodeModel.build(java.lang.Object)
遍历工程所用jar文件, 居然没有找到internal包下的类JCodeModel;
但报的异常是NoSuchMethodException, 而不是ClassNotFoundException, 表明该类是存在的, 可能包路径发生了变化, 遂STFG(search the fUcking google. 从陈皓老师的博文学到的 - - 囧), 最终发现该类现存在于jaxb-xjc-2.2.4-1.jar中, 包路径为com.sun.codemodel, 而不是异常中所提示的com.sun.codemodel.internal;
为什么会这样? 难道是我的jaxb-xjc jar包的版本不对?
遂通过http://jaxb.java.net/, 对比jaxb2.0.1 -- 2.2.5之间的所有版本, 均没有找到包com.sun.codemodel.internal...
Ok, 让我们继续查找jaxb1.x版本的jar包;
幸运的是, 在页面[url]http://jaxb.java.net/nonav/2.0.1/docs/jaxb-1_0.html [/url], 终于有所发现:
JAXB 2.0 is backwards compatible with JAXB 1.0 - you can deploy your existing 1.0 applications on the 2.0 runtime (provided that you also bundle the jaxb1-impl.jar) and they should run without modification.
查看我的项目的类库, 刚好缺少了这么一个jaxb-impl.jar包,,, 加上该包(我使用的是jaxb-impl-2.2.4-1.jar), 再次运行动态调用天气预报WebService的服务, Congratulations! 这个异常被干掉了!
但是, 不要高兴的太早, 服务并没有调用成功, 因为又回到了最开始遇到的问题:
<s:element ref="s:schema" />,
undefined element declaration 's:schema'
at line 85 column 41 of schema
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
具体调用代码如下:
- package com.client;
- import org.apache.cxf.endpoint.Client;
- import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
- public class Test {
- public static void main(String[] args) throws Exception {
- JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
- Client client = dcf.createClient(
- "http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl");
- Object[] res = client.invoke("getSupportProvince");
- System.out.println("Echo response: " + res[0]);
- }
- }
值得欣慰的是, 在补充了jaxb-impl-2.2.4-1.jar之后, 可以通过动态方式成功调用自己创建的WebService服务了, 详见下节;
四.使用JaxWsDynamicClientFactory动态调用自己创建的WebService服务
服务接口及实现类很简单:
接口 com.service.StudentService:
- package com.service;
- import javax.jws.WebParam;
- import javax.jws.WebService;
- @WebService
- public interface StudentService {
- String helloStudent(@WebParam(name="text")String name);
- }
实现类 com.service.impl.StudentServiceImpl:
- package com.service.impl;
- import javax.jws.WebService;
- import com.service.StudentService;
- @WebService(endpointInterface="com.service.StudentService", targetNamespace="http://service.com/")
- public class StudentServiceImpl implements StudentService{
- public String helloStudent(String name) {
- return "hello " + name;
- }
- }
server类: com.jettyServer.ServerForJetty:
- package com.jettyServer;
- import javax.xml.ws.Endpoint;
- import com.service.impl.StudentServiceImpl;
- public class ServerForJetty {
- public static void main(String[] args) throws InterruptedException {
- StudentServiceImpl implementor = new StudentServiceImpl();
- String address = "http://localhost:9000/student";
- Endpoint.publish(address, implementor);
- }
- }
client类:com.client.Test
- package com.client;
- import org.apache.cxf.endpoint.Client;
- import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
- public class Test {
- public static void main(String[] args) throws Exception {
- JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
- Client client = dcf.createClient("http://localhost:9000/student?wsdl");
- Object[] res = client.invoke("helloStudent", "LeeThinker");
- System.out.println("Echo response: " + res[0]);
- }
- }
先启动JettyServer, 后访问http://localhost:9000/student?wsdl, 成功刷新出wsdl, Ok, 服务顺利启动!
再执行Test的main方法, Congratulations! 这次真正使用Dynamic的方式, 在不需要通过wsdl2java生成客户端java类文件的情况下, 成功调用WebService服务!
至于不能通过这种方式成功调用
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
的问题, 还需要在进一步学习Schema和DTD的知识才能解答;
五.小结:
虽未能通过Dynamic的方式成功调用天气预报服务, 好歹wsdl2java生成客户端调用类
的方式是可行的.
六.其他问题:
6.1.@WebService声明问题
在"四.使用JaxWsDynamicClientFactory调用自己创建的WebService服务"中
自定义服务接口的实现类com.service.impl.StudentServiceImpl的类声明之前, 仅注释声明了@WebService, 而没有后边的(endpointInterface="com.service.StudentService",
targetNamespace="http://service.com/"), 这时使用动态代理方式调用该服务时, 会发生异常:
Exception in thread "main"
org.apache.cxf.common.i18n.UncheckedException: No operation was found with the name {http://impl.service.com/}helloStudent.
大概还是因为WSDL的基础知识不够过硬吧, STFG后, 在
http://lost-alien.iteye.com/blog/1175859 找到答案:
在com.service.impl.StudentServiceImpl的类声明之前, 正确注释了
@WebService(
endpointInterface="com.service.StudentService", targetNamespace="http://service.com/")之后,
再使用动态方式调用该服务, 一切顺利!
具体原因还有待分析, 认识和理解!
6.2.关于CXF wsdl2java生成的调用远程服务的客户端java类文件
在"四.使用JaxWsDynamicClientFactory调用自己创建的WebService服务"中所描述的自定义WebService服务中, 若使用JaxWsServerFactoryBean的调用方式, 那么首先需要通过wsdl2java生成客户端必需的java类文件;
将通过自己的wsdl生成的客户端java类文件的目录结构&类名称,
和wsdl2java http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
这个wsdl文件后生成的java类文件的目录结构&类名称, 对比之后, 发现差距明显:
对比可以清楚的看到, 自己的wsdl生成的客户端类文件, 其java类文件名及其混乱, 始终没能弄懂为什么会这样? 还请各位同学多多指教!
实战CXF调用Webxml天气预报服务相关推荐
- Spring Cloud【Finchley】实战-04将订单微服务与商品微服务分别拆分为多模块
文章目录 Spring Cloud[Finchley]专栏 概述 Product微服务功能分析及多模块拆分 拆分原则 Step1. 调整主(父)工程的工程类型 packaging为pom Step2. ...
- 微服务介绍及Asp.net Core实战项目系列之微服务介绍
0.目录 整体架构目录:ASP.NET Core分布式项目实战-目录 一.微服务选型 在做微服务架构的技术选型的时候,以"无侵入"和"社区活跃"为主要的考量点, ...
- cxf 服务端soap报文_使用Apache CXF开发SOAP Web服务
cxf 服务端soap报文 在上一篇文章中,我逐步介绍了使用apache CXF开发简单的RESTFull服务的步骤. 在本文中,我将讨论使用CXF开发SOAP Web服务. 在继续前进之前,让我们先 ...
- 使用Apache CXF开发SOAP Web服务
在上一篇文章中,我逐步介绍了使用apache CXF开发简单的RESTFull服务的步骤. 在本文中,我将讨论使用CXF开发SOAP Web服务. 在继续前进之前,让我们了解构成SOAP Web服务的 ...
- [菜鸟SpringCloud实战入门]第九章:服务网关Zuul体验
前言 欢迎来到菜鸟SpringCloud实战入门系列(SpringCloudForNoob),该系列通过层层递进的实战视角,来一步步学习和理解SpringCloud. 本系列适合有一定Java以及Sp ...
- 微服务_SpringCloud微服务架构实战:高并发微服务架构设计
高并发微服务架构设计 作为一个 IT 从业人员,我们经常会碰到类似于下面的一些问题: 单个项目巨大而沉重,难以维护. 系统稳定性得不到更有效的保证. 怎样才能持续地提升系统的性能. 怎样才能快速地响应 ...
- 基于Spring Boot应用Apache CXF发布Web Services服务
记录:298 场景:使用Spring Boot应用Apache CXF发布Web Services服务,实现跨系统之间交互接口. 版本: JDK 1.8 Spring Boot 2.6.3 Apach ...
- php 当地天气预报,PHP调用全国天气预报数据接口查询天气示例
本文实例讲述了PHP调用全国天气预报数据接口查询天气.分享给大家供大家参考,具体如下: 基于PHP的聚合数据全国天气预报API服务请求的代码样例 本代码示例是基于PHP的聚合数据全国天气预报API服务 ...
- 分布式场景实战第七节 微服务场景实战
18 如何处理好微服务之间千丝万缕的关系? 17 讲讲解了服务间数据依赖的场景,除了这种场景之外,其实我们还会碰到服务间依赖太杂乱的场景,这一讲我们将围绕这个场景进行讨论,还是先把整个场景描述一下. ...
最新文章
- rtsp流+vue进行视频播放(海康威视、大华摄像头)
- 任意次序的n个烙饼最小反转次数求解 暑期学习笔记(十)
- 如何在CentOS 7上安装Apache
- timestamp 数据类型
- 元学习论文OPTIMIZATION AS A MODEL FOR FEW-SHOT LEARNING的简单理解
- linux下ftp服务器搭建详解
- MySQL性能优化最佳实践 - 02 MySQL数据库性能衡量
- OpenCV A-KAZE匹配的实例(附完整代码)
- 抖音最强python_装逼篇 | 抖音超火的九宫格视频是如何生成的,Python 告诉你答案...
- c盘怎么清理到最干净_系统垃圾太多,怎么一键彻底清理干净
- SplObserver观察者模式
- Python+Django+SAE系列教程6-----本地配置Django
- opencv python教程简书_OpenCV-Python教程:28.模板匹配
- Luogu1939 【模板】矩阵加速(数列)
- Xmind 中附件的存放位置
- 计算机组成原理——总线标准
- 【Python计量】statsmodels对虚拟变量进行回归
- 三次bezier曲线 MATLAB,Matlab 画二次及三次Bezier曲线,8控制点的B样条曲线
- zabbix触发器通过钉钉发送警报
- 「九章」刷屏的背后:万字长文解析,量子计算机和电子计算机各有何优劣?