web service实现方式,简述service原理,Web Service 运行原理详细介绍

web service实现方式,简述service原理,Web Service 运行原理详细介绍

本文主要详细介绍了关于Web服务运行原理的相关信息,有需要的朋友可以参考一下。

在清明假期,我复习了Web Service的相关内容,并简要总结了它的工作原理。供以后有需要的朋友和自己参考。文章如有不妥之处,请各位朋友提出宝贵意见,相互鼓励。

在Web服务中,我们应该首先理解相关术语的含义:WSDL、UDDI.相关术语的介绍在此不再赘述,重点放在原理上。

在Web服务中,有三个角色:服务提供者、服务请求者和服务中介,他们之间的关系如图1-1所示。

实现一个完整的Web服务包括以下步骤:

Web服务提供者设计并实现Web服务,通过Web服务中介发布正确调试的Web服务,并在UDDI注册中心注册;(发布)

Web服务请求者向Web服务中介请求特定的服务,中介根据请求查询UDDI注册中心,为请求者寻找满足请求的服务;(发现)

Web服务代理将符合条件的Web服务描述信息返回给Web服务请求者。描述信息是用WSDL语写的,可以被各种支持Web服务的机器读取;(发现)

利用Web服务中介返回的描述信息(WSDL)生成相应的SOAP消息,并发送给Web服务提供者,实现Web服务的调用;(装订)

Web服务提供者根据SOAP消息执行相应的Web服务,并将服务结果返回给Web服务请求者。(装订)

图1-1 Web服务的架构

注意:WSDL的功能是一个Web服务规范。服务请求者根据这个WSDL生成相应的SOAP消息,服务提供者收到SOAP请求消息后绑定服务。

以下是web.xml中的servlet配置

!-设置初始化参数或定制servlet或JSP页面的URL时,必须首先命名servlet或JSP页面。Servlet元素用于完成这项任务。-

小型应用程序

servlet-name userservice/servlet-name

servlet-class com . sun . XML . ws . transport . http . servlet . ws servlet/servlet-class

!-标记容器是否在启动时加载这个servlet(实例化并调用其init()方法;的正值越小,这个servlet的优先级越高,应用程序在启动时加载得越早-

启动时加载1/启动时加载

/servlet

!-服务器通常为servlet提供一个默认的URL:http://host/web app Prefix/servlet/servlet name。

但是,这个URL经常被更改,以便servlet可以更容易地访问初始化参数或处理相对URL。更改默认URL时使用servlet-mapping元素。-

servlet映射

servlet-name userservice/servlet-name

!-描述相对于Web应用程序根目录的URL。url-pattern元素的值必须以斜杠(/)开头。-

url模式/用户/url模式

/servlet-映射

红队部分很重要,启动Web容器时会加载相应的servlet。绿色部分是该服务的外部接口。找到相应的jax-ws.xml文件(如下所示)

端点名称='UserPort '实现='cn.ujn.service.UserService '

url-pattern='/user '

/端点

然后绑定到相关的对应实现类cn.ujn.service.UserService.客户端发送的SOAP请求消息的主体包含客户端请求的方法名称和参数信息。

下面是为客户端封装的soap消息体(以Json模式与服务器进行数据传输)(SOAP请求信封):

soap env:Envelope xmlns:soap env=' http://schemas . XML soap . org/soap/Envelope/' xmlns:Q0=' http://ujn . cn/' xmlns:xsd=' http://www . w3 . org/2001/XML schema ' xmlns:xsi=' http://www . w3 . org/2001/XML schema-instance '

- soapenv:Body

- q0:登录

arg0{'username':'shq ',' password':'shq'}/arg0

/q0:登录

/soapenv:Body

/soapenv:Envelope

下面调用SOAP1.1协议的Web服务

/**

*通过SOAP1.1协议调用Web服务

*

* text/xml这是基于soap1.1协议的。

*

* @param wsdl WSDL路径

* @param方法方法名

* @param命名空间命名空间

* @param headerParameters标头参数

* @ param参数体参数

* @param isBodyParametersNS体参数是否有命名空间

* @返回字符串

* @抛出异常

*/

公共静态字符串invokeBySoap11(字符串wsdl,字符串方法,

字符串命名空间,映射字符串,字符串头参数,

MapString,String bodyParameters,boolean isBodyParametersNS)

引发异常{

StringBuffer soapOfResult=null

//去除?wsdl,获取方法列表

int length=wsdl.length().

wsdl=wsdl.substring(0,长度-5);

//以字符串为参数创建统一资源定位器实例

URL url=新URL(wsdl);

//创建连接

http URL connection conn=(http URL connection)URL。打开连接();

//设置请求方式

conn . setrequestmethod(' POST ');

//如果打算使用统一资源定位器连接进行输入,则将输入输出标志设置为真实的

conn . setdoinput(true);

//如果打算使用统一资源定位器连接进行输出,则将输入输出标志设置为真实的

conn . setdoooutput(true);

//主要是设置HttpURLConnection请求头里面的属性(K-V)

conn . setrequestproperty(' Content-Type ',' text/XML;charset=utf-8 ');

//获取输入流(相对于客户端来说,使用的是输出流)

输出流out=conn . get输出流();

//获取soap1.1版本消息

StringBuilder sb=new StringBuilder();

某人(somebody的简写)append(' soap:Envelope xmlns:xsi=' http://www。w3。' org/2001/XML架构-实例'

xmlns:xsd=' http://。w3。org/2001/XML schema ' xmlns:soap=' http://架构。XML soap。org/soap/envelope/' ');

sb.append('xmlns:ns0=')命名空间' ');

某人追加(');

//拼装消息头

if (headerParameters!=null) {

某人(somebody的简写)append(' soap:Header ');

for (EntryString,字符串头参数:头参数。entrySet()) {

某人(somebody的简写)追加(' ns0:');

某人(somebody的简写)append(头参数。getkey());

某人追加(');

某人(somebody的简写)append(头参数。getvalue());

某人(somebody的简写)追加('/ns0:');

某人(somebody的简写)append(头参数。getkey());

某人追加(');

}

某人(somebody的简写)追加('/soap:Header ');

}

//拼装消息体

某人(somebody的简写)append(' soap:body ns0:');

某人追加(方法);

某人追加(');

//输入参数

if (bodyParameters!=null) {

for (EntryString,字符串输入参数:车身参数。entrySet()) {

if (isBodyParametersNS) {

某人(somebody的简写)追加(' ns0:');

某人(somebody的简写)追加(输入参数。getkey());

某人追加(');

某人(somebody的简写)追加(输入参数。getvalue());

某人(somebody的简写)追加('/ns0:');

某人(somebody的简写)追加(输入参数。getkey());

某人追加(');

}否则{

某人追加(');

某人(somebody的简写)追加(输入参数。getkey());

某人追加(');

某人(somebody的简写)追加(输入参数。getvalue());

某人(somebody的简写)追加('/');

某人(somebody的简写)追加(输入参数。getkey());

某人追加(');

}

}

}

某人(somebody的简写)追加('/ns0:');

某人追加(方法);

某人(somebody的简写)append('/soap:Body/soap:Envelope ');

//测试用

系统。出去。印刷(某人)。tostring());

//写入肥皂消息(相对于客户端来说,使用的是out.write())

输出.写入(某人的字符串)。getBytes());

//获取服务器端的相应

int code=conn . getresponsecode();

如果(代码==200) {

InputStream is=conn . getinputstream();

字节[] b=新字节[1024];

int len=0;

soapOfResult=新字符串缓冲区();

//从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。以整数形式返回实际读取的字节数

//如果因为流位于文件末尾而没有可用的字节,则返回值-1;

while ((len=is.read(b))!=-1) {

//使用命名字符集将字节数组转换为字符串。

字符串s=新字符串(b,0,len,' UTF-8 ');

肥皂的结果。追加;

}

}

conn . disconnect();

返回soapOfResult==null?null:soapofresult。tostring();

}

注:在客户端发送肥皂请求消息后便处于阻塞状态。直至服务端返回状态码。

以下为服务端进行响应(肥皂响应信封):

S:Envelope xmlns:S=' http://模式。XML soap。org/soap/Envelope/'

-S:身体

-NS2:登录响应xmlns:NS2=' http://ujn。cn/'

返回1/返回

/ns2:登录响应

/S:正文

/S:信封

客户端接收到服务端发来的Json数据后会进行相应的解析操作。如下:

//将肥皂协议进行解析(DOM解析只能用于解析可扩展标记语言文档类型,而肥皂消息就是采用可扩展标记语言数据格式)

文档doc=XML util。字符串2g文档(结果);

Element ele=(Element)doc。getelementsbytagname(' return ').项目(0);

方法中使用到的string2Doc()方法体如下:

公共静态文档string2Doc(字符串str) {

//将可扩展标记语言文档解析成数字正射影像图树

DocumentBuilderFactory factory=DocumentBuilderFactory。新实例();

文档文档=空

文档生成器生成;

if(str==null | | str。等于('){

返回空

}

尝试{

InputStream Bais=new bytearray InputStream(str。getbytes(' UTF-8 ');

构建=工厂。newdocumentbuilder();

//将给定输入流的内容解析为可扩展标记语言文档,并返回新的DOM文档对象。

文档=构建。parse(Bais);

} catch(异常e) {

e。printstacktrace();

}

返回文档;

}

根据返回结果,客户端再进行相应的处理。

以上是网服务的基本工作原理。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: