昨天没事干看了会webService,今天没事干就把昨天的整理下。
学习WebService应该从以下几点来出发:
1.什么是webService?
2. 和webService同类型的还有哪些?相比那些webService的优缺点?
3.怎么用webService?
现在我们一步一步来看。
1.什么是WebService?
字面意思就是网络服务,其实也就是在网络的服务.
那么是什么服务呢?
计算机说来说去最大的服务还是数据,webService也是在网络上处理数据的服务
要讲到WebService就不得不讲到一些开发的背景知识:
现实开发中会有很多的对于数据查询的需求。
比如查询天气,没有比气象部门更了解的了,查询手机号,没有比三大运营商更了解的了。
我们想要查询这方面的数据,就应该去查询这些特定部门暴露出来的数据,
这样一定是最准确,最全面的。
与此同时,这些部门已经暴露了数据,
我们就没有必要在本地在建立一个数据库进行数据的被查询了。
这样既不符合不造同一个轮子的要求,也非常的浪费项目的资源。
尤其在我们手机端。不断的去查询数据库,
不仅耗电,也非常的耗性能影响速率,并且一个数据库如果过于庞大也会影响apk的大小。
因此我们在查询一些非常广泛的数据时都是从专业的网站上去取数据的。
这个就涉及到怎么取得问题。
webService就是从特定网络中取数据的一种方式。
webService是基于soap协议的,它把soap协议进行了封装,来进行数据的传输。
而soap协议就是http+xml,利用http来进行xml数据的传输,是基于Post的请求
http是应用层的东西,它是基于传输层的tcp协议。
这样也就大致搞清楚了webService的基本实现。
2.和webService同类型的还有哪些?相比那些webService的优缺点?
肯定还有其他取得方式,主要都包括:
1)rpc:
remote procedure call:远程过程调用
优点跨平台,缺点不面向对象
2)rmi:
remote method invocation:远程方法调用
优点面向对象,缺点c/s只能是java写,不跨平台
Webservice对RPC进行了升级,采用对http协议封装的soap协议进行通信
所以综上可知WebService是集合了前两者的优点的,它去网络端取数据的方式是跨平台的,
取回数据后对数据的处理也是面向对象的开发。
1:跨平台-->就是客户端和服务端可以是用c/java/c#/c++等任何一门语言编写
,可以是手机,平板,电脑。
都不影响webService的使用。
2.面向对象-->取回来的数据我们可以封装成对象,用面向对象的思想进行开发。
缺点:协议比较固定,不能变通,也就是麻烦的嫌疑。
3.WebService的使用
WebService常见的使用方式分为两种:jax-ws和cxf
我们今天先来简单研究下如何用jax-ws进行webService的开发
什么是jax-ws?
Java API for XML-Based Webservices ,从java5开始支持JAX-WS2.0版本
JDK中自带的.所以用javaSe开发这个不需要任何工具,只要jdk版本在1.5以上就行
下面先来写一个简单的例子,
来看看利用jax-ws如何开发webService的服务端和客户端,
然后取网上
气象局的一个数据来进行实际客户端webService的开发。
实际开发中我们应该是不用开发服务端的。
第一案例:
服务端代码
JAXW_Server.java
/**
* 利用JAXWS进行的webService的服务器端的开发
*
* JAXWS是jdk1.6以后出来的,内置到了java的jdk1.6版本及以上版本中。
* 服务端开发步骤:
* 1.首先要在类的最上层加@WebService
* 2.定义一个被客户端调用的方法:public not static
* 3.EndPoint.publish("http://ip:duankou/biaoshi","暴露方法的实现类");
* @author szxgg
*
*/
@WebService
public class Server_JAXWS {
private static String url = "http://10.10.144.182:12345/weather";
/**
* 服务端暴露的方法
* @param cityName 城市名称,由客户端传入
* @return 结果,传递给服务端
*/
public String getWeather(String cityName){
return cityName+"雾霾";
}
public static void main(String[] args) {
Endpoint.publish(url, new Server_JAXWS());
}
}
利用jax-ws开发服务端有以下三个步骤:
1.在类前见注释:@WebService
2.有一个非静态的公共方法,用于webService客户端的调用,这个方法最终是要暴露出去的
3.在主函数中执行EndPoint.publish(ip+port,实现类的实例);
然后将这个程序运行起来,注意,这个程序不运行就相当于服务器没开,就不可能被调用到数据。
然后服务器端就算是开发完成了,下面一步不是去开发客户端,而是查看基于服务端运行生成的wsdl文档。
何为wsdl文档?
WebServiceDescriptionLanguage,描述webService服务端的文件。
也就是说这个webService服务端的东西对于我们客户端调用而言就是一个黑匣子,我们不知道怎么玩他,
而这个文档也就给了我们帮助,但是其实如果第一次看这个帮助是没多大的,因为比较复杂,我们自己的很简单了。
怎么获得当前webService服务端的wsdl文档?
打开浏览器,输入ip+port(程序中的)?wsdl,就可以看了,前提是服务端程序运行
http://10.10.144.182:12345/weather?wsdl,得到数据如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. -->
<!-- Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. -->
-<definitions name="Server_JAXWSService" targetNamespace="http://server.jaxws.ktouch.cn/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://server.jaxws.ktouch.cn/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
-<types>
-<xsd:schema>
<xsd:import schemaLocation="http://10.10.144.182:12345/weather?xsd=1" namespace="http://server.jaxws.ktouch.cn/"/>
</xsd:schema>
</types>
-<message name="getWeather">
<part name="parameters" element="tns:getWeather"/>
</message>
-<message name="getWeatherResponse">
<part name="parameters" element="tns:getWeatherResponse"/>
</message>
-<portType name="Server_JAXWS">
-<operation name="getWeather">
<input message="tns:getWeather" wsam:Action="http://server.jaxws.ktouch.cn/Server_JAXWS/getWeatherRequest"/>
<output message="tns:getWeatherResponse" wsam:Action="http://server.jaxws.ktouch.cn/Server_JAXWS/getWeatherResponse"/>
</operation>
</portType>
-<binding name="Server_JAXWSPortBinding" type="tns:Server_JAXWS">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
-<operation name="getWeather">
<soap:operation soapAction=""/>
-<input>
<soap:body use="literal"/>
</input>
-<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
-<service name="Server_JAXWSService">
-<port name="Server_JAXWSPort" binding="tns:Server_JAXWSPortBinding">
<soap:address location="http://10.10.144.182:12345/weather"/>
</port>
</service>
</definitions>
这个看得顺序就是:
1.找service标签,是整个webService的试图
2.根据service中的tns找到binding标签
3.根据binding标签中的tns找到<portType>
4.基本上找到portType就够了,PortType下有一个子标签operation就是暴露的方法名,我们客户端就是调用
这些方法。
5.要是想查看这个方法的内部详细,还需要打开<schemalocation>对应的网址:
-<xs:schema targetNamespace="http://server.jaxws.ktouch.cn/" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://server.jaxws.ktouch.cn/">
<xs:element type="tns:getWeather" name="getWeather"/>
<xs:element type="tns:getWeatherResponse" name="getWeatherResponse"/>
-<xs:complexType name="getWeather">
-<xs:sequence>
<xs:element type="xs:string" name="arg0" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
-<xs:complexType name="getWeatherResponse">
-<xs:sequence>
<xs:element type="xs:string" name="return" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
下面面临的问题是这些xml数据我们怎么为我们客户端所用?
主要就是把这些xml通过一个工具转化成java代码(因为我们用java写,如果用其他语言写可以用其他工具转成其他代码,这就是跨平台性的体现)
这个工具是jdk1.5以上自带的,叫做wsimport,在cmd命令行中进行如下操作,就可以完成数据的转化了。
wsimport –d . http://10.10.144.182:12345/weather?wsdl
这样就生成了一个代码包:
然后把它考到我们的项目下面如图:
然后就进行客户端的开发,代码:
/**
*调用webService的客户端
* @author szxgg
*
*/
public class Client_Test {
public static void main(String[] args) {
//得到服务节点
ServerJAXWSService serverJAXWSService = new ServerJAXWSService();
//根据服务节点(视图)得到binding标签
ServerJAXWS serverJAXWSPort = serverJAXWSService.getServerJAXWSPort();
//根据binding标签得到调用的方法
System.out.println(serverJAXWSPort.getWeather("北京"));
}
}
运行
起来就可以得到结果了,结果如下图:
以上算是这个我们自己开发了基于jax-ws的简单的服务端和客户端。
下面我们模拟一下真实开发中使怎么开发的。
1)首先是找到需要的数据对应的webService文件
2)找到后打开查看一下它的wsdl
3)利用wsimport进行解析,解析成java代码
4)进行开发
下面上代码就是我们找的一个气象局的代码,我查的是甘肃省的天气
下载文件.wsdl到本地,在本地可以操作。
查看文件:file:///D:\ws\WEATHER.wsdl
然后进行解析
wsimport –d . file:///D:\ws\WEATHER.wsdl 这样就把这个网站的文件数据解析成了类对象
这样就生成了包,拷贝到自己的工程
代码:
public class Demo {
public static void main(String[] args) {
//得到service对象
WeatherWebService weatherWebService = new WeatherWebService();
//通过service得到需要的binding
WeatherWebServiceSoap weatherWebServiceSoap = weatherWebService.getWeatherWebServiceSoap12();
//根据binding找到需要的方法
List<String> cities = weatherWebServiceSoap.getSupportCity("甘肃").getString();
for (String city : cities) {
System.out.println("甘肃支持的城市有:"+city);
String regEx="[^0-9]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(city);
String realCity = m.replaceAll("".trim());
System.out.println("realCity code:"+realCity);
//在查询每一个城市的天气
List<String> supports = weatherWebServiceSoap.getWeatherbyCityName(realCity).getString();
//当前城市的城市名称
String current_city = supports.get(1);
//今天气温
String today_temp = supports.get(5);
//第二天气温
String tommorrow_temp = supports.get(12);
//第三天气温
String third_temp = supports.get(17);
//城市介绍
String city_des = supports.get(22);
System.out.println("城市:"+current_city);
System.out.println("今日气温:"+today_temp+",明日气温:"+tommorrow_temp+",后日气温:"+third_temp);
System.out.println("城市介绍:"+city_des);
System.out.println("==================================================");
}
}
}
输出
结果如下图:
在哪体现的跨平台:
数据转化成代码这一步
1.jdk--
2.c:
android中使用它不能这么直接,要调第三方类库。这个我们后面再说
最后说明一下,wsdl文件还可以放到ecplise中进行查看,有视图模式,可以帮助我们查看: