一、概念
1、什么是webservice
Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。
Web service 就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。这就是说,你能够用编程的方法通过Web来调用这个应用程序。我们把调用这个Web service 的应用程序叫做客户。例如,你想创建一个Web service ,它的作用是返回当前的天气情况。那么你可以建立一个jSP页面,它接受邮政编码作为查询字符串,然后返回一个由逗号隔开的字符串,包含了当前的气温和天气。要调用这个jSP页面,客户端需要发送下面的这个HTTP GET.
Web service平台是一套标准,它定义了应用程序如何在Web上实现互操作性。你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web service标准对这些服务进行查询和访问
2、JAX-WS
JAX-WS 的全称为Java API for XML-Based Webservices ,早期的基于SOAP 的JAVA 的Web 服务规范JAX-RPC(Java API For XML-Remote Procedure Call)目前已经被JAX-WS 规范取代。从java5开始支持JAX-WS2.0版本,Jdk1.6.0_13以后的版本支持2.1版本,jdk1.7支持2.2版本。
采用标准SOAP(Simple Object Access Protocol) 协议传输,soap属于w3c标准。Soap协议是基于http的应用层协议,soap协议传输是xml数据。
采用wsdl作为描述语言即webservice使用说明书,wsdl属w3c标准。
xml是webservice的跨平台的基础,XML主要的优点在于它既与平台无关,又与厂商无关。
XSD,W3C为webservice制定了一套传输数据类型,使用xml进行描述,即XSD(XML Schema Datatypes),任何编程语言写的webservice接口在发送数据时都要转换成webservice标准的XSD发送。
3、JAX-RS
为了让 WS 的开发与使用变得更加简单、更加轻量级,于是出现了另一种风格的 WS,名为 JAX-RS(JSR-339),全称 Java API for RESTful Web Services,同样也是一种规范,同样也有若干实现,cxf是其中比较著名的一种。
JAX-RS 是JAVA 针对REST(Representation State Transfer)风格制定的一套Web 服务规范,由于推出的较晚,该规范(JSR 311,目前JAX-RS 的版本为1.0)并未随JDK1.6 一起发行。
支持JAX-RS服务规范的框架有:
CXF——XFire和Celtix的合并(一个由IONA赞助的开源ESB,最初寄存在ObjectWeb上)。
Jersey——Sun公司的JAX-RS参考实现。
RESTEasy——JBoss的JAX-RS项目。
Restlet——也许是最早的REST框架了,它JAX-RS之前就有了。
注:REST 是一种软件架构模式,只是一种风格,rest服务采用HTTP 做传输协议。
4、soap
Simple Object Accrss Protocol,简单对象访问协议是在分散或分布式的环境中交换信息的简单的协议,是一个基于XML的协议,它包括四个部分:(1)SOAP封装(envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它,以及如何处理它们的框架;
(2)SOAP编码规则,用于表示应用程序需要使用的数据类型的实例。
(2)SOAP RPC 表示远程过程调用和应答的协定。
(4)SOAP绑定(binding),使用底层协议交换信息。
Web Service 希望实现不同的系统之间能够用“软件-软件对话”的方式相互调用,打破了软件应用、网站和各种设备之间的格格不入的状态,实现“基于Web无缝集成”的目标。
5、wsdl
WSDL(Web Service Description Language),是一个用来描述Web服务(Web Service)和说明如何与Web服务通信的XML语言。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的,这将是一个很大的好处。
(1)wsdl的阅读方法
是从下往上读。
每个wsdl有且只有一个Service节点。
1、先找Service节点
2、Service节点中找port节点。每个port对应一个PortType。
3、Port节点对应一binding节点。每个binding节点对应一个PortType
4、PortType中有operation 节点就是服务的方法。
5、operation 中有Input(参数)和output(返回值)
6、Input(参数)和output(返回值)对应message节点
7、Message对应element节点。Element节点对应complexType节点描述了参数及返回值的数据类型。
(2)使用注解规范wsdl
@WebService: 定义服务,在public class上边。
targetNamespace:指定命名空间。
name:portType的名称。
portName:port的名称。
serviceName:服务名称。
@WebResult:定义返回值。
name:返回结果值的名称。
@WebParam:定义参数。
name:指定参数的名称。
@WebMethod
exclude:排除指定的方法。
默认情况下,SEI实现类中所以的public方法会发布成服务方法。
如果不想把public方法发布成服务方法,需要使用@WebMethod注解。把此方法排除。在实现类中至少有一个方法发布为服务方法。
http://127.0.0.1:12345/weather?wsdl
http://127.0.0.1:12345/weather?xsd=1
作用: 通过注解,可以更加形像的描述Web服务。对自动生成的wsdl文档进行修改,为使用者提供一个更加清晰的wsdl文档。
当修改了WebService注解之后,会影响客户端生成的代码。调用的方法名和参数名也发生了变化。
6.UDDI
UDDI 是一种目录服务,通过它,企业可注册并搜索 Web services。企业将自己提供的Web Service注册在UDDI,也可以使用别的企业在UDDI注册的web service服务,从而达到资源共享。
UDDI旨在将全球的webservcie资源进行共享,促进全球经济合作。
但是使用webservice并不是必须使用UDDI,因为用户通过WSDL知道了web service的地址,可以直接通过WSDL调用webservice。
7、AXIS2和CXF选择
CXF、AXIS2都是在Java编程中webService技术的一种实现工具。为什么用CXF来实现webService:
1. Java的webService实现本身就是一个很耗性能的实现方案(xml与java对象之间在服务端以及客户端的互转比较消耗性能)
2. 目前java主流的webService应用以CXF、AXIS2为主;
3. 通过网络渠道的了解,目前CXF的效率要比AXIS2高出至少50%;
4. 另外有一个webService的工具metro的效率比CXF高出10%;
5. CXF的实现资料网上可以随便找出一大堆,metro的资料相对少一些;
6. CXF在java应用实现中已经很成熟,企业更倾向于用这样一个成熟的解决方案;
基于以上原因,我选择CXF来实现webService。
参考资料:
JavaWeb 服务: CXF 性能比较----CXF 与最新版本的 Axis2 和 Metro 之间的性能对比
http://www.ibm.com/developerworks/cn/java/j-jws14/
二、以annotation注解方式实现CXF开发webService应用
Apache CXF = Celtix + Xfire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。Apache CXF 是一个开源的 web Services 框架,CXF 帮助您构建和开发 web Services ,它支持多种协议,比如:SOAP1.1,1,2XML/HTTP、RESTful 或者CORBA。
RESTful: 一种风格而不是一个协议。它理念是网络上的所有事物都被抽象为资源,每个资源对应一个唯一的资源标识符。
Cxf是基于SOA总线结构,依靠spring完成模块的集成,实现SOA方式。
灵活的部署: 可以运行在Tomcat,Jboss,Jetty(内置),weblogic上面。
并解压
作为java常用工具,最好在环境变量里配置一下,另cxf-3.1.8需要jdk1.6以上在系统变量里的Path中添加(注意两个变量之间要有分号)
作者: 时间丶思考
链接:http://www.imooc.com/article/14635
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作! 作为java常用工具,最好在环境变量里配置一下,另cxf-3.1.11需要jdk1.6以上在系统变量里的Path中添加(注意两个变量之间要有分号)
在cmd中输入wsdl2java -help输出一大堆
说明环境变量配置成功
下面开始建立webservice项目,分为两种项目,一种是普通java项目,另一种基于springmvc项目
1、普通java项目
1)、建立接口
package com.it.cxf; import javax.jws.WebService; @WebService public interface MyWebService { public int add(int a, int b); public int minus(int a, int b); }
2)、开发实现类
package com.it.cxf; import javax.jws.WebService; @WebService(endpointInterface="com.it.cxf.MyWebService") public class MyWebServiceImpl implements MyWebService { @Override public int add(int a, int b) { System.out.println(a + "+" + b + "=" + (a + b)); return a + b; } @Override public int minus(int a, int b) { System.out.println(a + "-" + b + "=" + (a - b)); return a - b; } }
3)、发布
package com.it.cxf; import javax.xml.ws.Endpoint; public class MyServer { public static void main(String[] args) { String address = "http://localhost:8888/ms"; Endpoint.publish(address, new MyWebServiceImpl()); } }这时,可以打开浏览器并输入http://localhost:8888/ms?wsdl,可以看到暴漏的wsdl如下:
wsdl:definitions name="MyWebServiceImplService" targetNamespace="http://cxf.it.com/"> <wsdl:types> <xs:schema elementFormDefault="unqualified" targetNamespace="http://cxf.it.com/" version="1.0"> <xs:element name="add" type="tns:add" /> <xs:element name="addResponse" type="tns:addResponse" /> <xs:element name="minus" type="tns:minus" /> <xs:element name="minusResponse" type="tns:minusResponse" /> <xs:complexType name="add"> <xs:sequence> <xs:element name="arg0" type="xs:int" /> <xs:element name="arg1" type="xs:int" /> </xs:sequence> </xs:complexType> <xs:complexType name="addResponse"> <xs:sequence> <xs:element name="return" type="xs:int" /> </xs:sequence> </xs:complexType> <xs:complexType name="minus"> <xs:sequence> <xs:element name="arg0" type="xs:int" /> <xs:element name="arg1" type="xs:int" /> </xs:sequence> </xs:complexType> <xs:complexType name="minusResponse"> <xs:sequence> <xs:element name="return" type="xs:int" /> </xs:sequence> </xs:complexType> </xs:schema> </wsdl:types> <wsdl:message name="minusResponse"> <wsdl:part element="tns:minusResponse" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="addResponse"> <wsdl:part element="tns:addResponse" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="add"> <wsdl:part element="tns:add" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="minus"> <wsdl:part element="tns:minus" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:portType name="MyWebService"> <wsdl:operation name="add"> <wsdl:input message="tns:add" name="add"> </wsdl:input> <wsdl:output message="tns:addResponse" name="addResponse"> </wsdl:output> </wsdl:operation> <wsdl:operation name="minus"> <wsdl:input message="tns:minus" name="minus"> </wsdl:input> <wsdl:output message="tns:minusResponse" name="minusResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="MyWebServiceImplServiceSoapBinding" type="tns:MyWebService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="add"> <soap:operation soapAction="" style="document" /> <wsdl:input name="add"> <soap:body use="literal" /> </wsdl:input> <wsdl:output name="addResponse"> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="minus"> <soap:operation soapAction="" style="document" /> <wsdl:input name="minus"> <soap:body use="literal" /> </wsdl:input> <wsdl:output name="minusResponse"> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="MyWebServiceImplService"> <wsdl:port binding="tns:MyWebServiceImplServiceSoapBinding" name="MyWebServiceImplPort"> <soap:address location="http://localhost:8888/ms" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
4)、客户端调用
package com.it.cxf; import java.net.MalformedURLException; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; public class MyClient { public static void main(String[] args) { try { URL url = new URL("http://localhost:8888/ms?wsdl");//wsdl路径 // Qnameqname是qualified name 的简写 //可通过这里获得<wsdl:definitions name="MyWebServiceImplService" targetNamespace="http://cxf.it.com/"> QName qname = new QName("http://cxf.it.com/", "MyWebServiceImplService"); Service service=Service.create(url, qname); MyWebService myWebService=service.getPort(MyWebService.class); int result=myWebService.add(1, 1); System.out.println(result); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
执行结果如下图: