- 浏览: 210218 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
xiaokang1582830:
这有涉及到跨域?
ajax跨域调用webservice -
337240552:
...
web.xml中<security-constraint>和四种认证类型 -
pythoner126com:
写得不错,国内对perl热情不是很高,我最近也有翻译,请多多指 ...
Perl Hash 用法 -
an_yeblack:
你好,我想问一下,一般是什么愿因导致这种错误的呢?先谢谢了!! ...
WAS7 无法在控制台启动 Node Agent -
linzixiao:
感谢分享
冻结table的行和列
Web Service的定义
最普遍的一种说法就是,Web Service = SOAP + HTTP + WSDL。其中,SOAP Simple Object Access Protocol)协议是web service的主体,它通过HTTP或者SMTP等应用层协议进行通讯,自身使用XML文件来描述程序的函数方法和参数信息,从而完成不同主机的异构系统间的计算服务处理。这里的WSDL(Web Services Description Language)web 服务描述语言也是一个XML文档,它通过HTTP向公众发布,公告客户端程序关于某个具体的 Web service服务的URL信息、方法的命名,参数,返回值等。
下面,我们先来熟悉一下SOAP协议,看看它是如何描述程序中的函数方法、参数及结果对象的。
SOAP协议简介
什么是SOAP
SOAP 指简单对象访问协议,它是一种基于XML的消息通讯格式,用于网络上,不同平台,不同语言的应用程序间的通讯。可自定义,易于扩展。一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素:
• Envelope 元素,标识XML 文档一条 SOAP 消息
• Header 元素,包含头部信息的XML标签
• Body 元素,包含所有的调用和响应的主体信息的标签
• Fault 元素,错误信息标签。
以上的元素都在 SOAP的命名空间http://www.w3.org/2001/12/soap-envelope中声明;
SOAP的语法规则
• SOAP 消息必须用 XML 来编码
• SOAP 消息必须使用 SOAP Envelope 命名空间
• SOAP 消息必须使用 SOAP Encoding 命名空间
• SOAP 消息不能包含 DTD 引用
• SOAP 消息不能包含 XML 处理指令
SOAP 消息的基本结构
SOAP Envelope 元素
Envelope 元素是 SOAP 消息的根元素。它指明 XML 文档是一个SOAP 消息。它的属性 xmlns:soap的值必须是http://www.w3.org/2001/12/soap-envelope。
encodingStyle 属性,语法:soap:encodingStyle="URI"
encodingStyle 属性用于定义文档中使用的数据类型。此属性可出现在任何 SOAP 元素中,并会被应用到元素的内容及元素的所有子元素上。
SOAP Header 元素
actor 属性,语法soap:actor="URI"
通过沿着消息路径经过不同的端点,SOAP 消息可从某个发送者传播到某个接收者。并非 SOAP 消息的所有部分均打算传送到 SOAP 消息的最终端点,不过,另一个方面,也许打算传送给消息路径上的一个或多个端点。SOAP 的 actor 属性可被用于将 Header 元素寻址到一个特定的端点。
mustUnderstand 属性 ,语法soap:mustUnderstand="0|1"
SOAP 的 mustUnderstand 属性可用于标识标题项对于要对其进行处理的接收者来说是强制的还是可选的。假如您向 Header 元素的某个子元素添加了 "mustUnderstand="1",则要求处理此头部的接收者必须认可此元素。
SOAP Body 元素
必需的 SOAP Body 元素可包含打算传送到消息最终端点的实际 SOAP 消息。Body元素中既可以包含SOAP定义的命名空间中的元素,如Fault,也可以是用户的应用程序自定义的元素。以下是一个用户定义的请求:
上面的例子请求苹果的价格。请注意,上面的 m:GetPrice 和 Item 元素是应用程序专用的元素。它们并不是 SOAP 标准的一部分。而对应的 SOAP 响应应该类似这样
SOAP Fault 元素
Fault 元素表示 SOAP的错误消息。它必须是 Body 元素的子元素,且在一条 SOAP 消息中,Fault 元素只能出现一次。Fault 元素拥有下列子元素:
常用的SOAP Fault Codes
HTTP协议中的SOAP 实例
下面的例子中,一个 GetStockPrice 请求被发送到了服务器。此请求有一个 StockName 参数,而在响应中则会返回一个 Price 参数。此功能的命名空间被定义在此地址中: "http://www.jsoso.net/stock"
SOAP 请求:(注意HTTP的Head属性)
SOAP 响应:(注意HTTP的Head属性)
WSDL简介
介绍过了SOAP,让我们关注Web Service中另外一个重要的组成WSDL。
WSDL的主要文档元素
WSDL文档可以分为两部分。顶部分由抽象定义组成,而底部分则由具体描述组成。抽象部分以独立于平台和语言的方式定义SOAP消息,它们并不包含任何随机器或语言而变的元素。这就定义了一系列服务,截然不同的应用都可以实现。具体部分,如数据的序列化则归入底部分,因为它包含具体的定义。在上述的文档元素中,<types>、<message>、<portType>属于抽象定义层,<binding>、<service>属于具体定义层。所有的抽象可以是单独存在于别的文件中,也可以从主文档中导入。
WSDL文档的结构实例解析
下面我们将通过一个实际的WSDL文档例子来详细说明各标签的作用及关系。
在接下来的章节中,我们将学习如何使用Java6.0的Annotation标签来定义和生成对应的WSDL。
JavaSE6.0下的Web Service
从JavaSE6.0开始,Java引入了对Web Service的原生支持。我们只需要简单的使用Java的Annotation标签即可将标准的Java方法发布成Web Service.
Java Annotation details refer to:
但不是所有的Java类都可以发布成Web Service。Java类若要成为一个实现了Web Service的bean,它需要遵循下边这些原则:
这个类必须是public类
这些类不能是final的或者abstract
这个类必须有一个公共的默认构造函数
这个类绝对不能有finalize()方法
下面我们将通过一个具体的Java Web Service代码例子,配合上述的WSDL文件,讲述如何编写JavaSE6.0的原生Web Service应用。
完整的Java Web Service类代码
Annotation 1@WebService(name="Example", targetNamespace="http://www.jsoso.com/wstest", serviceName="Example")
@WebService标签主要将类暴露为WebService,其中targetNamespace属性定义了自己的命名空间,serviceName则定义了< definitions >标签和<service>标签的name属性。
Annotation 2:@SOAPBinding(style=SOAPBinding.Style.RPC)
@SOAPBinding标签定义了WSDL文档中SOAP的消息协议,其中style属性对应SOAP的文档类型,可选的有RPC和DOCUMENT
Annotation 3:@WebMethod(operationName="toSayHello",action="sayHello",exclude=false)
@WebMethod定义Web Service运作的方法,
属性action 对应操作的活动 ,如<soap:operation soapAction="sayHello" />
属性operationName匹配的wsdl:operation 的名称,如<operation name="toSayHello" parameterOrder="userName">
属性exclude 用于阻止将某一继承方法公开为web服务,默认为false
Annotation 4:@WebResult(name="returnWord")
@ WebResult定义方法返回值得名称,如<part name="returnWord" type="xsd:string" />
Annotation 5:@WebParam(partName="person", mode=Mode.IN
@WebParam定义方法的参数名称,如<part name="person" type="tns:person" />,其中mode属性表示参数的流向,可选值有IN / OUT / INOUT
这里要着重说明的是,上述Web Service类的sayHello方法中,带有HelloException这个异常声明,造成该服务类不能直接发布成Web Service。需要使用wsgen工具为其生存异常Bean。关于wsgen工具的使用,请参考wsgen与wsimport命令说明
发布一个的Java Web Service
在完成了上述的Web Service Annotation注释后,我们使用wsgen工具为其进行服务资源文件的构造(这里主要是生成一个名为org.jsoso.jws.server.jaxws.HelloExceptionBean的异常bean类),最后使用以下的类发布Web 服务:
在控制台运行这个类,就可以使用URL :http://localhost:8080/hello?wsdl 浏览到上文所描述的WSDL的全文了。这说明您的第一个Web Service应用发布成功!
构建Web Service客户端
使用JavaSE6.0构建Web Service的客户端是一件相当简单的事。这里我们要使用到JDK中的另一个命令行工具wsimport。在控制台下输入以下命令:
即可在包org.jsoso.jws.client.ref中生成客户端的存根及框架文件。其中我们要使用的类只有两个:服务类Example_Service和本地接口Example。编写如下客户端,即可调用Web Service服务:
届此,本次Web Service的学习暂告一个段落.
附录:wsgen与wsimport命令说明
wsgen
wsgen是在JDK的bin目录下的一个exe文件(Windows版),该命令的主要功能是用来生成合适的JAX-WS。它读取Web Service的终端类文件,同时生成所有用于发布Web Service所依赖的源代码文件和经过编译过的二进制类文件。这里要特别说明的是,通常在Web Service Bean中用到的异常类会另外生成一个描述Bean,如果Web Service Bean中的方法有申明抛出异常,这一步是必需的,否则服务器无法绑定该对像。此外,wsgen还能辅助生成WSDL和相关的xsd文件。wsgen从资源文件生成一个完整的操作列表并验证web service是否合法,可以完整发布。
命令参数说明:
-cp 定义classpath
-r 生成 bean的wsdl文件的存放目录
-s 生成发布Web Service的源代码文件的存放目录(如果方法有抛出异常,则会生成该异常的描述类源文件)
-d 生成发布Web Service的编译过的二进制类文件的存放目录(该异常的描述类的class文件)
命令范例:wsgen -cp ./bin -r ./wsdl -s ./src -d ./bin -wsdl org.jsoso.jws.server.Example
wsimport
wsimport也是在JDK的bin目录下的一个exe文件(Windows版),主要功能是根据服务端发布的wsdl文件生成客户端存根及框架,负责与Web Service 服务器通信,并在将其封装成实例,客户端可以直接使用,就像使用本地实例一样。对Java而言,wsimport帮助程序员生存调用web service所需要的客户端类文件.java和.class。要提醒指出的是,wsimport可以用于非Java的服务器端,如:服务器端也许是C#编写的web service,通过wsimport则生成Java的客户端实现。
命令参数说明:
-d 生成客户端执行类的class文件的存放目录
-s 生成客户端执行类的源文件的存放目录
-p 定义生成类的包名
命令范例:wsimport -d ./bin -s ./src -p org.jsoso.jws.client.ref http://localhost:8080/hello?wsdl
最普遍的一种说法就是,Web Service = SOAP + HTTP + WSDL。其中,SOAP Simple Object Access Protocol)协议是web service的主体,它通过HTTP或者SMTP等应用层协议进行通讯,自身使用XML文件来描述程序的函数方法和参数信息,从而完成不同主机的异构系统间的计算服务处理。这里的WSDL(Web Services Description Language)web 服务描述语言也是一个XML文档,它通过HTTP向公众发布,公告客户端程序关于某个具体的 Web service服务的URL信息、方法的命名,参数,返回值等。
下面,我们先来熟悉一下SOAP协议,看看它是如何描述程序中的函数方法、参数及结果对象的。
SOAP协议简介
什么是SOAP
SOAP 指简单对象访问协议,它是一种基于XML的消息通讯格式,用于网络上,不同平台,不同语言的应用程序间的通讯。可自定义,易于扩展。一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素:
• Envelope 元素,标识XML 文档一条 SOAP 消息
• Header 元素,包含头部信息的XML标签
• Body 元素,包含所有的调用和响应的主体信息的标签
• Fault 元素,错误信息标签。
以上的元素都在 SOAP的命名空间http://www.w3.org/2001/12/soap-envelope中声明;
SOAP的语法规则
• SOAP 消息必须用 XML 来编码
• SOAP 消息必须使用 SOAP Envelope 命名空间
• SOAP 消息必须使用 SOAP Encoding 命名空间
• SOAP 消息不能包含 DTD 引用
• SOAP 消息不能包含 XML 处理指令
SOAP 消息的基本结构
<? xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Header> ... ... </soap:Header> <soap:Body> ... ... <soap:Fault> ... ... </soap:Fault> </soap:Body> </soap:Envelope>
SOAP Envelope 元素
Envelope 元素是 SOAP 消息的根元素。它指明 XML 文档是一个SOAP 消息。它的属性 xmlns:soap的值必须是http://www.w3.org/2001/12/soap-envelope。
encodingStyle 属性,语法:soap:encodingStyle="URI"
encodingStyle 属性用于定义文档中使用的数据类型。此属性可出现在任何 SOAP 元素中,并会被应用到元素的内容及元素的所有子元素上。
<? xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> ... Message information goes here ... </soap:Envelope>
SOAP Header 元素
actor 属性,语法soap:actor="URI"
通过沿着消息路径经过不同的端点,SOAP 消息可从某个发送者传播到某个接收者。并非 SOAP 消息的所有部分均打算传送到 SOAP 消息的最终端点,不过,另一个方面,也许打算传送给消息路径上的一个或多个端点。SOAP 的 actor 属性可被用于将 Header 元素寻址到一个特定的端点。
mustUnderstand 属性 ,语法soap:mustUnderstand="0|1"
SOAP 的 mustUnderstand 属性可用于标识标题项对于要对其进行处理的接收者来说是强制的还是可选的。假如您向 Header 元素的某个子元素添加了 "mustUnderstand="1",则要求处理此头部的接收者必须认可此元素。
<? xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Header> <m:Trans xmlns:m="http://www.jsoso.net/transaction/" soap:mustUnderstand="1" soap:actor="http://www.w3schools.com/appml/ “ >234</m:Trans> </soap:Header> ... ... </soap:Envelope>
SOAP Body 元素
必需的 SOAP Body 元素可包含打算传送到消息最终端点的实际 SOAP 消息。Body元素中既可以包含SOAP定义的命名空间中的元素,如Fault,也可以是用户的应用程序自定义的元素。以下是一个用户定义的请求:
<? xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body> <m:GetPrice xmlns:m="http://www.jsoso.net/prices"> <m:Item>Apples</m:Item> </m:GetPrice> </soap:Body> </soap:Envelope>
上面的例子请求苹果的价格。请注意,上面的 m:GetPrice 和 Item 元素是应用程序专用的元素。它们并不是 SOAP 标准的一部分。而对应的 SOAP 响应应该类似这样
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body> <m:GetPriceResponse xmlns:m="http://www.jsoso.net/prices"> <m:Price>1.90</m:Price> </m:GetPriceResponse> </soap:Body> </soap:Envelope>
SOAP Fault 元素
Fault 元素表示 SOAP的错误消息。它必须是 Body 元素的子元素,且在一条 SOAP 消息中,Fault 元素只能出现一次。Fault 元素拥有下列子元素:
常用的SOAP Fault Codes
HTTP协议中的SOAP 实例
下面的例子中,一个 GetStockPrice 请求被发送到了服务器。此请求有一个 StockName 参数,而在响应中则会返回一个 Price 参数。此功能的命名空间被定义在此地址中: "http://www.jsoso.net/stock"
SOAP 请求:(注意HTTP的Head属性)
POST /InStock HTTP/1.1 Host: www.jsoso.net Content-Type: application/soap+xml; charset=utf-8 Content-Length: XXX <? xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body xmlns:m="http://www.jsoso.net/stock"> <m:GetStockPrice> <m:StockName>IBM</m:StockName> </m:GetStockPrice> </soap:Body> </soap:Envelope>
SOAP 响应:(注意HTTP的Head属性)
HTTP/1.1 200 OK Content-Type: application/soap+xml; charset=utf-8 Content-Length: XXX <? xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body xmlns:m="http://www.jsoso.net/stock"> <m:GetStockPriceResponse> <m:Price>34.5</m:Price> </m:GetStockPriceResponse> </soap:Body> </soap:Envelope>
WSDL简介
介绍过了SOAP,让我们关注Web Service中另外一个重要的组成WSDL。
WSDL的主要文档元素
WSDL文档可以分为两部分。顶部分由抽象定义组成,而底部分则由具体描述组成。抽象部分以独立于平台和语言的方式定义SOAP消息,它们并不包含任何随机器或语言而变的元素。这就定义了一系列服务,截然不同的应用都可以实现。具体部分,如数据的序列化则归入底部分,因为它包含具体的定义。在上述的文档元素中,<types>、<message>、<portType>属于抽象定义层,<binding>、<service>属于具体定义层。所有的抽象可以是单独存在于别的文件中,也可以从主文档中导入。
WSDL文档的结构实例解析
下面我们将通过一个实际的WSDL文档例子来详细说明各标签的作用及关系。
<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.jsoso.com/wstest" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://www.jsoso.com/wstest" name="Example"> ---<definitions>定义了文档中用到的各个xml元素的namespace缩写,也界定了本文档自己的targetNamespace="http://www.jsoso.com/wstest",这意味着其它的XML要引用当前XML中的元素时,要声明这个namespace。注意xmlns:tns="http://www.jsoso.com/wstest"这个声明,它标示了使用tns这个前缀指向自身的命名空间。 <types> <xsd:schema> <xsd:import namespace="http://www.jsoso.com/wstest" schemaLocation="http://localhost:8080/hello?xsd=1"></xsd:import> </xsd:schema> </types> ---<types>标签定义了当前的WSDL文档用到的数据类型。要说明的是,为了最大程度的平台中立性,WSDL 使用 XML Schema 语法来定义数据类型。这些数据类型用来定义web service方法的参数和返回指。对于通用的原生数据类型如:integer , boolean , char , float等,在W3C的标准文档http://www.w3.org/2001/XMLSchema中已经做了定义。这里我们要引入的schema定义schemaLocation="http://localhost:8080/hello?xsd=1"是我们自定义的Java对象类型。 <message name="toSayHello"> <part name="userName" type="xsd:string"></part> </message> <message name="toSayHelloResponse"> <part name="returnWord" type="xsd:string"></part> </message> <message name="sayHello"> <part name="person" type="tns:person"></part> <part name="arg1" type="xsd:string"></part> </message> <message name="sayHelloResponse"> <part name="personList" type="tns:personArray"></part> </message> <message name="HelloException"> <part name="fault" element="tns:HelloException"></part> </message> ---<message>元素定义了web service函数的参数。<message>元素中的每个<part>子元素都和某个参数相符。输入参数在<message>元素中定义,与输出参数相隔离,输出参数有自己的<message>元素。兼作输入、输出的参数在输入输出的<message>元素中有它们相应的<part>元素。输出<message>元素以"Response"结尾,对Java而言方法得返回值就对应一个输出的<message>。每个<part>元素都有名字和类型属性,就像函数的参数有参数名和参数类型。 在上面的文档中有两个输入参数、两个输出参数和一个错误参数(对应Java中的Exception)。 输入参数<message>的name属性分别命名为toSayHello,sayHello。 toSayHello对应输入参数userName,参数类型为xsd:string,在Java语言中就是String; sayHello对应两个输入参数person和arg1,类型为tns:person和xsd:string。这里tns:person类型就是引用了< types >标签中的类型定义。 输出参数<message>的name属性分别命名为toSayHelloResponse和sayHelloResponse。 这个名称和输入参数的<message>标签name属性对应,在其后面加上Response尾缀。 toSayHelloResponse对应的返回值是returnWord,参数类型为xsd:string; sayHelloResponse对应的返回值是personList,参数类型为tns:personArray(自定义类型); 错误参数<message>的name属性为HelloException。 它的<part>子标签element而不是type来定义类型。 以上的message标签的name属性通常使用web service函数方法名作为参照,错误参数标签则使用异常类名为参照。标签中的参数名称,即part子元素的name属性是可自定义的(下一章节详细说明)。message标签的参数类型将引用types标签的定义。 <portType name="Example"> <operation name="toSayHello" parameterOrder="userName"> <input message="tns:toSayHello"></input> <output message="tns:toSayHelloResponse"></output> </operation> <operation name="sayHello" parameterOrder="person arg1"> <input message="tns:sayHello"></input> <output message="tns:sayHelloResponse"></output> <fault message="tns:HelloException" name="HelloException"></fault> </operation> </portType> <portType> 元素是最重要的 WSDL 元素。它可描述一个 web service、可被执行的操作,以及相关的消息。portType的name属性对应Java中的一个服务类的类名。<portType> 元素使用其子元素< operation>描述一个web service的服务方法。 在<operation>元素中,name属性表示服务方法名,parameterOrder属性表示方法的参数顺序,使用空格符分割多个参数,如:“parameterOrder="person arg1”。<operation>元素的子标签<input>表示输入参数说明,它引用<message>标签中的输入参数。<output>表示输出参数说明,它引用<message>标签中的输出参数。<fault>标签在Java方法中的特别用来表示异常(其它语言有对应的错误处理机制),它引用<message>标签中的错误参数。 <binding name="ExamplePortBinding" type="tns:Example"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"></soap:binding> <operation name="toSayHello"> <soap:operation soapAction="sayHello"></soap:operation> <input> <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> </input> <output> <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> </output> </operation> <operation name="sayHello"> <soap:operation soapAction="sayHello"></soap:operation> <input> <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> </input> <output> <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> </output> <fault name="HelloException"> <soap:fault name="HelloException" use="literal"></soap:fault> </fault> </operation> </binding> ---<binding>标签是完整描述协议、序列化和编码的地方,<types>,<message>和<portType>标签处理抽象的数据内容,而<binding>标签是处理数据传输的物理实现。 <binding>标签把前三部分的抽象定义具体化。 首先<binding>标签使用<soap:binding>的transport和style属性定义了Web Service的通讯协议HTTP和SOAP的请求风格RPC。其次<operation>子标签将portType中定义的operation同SOAP的请求绑定,定义了操作名称soapAction,输出输入参数和异常的编码方式及命名空间。 <service name="Example"> <port name="ExamplePort" binding="tns:ExamplePortBinding"> <soap:address location="http://localhost:8080/hello"></soap:address> </port> </service> service是一套<port>元素。在一一对应形式下,每个<port>元素都和一个location关联。如果同一个<binding>有多个<port>元素与之关联,可以使用额外的URL地址作为替换。 一个WSDL文档中可以有多个<service>元素,而且多个<service>元素十分有用,其中之一就是可以根据目标URL来组织端口。在一个WSDL文档中,<service>的name属性用来区分不同的service。在同一个service中,不同端口,使用端口的"name"属性区分。 </definitions>
在接下来的章节中,我们将学习如何使用Java6.0的Annotation标签来定义和生成对应的WSDL。
JavaSE6.0下的Web Service
从JavaSE6.0开始,Java引入了对Web Service的原生支持。我们只需要简单的使用Java的Annotation标签即可将标准的Java方法发布成Web Service.
Java Annotation details refer to:
但不是所有的Java类都可以发布成Web Service。Java类若要成为一个实现了Web Service的bean,它需要遵循下边这些原则:
这个类必须是public类
这些类不能是final的或者abstract
这个类必须有一个公共的默认构造函数
这个类绝对不能有finalize()方法
下面我们将通过一个具体的Java Web Service代码例子,配合上述的WSDL文件,讲述如何编写JavaSE6.0的原生Web Service应用。
完整的Java Web Service类代码
package org.jsoso.jws.server; import java.util.ArrayList; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.jws.WebParam.Mode; import javax.jws.soap.SOAPBinding; / * 提供WebService服务的类 */ @WebService(name="Example", targetNamespace="http://www.jsoso.com/wstest", serviceName="Example") @SOAPBinding(style=SOAPBinding.Style.RPC) public class Example { private ArrayList<Person> persons = new ArrayList<Person>();; /** * * 返回一个字符串 * @param userName * @return */ @WebMethod(operationName="toSayHello",action="sayHello",exclude=false) @WebResult(name="returnWord")//自定义该方法返回值在WSDL中相关的描述 public String sayHello(@WebParam(name="userName")String userName) { return "Hello:" + userName; } /** * web services 方法的返回值与参数的类型不能为接口 * @param person * @return * @throws HelloException */ @WebMethod(operationName="sayHello", action="sayHello") @WebResult(partName="personList") public Person[] sayHello(@WebParam(partName="person", mode=Mode.IN)Person person, String userName) throws HelloException { if (person == null || person.getName() == null) { throw new HelloException("说hello出错,对像为空。。"); } System.out.println(person.getName() + " 对 " + userName + " 说:Hello,我今年" + person.getAge() + "岁"); persons.add(person); return persons.toArray(new Person[0]); } }
Annotation 1@WebService(name="Example", targetNamespace="http://www.jsoso.com/wstest", serviceName="Example")
@WebService标签主要将类暴露为WebService,其中targetNamespace属性定义了自己的命名空间,serviceName则定义了< definitions >标签和<service>标签的name属性。
Annotation 2:@SOAPBinding(style=SOAPBinding.Style.RPC)
@SOAPBinding标签定义了WSDL文档中SOAP的消息协议,其中style属性对应SOAP的文档类型,可选的有RPC和DOCUMENT
Annotation 3:@WebMethod(operationName="toSayHello",action="sayHello",exclude=false)
@WebMethod定义Web Service运作的方法,
属性action 对应操作的活动 ,如<soap:operation soapAction="sayHello" />
属性operationName匹配的wsdl:operation 的名称,如<operation name="toSayHello" parameterOrder="userName">
属性exclude 用于阻止将某一继承方法公开为web服务,默认为false
Annotation 4:@WebResult(name="returnWord")
@ WebResult定义方法返回值得名称,如<part name="returnWord" type="xsd:string" />
Annotation 5:@WebParam(partName="person", mode=Mode.IN
@WebParam定义方法的参数名称,如<part name="person" type="tns:person" />,其中mode属性表示参数的流向,可选值有IN / OUT / INOUT
这里要着重说明的是,上述Web Service类的sayHello方法中,带有HelloException这个异常声明,造成该服务类不能直接发布成Web Service。需要使用wsgen工具为其生存异常Bean。关于wsgen工具的使用,请参考wsgen与wsimport命令说明
发布一个的Java Web Service
在完成了上述的Web Service Annotation注释后,我们使用wsgen工具为其进行服务资源文件的构造(这里主要是生成一个名为org.jsoso.jws.server.jaxws.HelloExceptionBean的异常bean类),最后使用以下的类发布Web 服务:
package org.jsoso.jws.server; import java.util.LinkedList; import java.util.List; import javax.xml.ws.Binding; import javax.xml.ws.Endpoint; import javax.xml.ws.handler.Handler; /** * @author zsy 启动web services服务 */ public class StartServer { /** * @param args */ public static void main(String[] args) { /* * 生成Example 服务实例 */ Example serverBean = new Example(); /* * 发布Web Service到http://localhost:8080/hello地址 */ Endpoint endpoint = Endpoint.publish("http://localhost:8080/hello", serverBean); Binding binding = endpoint.getBinding(); /* * 设置一个SOAP协议处理栈 * 这里就简单得打印SOAP的消息文本 */ List<Handler> handlerChain = new LinkedList<Handler>(); handlerChain.add(new TraceHandler()); binding.setHandlerChain(handlerChain); System.out.println("服务已启动 http://localhost:8080/hello"); } }
在控制台运行这个类,就可以使用URL :http://localhost:8080/hello?wsdl 浏览到上文所描述的WSDL的全文了。这说明您的第一个Web Service应用发布成功!
构建Web Service客户端
使用JavaSE6.0构建Web Service的客户端是一件相当简单的事。这里我们要使用到JDK中的另一个命令行工具wsimport。在控制台下输入以下命令:
wsimport -d ./bin -s ./src -p org.jsoso.jws.client.ref http://localhost:8080/hello?wsdl
即可在包org.jsoso.jws.client.ref中生成客户端的存根及框架文件。其中我们要使用的类只有两个:服务类Example_Service和本地接口Example。编写如下客户端,即可调用Web Service服务:
package org.jsoso.jws.client; import org.jsoso.jws.client.ref.*; public class RunClient { /** * @param args */ public static void main(String[] args) { //初始化服务框架类 Example_Service service = new Example_Service(); //或者本地服务借口的实例 Example server = (Example) service.getExamplePort(); try { //调用web service的toSayHello方法 System.out.println("输入toSayHello的返回值——" + server.toSayHello("阿土")); Person person = new Person(); person.setName("阿土"); person.setAge(25); //调用web service的sayHello方法 server.sayHello(person, "机器人"); person = new Person(); person.setName("aten"); person.setAge(30); //调用web service的sayHello方法 PersonArray list = server.sayHello(person, "机器人"); //输出返回值 System.out.println("\n以下输入sayHello的返回值——"); for (Person p : list.getItem()) { System.out.println(p.getName() + ":" + p.getAge()); } } catch (HelloException_Exception e) { e.printStackTrace(); } } }
届此,本次Web Service的学习暂告一个段落.
附录:wsgen与wsimport命令说明
wsgen
wsgen是在JDK的bin目录下的一个exe文件(Windows版),该命令的主要功能是用来生成合适的JAX-WS。它读取Web Service的终端类文件,同时生成所有用于发布Web Service所依赖的源代码文件和经过编译过的二进制类文件。这里要特别说明的是,通常在Web Service Bean中用到的异常类会另外生成一个描述Bean,如果Web Service Bean中的方法有申明抛出异常,这一步是必需的,否则服务器无法绑定该对像。此外,wsgen还能辅助生成WSDL和相关的xsd文件。wsgen从资源文件生成一个完整的操作列表并验证web service是否合法,可以完整发布。
命令参数说明:
-cp 定义classpath
-r 生成 bean的wsdl文件的存放目录
-s 生成发布Web Service的源代码文件的存放目录(如果方法有抛出异常,则会生成该异常的描述类源文件)
-d 生成发布Web Service的编译过的二进制类文件的存放目录(该异常的描述类的class文件)
命令范例:wsgen -cp ./bin -r ./wsdl -s ./src -d ./bin -wsdl org.jsoso.jws.server.Example
wsimport
wsimport也是在JDK的bin目录下的一个exe文件(Windows版),主要功能是根据服务端发布的wsdl文件生成客户端存根及框架,负责与Web Service 服务器通信,并在将其封装成实例,客户端可以直接使用,就像使用本地实例一样。对Java而言,wsimport帮助程序员生存调用web service所需要的客户端类文件.java和.class。要提醒指出的是,wsimport可以用于非Java的服务器端,如:服务器端也许是C#编写的web service,通过wsimport则生成Java的客户端实现。
命令参数说明:
-d 生成客户端执行类的class文件的存放目录
-s 生成客户端执行类的源文件的存放目录
-p 定义生成类的包名
命令范例:wsimport -d ./bin -s ./src -p org.jsoso.jws.client.ref http://localhost:8080/hello?wsdl
发表评论
-
ajax跨域调用webservice
2011-03-03 17:06 2490跨域请求有多种实现方式,这里只谈谈通过iframe 很简单,就 ... -
java代码通过HttpClient发送WebService请求
2011-03-03 16:07 5061import java.io.ByteArrayInputSt ... -
web service应用实例
2011-02-25 16:25 1872关于webService的描述 1,什么是 Web Servi ... -
web service,soap 和wsdl 学习
2011-01-19 14:11 1283http://www.ibm.com/developerwor ... -
创建一个java的webservice
2011-01-07 21:43 2082转自:http://blog.csdn.net/y ...
相关推荐
基于S7-300PLC与MCGS6.2的饮料罐装生产线自动化控制系统设计,包含仿真、程序、IO表与电气原理,实现自动操作、灌装报警及瓶数记录功能。,基于PLC的饮料罐装生产线控制系统设计。 S7-300PLC MCGS6.2仿真 仿真,程序,IO表,电气原理图,6500字说明。 实现功能有: (1)系统通过开关设定为自动操作模式,一旦启动,则传送带的驱动电机启动并一直保持到停止开关动作或罐装设备下的传感器检测到一个瓶子时停止;瓶子装满饮料后,传送带驱动电机必须自动启动,并保持到又检测到一个瓶子或停止开关动作。 (2)当瓶子定位在灌装设备下时,停顿1秒,罐装设备开始工作,灌装过程为5秒钟,罐装过程应有报警显示,5秒后停止并不再显示报警。 (2)用两个传感器和若干个加法器检测并记录空瓶数和满瓶数,一旦系统启动,必须记录空瓶和满瓶数,设最多不超过99999999瓶。 (4)可以手动对计数器清零(复位)。 ,关键词:S7-300PLC; MCGS6.2仿真; 传送带驱动电机; 传感器检测; 瓶装; 空瓶数; 满瓶数; 报警显示; 自动操作模式; 灌装设备。,基于S7-300PLC的饮料罐装
python加密货币时间序列预测源码+数据集-最新出炉 加密货币分析: 对各种加密货币的数据进行分析和研究。可能会使用到从各种来源收集的数据,包括但不限于加密货币的价格、市值、交易量、交易时间等信息。 探索加密货币市场的趋势和模式,例如价格的波动情况、不同加密货币之间的相关性等。 数据处理与操作: 可能使用 Python 语言(Kaggle 上常用的数据分析语言),并运用一些数据处理和分析的库,如 pandas 用于数据的读取、清洗、整理和转换操作,将原始的加密货币数据转换为更易于分析的格式。 可视化展示: 通过可视化工具,如 matplotlib 或 seaborn 库,将加密货币的信息以图表的形式展示出来,以帮助直观地理解数据中的关系和趋势。 统计分析或预测: 可能会进行一些基本的统计分析,如计算加密货币价格的均值、中位数、标准差等统计量,以描述数据的特征。 或者使用机器学习或时间序列分析的方法对加密货币的价格进行预测,根据历史数据预测未来价格走势。 例如,使用 scikit-learn 进行简单的回归分析: 数据挖掘与特征提取: 挖掘加密货币数据中的特征,如找出影响价格的关键因素,对数据中的特征进行筛选和提取,以帮助更好地理解加密货币的市场行为。
类和对象、继承、封装、多态、接口、异常
gee python相关教程
夜间灯光强度(平均灯光强度)的高低反映了一个地区城市化发展的水平,平均灯光强度越高,说明该地区城市群越多,城市化程度越高。夜间灯光数据现在越来越广泛地应用于经济增长分析、经济地理、城市经济学、数字经济等众多领域。 本数据包括三套: [1]中国类DMSP-OLS灯光数据1992-202 [2]中国超长序列灯光数据1984-2020 [3]全球类NPP-VIIRS夜间灯光数据2000-2022 包括:全国各省、市、县夜间灯光数据 矫正后夜间灯光数据 细分:标准差、平均值、总值、最大值和最小值
工程项目总监绩效考核表
首先解释一下什么叫转移支付。其实,这和养老金的中央调剂是一样的。 每年,地方都要向中央缴纳财政。而中央又要根据各地方的财政实力,给予转移支付。比如一些经济弱省,本身财政收入就不够支出的,还得上交一部分给中央,怎么维持财政运转?由于各省市直接的财政收入能力存在差异,中央为实现各个地方的公共服务水平平等,于是便有了财政转移支付制度。 简单理解就是富省养穷省。 2022年全国一般预算内财政收入203703亿元,给地方转移支付了97144.75亿元,转移支付数额创下新高。
基于门控卷积和堆叠自注意力的离线手写汉字识别算法研究.pdf
【数据介绍】 作为第二大人类部门用水,高质量的工业用水格网数据对于水资源研究和管理至关重要。中国工业用水格网数据(China Industrial Water Withdrawal dataset, CIWW)基于超过 40 万家企业数据、月度工业产品产量数据和连续工业用水统计数据制作得到的一套1965-2020年逐月中国工业用水数据集,其空间分辨率为 0.1°和 0.25°。数据集包括工业用水、企业数量和企业生产总值(辅助数据)等变量,可被用于水文、地理学、环境、可持续发展等方面科学研究。 【数据来源】 数据来源为《中国经济普查年鉴》(省级工业取水量、工业产出)、《中国工业企业数据库》(企业地理位置、产值)、《中国工业产品产量数据库》(工业产品月生产量),以及《中国水资源公报》和(Zhou et al, 2020, PNAS)的工业用水量数据。 【数据处理】 首先通过2008年企业分布数据、经济普查年鉴中分省分部门的工业用水量和工业产值计算得到分省分部门工业用水效率和工业产品产量数据,得到了2008年逐月工业用水数据。然后结合中国水资源公报和相关文献中省级工业用水数据,以2008年工业用水的时空格局作为基础分配工业用水数据,最终得到1965-2020年逐月工业用水的格网数据。详细方法见High-resolution mapping of monthly industrial water withdrawal in China from 1965 to 2020 (Hou et al, 2024, ESSD). 将数据集与统计数据记录和其他数据集进行了验证,结果表示在时间尺度和空间尺度上都与统计数据具有一致性,相比已有工业用水数据有更好的精度。
65 -质量管理部经理绩效考核表1
11 -电脑部经理绩效考核表1
内容概要:本文提供了针对大学生英语竞赛写作准备的重要资源——一系列通用的英文句子模板。这些模板涵盖了现代经济社会的各种话题,从科技进步到环境保护,以及个人品质和社会责任等,并且适用于论述类文章、观点对比和个人见解的表达。文章通过对每一句话的应用环境解释和语法提示,确保使用者可以在实际写作中正确且有效地应用这些表达方式。 适合人群:正在准备参加大学生英语竞赛的学生及其他希望提高书面表达能力的学习者。 使用场景及目标:考生能够在竞赛时间内迅速构建思路完整的文章,增强语言表达的流利性和规范性;帮助学习者积累高级词汇,提升英语写作水平并培养良好的思维逻辑。 阅读建议:结合历年优秀范文进行深入学习,熟悉不同类型话题下的表述方法;练习将提供的句子融入自身创作的文章中,通过不断修订和完善来巩固记忆。同时也可以用于日常的英语写作训练当中。
法律事务专员绩效考核表
1、文件内容:apache-commons-digester-javadoc-1.8.1-19.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/apache-commons-digester-javadoc-1.8.1-19.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
永磁同步电机磁场定向控制(矢量控制)Simulink仿真模型波形展现与解析,永磁同步电机的磁场定向控制(矢量控制)simulink仿真模型,波形完美 ,核心关键词:永磁同步电机; 磁场定向控制(矢量控制); Simulink仿真模型; 波形完美;,永磁同步电机矢量控制仿真模型:磁场完美调控,波形精确无误
07 -储运部经理绩效考核表1
OQC检验员(成品出货检验员)绩效考核表
基于Matlab2020b的电机控制算法:无传感FOC算法Simulink仿真模型及实践指导,定位+电流闭环强拖+ 角度渐变切+ 速度电流双闭环+ 无传感器角度估算SMO+ PLL 控制方式 Simulink 仿真模型 (Matlab2020b版本)以及教授模型搭建 这是一种常用的无传感FOC电机控制算法,掌握这种算法的基本原理,并有仿真模型在手,就可以用它来指导实践中的程序调试,做到实际项目不盲目调试。 模型特点: 1. 所有模块都做到了模块化,各个模块分区清楚,结构清晰。 2. 所有电机和控制参数均在m文件中体现,变量注释清楚,随用随改。 3. 速度环和电流环PI参数均实现自动整定。 4. 模型采用标幺值系统。 5. 各状态切使用stateflow,模型结构清晰。 6.通用表贴和内嵌式电机。 ,定位;电流闭环强拖;角度渐变切换;速度电流双闭环;无传感器角度估算SMO;PLL控制方式;Simulink仿真模型;Matlab2020b版本建模;教授模型搭建;模块化设计;参数自动整定;标幺值系统;Stateflow应用;通用表贴和内嵌式电机。,基于Matlab 2020b的FOC电机