WebService学习(刚开始)
————————————————————————————————————————————————————————————————————
WebService:跨平台跨语言的远程调用技术。WebService即web服务。
Java*有三种WebService规范,分别是JAX-WS(JAX-RPC)、JAXM&SAAJ、JAX-RS。
WebService三要素:soap、wsdl、uddi
SOAP协议:是一种网络协议
soap即Simple Object Access Protocol简易对象访问协议。用于跨平台应用程序之间的通信,被设计用来通过因特网(http)进行通信。SOAP = HTTP+XML,其实就是通过HTTP发xml数据。很简单并可扩展支持面向对象,允许您跨越防火墙。
Socket是所有通信的基础也是语言个无关平台无关。使用的是tcp协议,传输效率高。适合传递大数据高并发场景,高并发的情况需要实现多线程并且使用到线程池,编码复杂。Socket只是流的传输,传输的格式需要程序员自己定义。Sockt的高并发框架mina。
Webservice使用的是soap协议,soap协议基于http协议的应用层协议,本质就是http+xml。Soap协议是w3c标准,传输效率低。使用传输数据不是太大的场合,也是支持高并发的,受限于web容器。支持soap协议和wsdl两者都是国际通用标准,不需要自定义数据格式,只需要面向对象开发。
WSDL
WebService的使用说明书。描述了WebService的服务器地址以及WebService服务接口、参数、返回值。(从下往上阅读)
1、先找service节点:每个wsdl中,有且只有一个service节点。也叫服务视图节点。service中有port节点服务端端口。
2、根据port节点的binding属性找binding节点。根据binding节点的type属性找portType节点。
3、portType节点就是我们定义的SEI服务的接口类型。Prottype中的operation 节点就是方法名称。
4、operation 节点的input就是参数的定义,output就是返回值的定义。
5、Input有个属性叫做message,message属性对应message节点。其中有一个element,对应element节点。
6、Element节点定义中xsd中。定义了数据的类型。参数和返回值都在其中定义。
小例子:( 天气查询系统(Base) )
服务器端:
1、编写SEI,即接口
package service; public interface WeatherInterface { String queryWeather(String cityName); }
2、编写SEI实现类,需实现SEI接口,还需在实现类上添加@WebService注解
package service; import javax.jws.WebService; @WebService
public class WeatherInterfaceImpl implements WeatherInterface { @Override
public String queryWeather(String cityName) {
System.out.println("发送的城市名称为:" + cityName); String result = "高温预警!!!"; return result;
} }
3、发布服务。(使用Endpoint的静态方法publish)
package service; import javax.xml.ws.Endpoint; public class WeatherServer { public static void main(String[] args) { Endpoint.publish("http://127.0.0.1:11111/weather", new WeatherInterfaceImpl()); } }
(注意:如果你使用的IP地址是本机的,只能自己访问,但是如果你使用的是外网IP,类似196.128.*.*,请将项目放入网络容器中,即tomcat发布)
4、查看效果:访问 http://127.0.0.1:11111/weather?wsdl 就可以看到wsdl说明书,启动成功!
客户端:
可以使用简单的wsimport来自动生成客户端(在jdk安装目录bin中,有一个wsimport命令,可根据wsdl文档生成客户端调用代码)
新建Java工程,使用cmd定位到src目录下,运行命令:wsimport -s . http://127.0.0.1:11111/weather?wsdl
成功之后,项目结构如下:
此时就可以调用服务器端方法了:
1、创建一个服务视图对象
2、从服务试图获得porttype(SEI)对象
3、调用服务端方法
4、打印结果
package client; import service.WeatherInterfaceImpl;
import service.WeatherInterfaceImplService; public class WeatherClient { public static void main(String[] args) { WeatherInterfaceImplService service = new WeatherInterfaceImplService(); WeatherInterfaceImpl portType = service.getWeatherInterfaceImplPort(); String result = portType.queryWeather("武汉"); System.out.println(result); } }
扩展(公网天气查询)
服务器使用第三方:下载地址
其中client.java类如下:
public static void main(String[] args) {
//创建服务视图
//WeatherWebService service=new WeatherWebService(); URL url = null;
try {
url = new URL("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL");
} catch (MalformedURLException e) {
e.printStackTrace();
}
QName qName=new QName("http://WebXml.com.cn/", "WeatherWebService"); Service service=Service.create(url,qName);
WeatherWebServiceSoap portType=service.getPort(WeatherWebServiceSoap.class);
//service.getWeatherWebServiceSoap(); ArrayOfString arrayOfString=portType.getWeatherbyCityName("武汉");
for (String string : arrayOfString.getString()) {
System.out.println(string);
}
}
上面即为使用外部WebService来更新信息