一、WebService概述
什么是WebService,顾名思义,就是基于Web的服务,它使用Http方式接收和响应外部系统的某种请求,从而实现远程调用。WebService实际上就是依据某些标准,不关心对方使用的是何种语言,实现对外部其它应用程序提供跨平台、跨语言服务的一种技术。
使用WebService,我们可以调用互联网上查询天气信息的Web服务,然后将其嵌入到我们的程序中,当用户从我们的网点看到天气信息的时候,他会以为我们为他提供了很多的信息服务,但其实我们什么也没有做,只是简单调用了一下服务器上的一端代码而已。
之前曾经说过Spring的远程调用,实际上WebService的功能和Spring的远程调用完全相同,WebService的本质也就是远程调用,只不过Spring和WebService的实现原理不相同而已。比较WebService和Spring的远程调用:
1.Spring远程调用在网络上传输的是“串行化对象”,而WebService在网络上传输的是XML字符串。
2.Spring远程调用效率更高,因为它传输的是真正的“数据”,而为了满足传输的XML的规范,WebService需要将数据进行一层层的封装,比如服务端需要传递给客户端一个大小为100的List<Student>list,使用Spring的远程调用直接传递该对象到网络流即可,但是使用WebService却必须得将数据进行严格的规整以使其满足XML的规范(示例,实际上的传输规范并不是这样):
<List>
<Student>
<id>1</id>
<name>小张</name>
<sex>男</sex>
<age>13</age>
<phone>111111111</phone>
<email>11111@123.com</email>
</Student>
<Student>
<id>2</id>
<name>小李</name>
<sex>女</sex>
<age>15</age>
<phone>2222222</phone>
<email>22222@123.com</email>
</Student>
...此处省略98个Student...
</List>
这样导致的问题就是传输了大量的“无用字符”,也就是大量的标签了,实际上在上述的例子中标签所占据的字符数量几乎和要传递的数据量一样多,其效率之低是显而易见的。
3.spring远程调用要求两个程序都使用spring环境(java环境),但是WebService可以实现跨平台通信,也就是说即使两个程序之间使用的不是同一种语言,比如一个PHP的程序和Java的程序,他们也能够相互通信,这是WebService的最大卖点。
4.在不考虑通用性的情况下,如果程序两端都使用了Spring,那么就使用Spring的远程调用;如果平台语言不相同,则使用WebService;如果考虑到通用性,即需要向大众提供服务,那么一定得使用Webservice。
二、名词解释
1.WSDL
全名为WebService Description Language ,翻译过来就是Web服务描述语言。它使用XML描述服务的地址,服务提供的方法以及参数列表、返回值类型等,实际上就是一个Web服务的说明书,比如webxml.com.cn网站提供了天气预报查询的服务,对应的WSDL就是:http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl
2.SOAP
全名为Simple Object Access Protocol,翻译过来就是简单对象访问协议,SOAP是一种XML语言的协议,用于在网络上传输数据。
SOAP=XML+HTTP
SOAP是基于Http协议的,SOAP的组成:Envelope,这是必须的部分,以XML根元素的形式出现;Headers,可选;Body,必须的部分,包含要执行的服务器上的方法和发送到服务器上的数据。
三、在Java项目中发布第一个WebService服务
package com.kdyzm.ws; import javax.jws.WebService;
import javax.xml.ws.Endpoint; @WebService
public class MyWsServer {
public String calculate(int input){
return input*input+"";
}
public static void main(String[] args) {
Endpoint.publish("http://localhost:9090/ws", new MyWsServer());
System.out.println("server ready ......");
}
}
OK,一个最简单的WebService服务就发布了。
对以上的代码的说明:在Java中,使用EndPoint类发布服务,使用该类发布服务的方法是publish方法,该方法由两个参数,一个参数是发布服务的地址,另外一个参数是提供服务的类;当执行到publish方法的时候,程序会新开一个线程专门用于提供服务,主线程会继续执行下去,所以下面的打印的代码会不受影响的执行。
另外,提供服务的类至少应当提供一个非静态方法否则服务启动不起来。
如何查看wsdl?在浏览器上输入http://localhost:9090/ws?wsdl,回车即可查看wsdl内容:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
JAX-WS RI 2.1.6 in JDK 6. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
JAX-WS RI 2.1.6 in JDK 6. -->
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://ws.kdyzm.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://ws.kdyzm.com/"
name="MyWsServerService">
<types>
<xsd:schema>
<xsd:import namespace="http://ws.kdyzm.com/"
schemaLocation="http://localhost:9090/ws?xsd=1"></xsd:import>
</xsd:schema>
</types>
<message name="calculate">
<part name="parameters" element="tns:calculate"></part>
</message>
<message name="calculateResponse">
<part name="parameters" element="tns:calculateResponse"></part>
</message>
<portType name="MyWsServer">
<operation name="calculate">
<input message="tns:calculate"></input>
<output message="tns:calculateResponse"></output>
</operation>
</portType>
<binding name="MyWsServerPortBinding" type="tns:MyWsServer">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"></soap:binding>
<operation name="calculate">
<soap:operation soapAction=""></soap:operation>
<input>
<soap:body use="literal"></soap:body>
</input>
<output>
<soap:body use="literal"></soap:body>
</output>
</operation>
</binding>
<service name="MyWsServerService">
<port name="MyWsServerPort" binding="tns:MyWsServerPortBinding">
<soap:address location="http://localhost:9090/ws"></soap:address>
</port>
</service>
</definitions>
四、使用wsimport命令生成本地调用代码。
如果能力足够高的话,直接阅读wsdl文件就能够直接向服务器请求并获取服务了,但是一般来说这么做非常的复杂,为了提高开发效率,在java环境下我们使用wsimport命令生成本地调用代码,然后直接使用这些生成的代码就可以了。
wsimport命令是jdk提供的命令,但是应当注意的是,该命令只是在jdk1.6.0_24及以上的版本才提供,所以如果使用了jdk1.5的版本肯定不能支持。
wsimport命令能够解析指定的wsdl文件并将根据wsdl文件中的配置生成对应的java代码并将其编译成class文件。
wsimport命令的常用参数:
-d <目录名>:将会生成.class文件,默认参数,就算不使用该参数也会自动加上。
-s <目录名>:将会生成java文件
-p <生成的包名>:将生成的类放到指定的目录下。
步骤:使用命令生成本地调用代码:wsimport -s . http://localhost:9090/ws?wsdl
任务执行完毕之后,会在当前目录下生成一个文件夹,文件夹中存放着所有将要使用到的java类和编译之后的.class文件
将所有的class文件删除掉,之后将文件夹直接拷贝到项目中即可使用。
注意事项:如果是我们自己发布的服务,我们使用wsimport命令肯定能够解析成功,但是如果我们使用网络上其它站点提供的服务,那么在生成本地调用代码的时候很有可能会生成失败。比如我们经常回到这个网站上找相关的免费服务:http://www.webxml.com.cn/zh_cn/index.aspx,在这个网站上有一个“天气预报查询”的服务,它也提供了一个wsdl文档,但是我们在解析该文档生成本地调用代码的时候会生成失败。解决方法参考:http://blog.sina.com.cn/s/blog_924d6a570102w203.html
五、使用本地调用代码的方法
以之前发布的服务为例。
新建一个普通类型的java工程,将文件夹中的所有.class文件删除掉之后,将包括文件夹在内的所有文件都拷贝到项目中。
将生成的代码拷贝到项目中之后很有可能会报错,提示Service类中没有对应的构造方法,解决方法参考http://blog.sina.com.cn/s/blog_924d6a570102w21v.html
接下来只需要使用这些类就可以了,如何使用这些类,应当参考wsdl文档。
客户端的测试代码:
package com.kdyzm.test; import com.kdyzm.ws.MyWsServer;
import com.kdyzm.ws.MyWsServerService; public class Main {
public static void main(String[] args) {
MyWsServerService myWsServerService=new MyWsServerService();
MyWsServer myWsServer=myWsServerService.getMyWsServerPort();
String result=myWsServer.calculate(2);
System.out.println(result);
}
}
控制台输出结果是4(客户端)。
六、使用Web Service Exployer工具查看请求信息和相应信息。
java ee版本的eclipse中(java ee视图)提供了一种专门用于WebService的浏览器,名字为Web Service Exployer
直接进入到该视图中,然后切换到WSDL Page视图,并点击clear按钮,最终显示的界面如下:
在地址栏中输入wsdl的地址,这里是http://localhost:9090/ws?wsdl,并回车
接下来会显示出所有的服务(类)和服务下的方法,图略。
下一步就是单击方法名,然后给方法添加实参发出请求之后查看请求的时候的请求信息和响应信息,这里还是以2为例,最终结果是这样的:
显示返回值是4,然后单击source
这也不是我想要的,直接对着框框右键“查看源代码”,可以看到SOAP的请求信息和SOAP的响应信息:
请求信息:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://ws.kdyzm.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<q0:calculate>
<arg0>2</arg0>
</q0:calculate>
</soapenv:Body>
</soapenv:Envelope>
响应信息:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:calculateResponse xmlns:ns2="http://ws.kdyzm.com/">
<return>4</return>
</ns2:calculateResponse>
</S:Body>
</S:Envelope>
可以看到无论是请求信息还是响应信息都是以Envelope为根节点,而且接下来都是Body节点,这点是符合SOAP协议的规范的。
【Java EE 学习 80 上】【WebService】的更多相关文章
-
【Java EE 学习 74 上】【数据采集系统第六天】【使用Jfreechart的统计图实现】【Jfreechart的基本使用方法】
之前已经实现了数据的采集,现在已经有了基本的数据,下一步就需要使用这些数据实现统计图的绘制了.这里使用Jfreechart实现这些统计图的绘制.首先看一下Jfreechart的基本用法,只有知道了它的 ...
-
【Java EE 学习 25 上】【网上图书商城项目实战】
一.概述 1.使用的jdk版本:1.6 2.java EE版本:1.6 3.指导老师:传智播客 王建 二.小项目已经实现的功能 普通用户: 1.登陆 2.注册 3.购物 4.浏览 管理员用户(全部管理 ...
-
【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】
不考虑第三方框架,如果只使用JDK提供的API,那么可以使用三种方式调用WebService服务:另外还可以使用Ajax调用WebService服务. 预备工作:开启WebService服务,使用jd ...
-
【Java EE 学习 67 上】【OA项目练习】【JBPM工作流的使用】
OA项目中有极大可能性使用到JBPM框架解决流程控制问题,比如请假流程.报销流程等等. JBPM:JBoss Business Process Management,翻译过来就是业务流程管理.实际上就 ...
-
【Java EE 学习 83 上】【SpringMVC】【基本使用方法】
一.SpringMVC框架概述 什么是SpringMVC?SpringMVC是一个和Struts2差不多的东西,他们的作用和性质几乎是相同的,甚至开发效率上也差不多,但是在运行效率上SpringMVC ...
-
【Java EE 学习 82 上】【MAVEN基本安装和使用方法】
一.Maven概述 1.什么是Maven? Maven中文意思是"行家"."专家",它是一种跨平台的项目管理工具. 2.Maven有什么作用? Maven能够实 ...
-
【Java EE 学习 79 上】【mybatis 基本使用方法】
一.简介 mybatis类似于hibernate,都是简化对数据库操作的框架,但是和hibernate不同的是,mybatis更加灵活,整体来说框架更小,这体现在它需要我们手写SQL语句,而hiber ...
-
【Java EE 学习 78 上】【数据采集系统第十天】【Service使用Spring缓存模块】
一.需求分析 调查问卷中或许每一个单击动作都会引发大量的数据库访问,特别是在参与调查的过程中,只是单击“上一页”或者“下一页”的按钮就会引发大量的查询,必须对这种问题进行优化才行.使用缓存策略进行查询 ...
-
【Java EE 学习 77 上】【数据采集系统第九天】【通过AOP实现日志管理】【通过Spring石英调度动态生成日志表】【日志分表和查询】
一.需求分析 日志数据在很多行业中都是非常敏感的数据,它们不能删除只能保存和查看,这样日志表就会越来越大,我们不可能永远让它无限制的增长下去,必须采取一种手段将数据分散开来.假设现在整个数据库需要保存 ...
随机推荐
-
Csharp--Read Csv file to DataTable
在网上找的资料都不怎么好使,许多代码一看就知道根本没有考虑全面. 最后找到一个好用的,在codeproject上,这位老兄写成了一个framework,太重了. http://www.codeproj ...
-
codeforces 484C Strange Sorting Codeforces Round #276 (Div. 1) C
思路:首先 他是对1到k 元素做一次变换,然后对2到k+1个元素做一次变化....依次做完. 如果我们对1到k个元素做完一次变换后,把整个数组循环左移一个.那么第二次还是对1 到 k个元素做和第一次一 ...
-
BugTracker 加入发Mail的功能
BugTracker部署好之后,发现增加bug不能mail提醒.于是补上这个功能记录在此,方法是次要的,主要是找到地方.需要3步.吐槽下Asp的代码风格看的真心蛋疼.... 一.发送mail(主要是找 ...
-
CharSequence 接口
java中有些方法需要用到CharSequence 类型的参数,笔者百度了一下,总结出一下几点: 1.CharSequence 是一个接口,可以直接用“=”赋值一段字符串,但是不能用new新建一个对象 ...
-
2015.07.12hadoop伪分布安装
hadoop伪分布安装 Hadoop2的伪分布安装步骤[使用root用户用户登陆]other进去超级用户拥有最高的权限 1.1(桥接模式)设置静态IP ,,修改配置文件,虚拟机IP192.168. ...
-
Spring MVC__自定义日期类型转换器
WEB层采用Spring MVC框架,将查询到的数据传递给APP端或客户端,这没啥,但是坑的是实体类中有日期类型的属性,但是你必须提前格式化好之后返回给它们.说真的,以前真没这样做过,之前都是一口气查 ...
-
Node项目的Restful化
提倡Restful风格的目的或者作用主要是,结构清晰.符合标准.易于理解.扩展方便. 个人把Restful简单粗暴地理解为:路由不包含动词. 怎么做到路由不包含动词呢?答案是,启用常用的GET和POS ...
-
将mssql数据库高版本迁移到低版本
将mssql数据库高版本迁移到低版本 在低版本目标数据库中创建目标空数据库[TargetDb] ,注意新建数据库即可,不要创建任何表 在低版本数据库中,选中[服务器对象=>链接服务器] 右键[新 ...
-
contain与compareDocumentPosition
contain方法由IE创建,用于判断元素之间是否是父亲与后代的关系,例如:如果A元素包含B元素,则返回true,否则,返回false eg: <div id= "a"> ...
-
第一章:初识JAVA
一:计算机语言发展史 机器语言:典型的二进制文件和计算机交流. 汇编语言: 通过大量的标识符表示一些基本操作来和计算机做交流. 高级语言:通过常见的英语指令来编写程序,完成沟通 常见高级语言 Java ...