分享
 
 
 

Servlet与Web服务

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

Servlet在web services中起到很大的作用,负责解析soap文件(消息和附件封套),使用wsdl来校验soap消息等。作为基本的编程是可以用servlet来解析soap消息,尤其是对于带附件的soap消息,这样做很透明,但是servlet不能作为Web服务,当然拓展的JAXM是可以做到的。现在那些支持web services的项目都是通过底层上实现了servlet的功能,来完成HTTP+SOAP的通信,就不需要程序员考虑基于HTTP的SOAP消息的通信过程(不要有这样的误解,在java平台上HTTP的通信的服务程序是servlet/jsp,而现在你不用servlet和jsp来通信,岂不是矛盾?事实不矛盾,记住是底层已经实现了servlet功能,具体通信有底曾自己管理),直接上升到业务逻辑的服务编程。当然有时也可以编写解析SOAP消息的servlet,那就仅仅只是SOAP通信了(servlet无法作为服务来描述)。

下面根据配置文件,来说明一些底层与web services的关系:

回顾一下servlet的映射模式。我们知道,servlet是从javax.servlet.http.HttpServlet继承的,在服务器端被载入JVM执行,然后向客户端输出html流。

servlet的web.xml文件(位于 webapps/foo/WEB-INF目录):

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"

"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">

<web-app>

<servlet-mapping>

<servlet-name>invoker</servlet-name>

<url-pattern>/servlet/*</url-pattern>

</servlet-mapping>

</web-app>

invoker servlet 其实是:org.apache.catalina.servlets.InvokerServlet

按类名提供小服务程序。例如,如果您调用 foo/servlet/HelloServlet,

invoker servlet将装入该HelloServlet(如果它在其类路径中的话)并执行。

初看上面的web.xml,好像只给出了一个servlet映射,而没有定义invoker servlet。

其实,invoker servlet 是在tomcat的conf目录中的web.xml中定义的::

<servlet>

<servlet-name>invoker</servlet-name>

<servlet-class>

org.apache.catalina.servlets.InvokerServlet

</servlet-class>

<init-param>

<param-name>debug</param-name>

<param-value>0</param-value>

</init-param>

<load-on-startup>2</load-on-startup>

</servlet>

所以,如果抛开Tomcat_HOME/conf/web.xml,我们这样定义一个web.xml,似乎更能清楚的说明问题:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"

"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">

<web-app>

<servlet-name>MyInvoker</servlet-name>

<servlet-class>

org.apache.catalina.servlets.InvokerServlet

</servlet-class>

<init-param>

<param-name>debug</param-name>

<param-value>0</param-value>

</init-param>

<load-on-startup>2</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>MyInvoker</servlet-name>

<url-pattern>/servlet/*</url-pattern>

</servlet-mapping>

</web-app>

即所有/servlet/* 模式的url,都会交给org.apache.catalina.servlets.InvokerServlet来处理。

或者说,所有/servlet/* 模式的url,其实都是调用InvokerServlet这个类,而InvokerServlet本身也是

一个servlet,它也是从 HttpServlet 继承而来的。

这样,我们自己的servlet就能够通过特定的url执行,即 /servlet/OurServlet。

当然,如果你高兴,可以定义任何的 url pattern,而不一定是 /servlet/*,这一点,正如我们后面

看到的Axis处理Soap消息的方法。

进一步,如果不想让 InvokerServlet 在中间“捣鬼”,我们当然可以直接定义自己的servlet:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"

"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">

<web-app>

<servlet-name>MyInvoker2</servlet-name>

<servlet-class>

com.foo.MyServlet

</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>MyInvoker2</servlet-name>

<url-pattern>/AnyName/*</url-pattern>

</servlet-mapping>

</web-app>

JSP也是一样的道理,有了上面的分析,

看看Tomcat_HOME/conf/web.xml中的如下语句就可以JSP的处理方法了,这里就不再废话了:

....

<servlet>

<servlet-name>jsp</servlet-name>

<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>

<init-param>

<param-name>logVerbosityLevel</param-name>

<param-value>WARNING</param-value>

</init-param>

<load-on-startup>3</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>jsp</servlet-name>

<url-pattern>*.jsp</url-pattern>

</servlet-mapping>

....

进入正题。

我们先来看部署Web Service的web.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<web-app>

<servlet>

<servlet-name>Axis</servlet-name>

<!--实际servlet程序,这里是AxisServlet-->

<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>

</servlet>

<!-- ### 定义servlet和url的对应关系-->

<servlet-mapping>

<servlet-name>Axis</servlet-name>

<url-pattern>/services/*</url-pattern>

</servlet-mapping>

</web-app>

所有 /services/* 模式的 url 都会交给org.apache.axis.transport.http.AxisServlet处理,

AxisServlet当然也是从HttpServlet继承而来的。这就是为什么我们部署的Web服务在调用时都要在

服务名称前加上 services/ 了。

可以说,AxisServlet是所有Web服务调用的入口。

那么AxisServlet在接手Web服务调用后都做了哪些工作呢?

客户端用call.invoke()调用web服务用的是POST,所以入口是AxisServlet.doPost...

而不是AxisServlet.doGet...

先来看看AxisServlet的doPost函数,这里只给出了关键语句及注释:

/**

* Process a POST to the servlet by handing it off to the Axis Engine.

* Here is where SOAP messages are received

* @param req posted request

* @param res respose

* @throws ServletException trouble

* @throws IOException different trouble

*/

public void doPost(HttpServletRequest req, HttpServletResponse res)

throws ServletException, IOException

{

msgContext = createMessageContext(engine, req, res);//获取客户请求信息

engine.invoke(msgContext); //调用客户端请求的服务

responseMsg = msgContext.getResponseMessage();//得到调用的返回结果

sendResponse(getProtocolVersion(req), contentType, res, responseMsg);//将结果送至客户端

}

这样一来,Web服务调用的来龙去脉就大致清楚了。。。

为了高清楚前面我们的三个url

http://192.168.0.1/test/services

http://192.168.0.1/test/services/sayHelloService?wsdl

http://192.168.0.1/test/services/sayHelloService?method=sayHelloTo&aname=everybody

是怎样获得输出结果的,再来看看AxisServlet的doGet函数,这里只给出了流程框架及注释:

**

* Process GET requests. Because Axis does not support the GET-style

* pseudo execution of SOAP methods, this handler deals with queries

* of various kinds, not real SOAP actions.

*

* @todo for secure installations, dont stack trace on faults

* @param request request in

* @param response request out

* @throws ServletException

* @throws IOException

*/

public void doGet(HttpServletRequest req, HttpServletResponse res)

throws ServletException, IOException

{

//如果路径为空,比如:http://localhost/wstk/services 或 http://localhost/wstk/services/*

if((pathInfo == null || pathInfo.equals("")) && !realpath.endsWith(".jws"))

{

//从server-config.wsdd文件中读取所有部署的服务信息,向向客户端列出所有部署的服务,

//包括每个服务可调用的方法。

}else

//如果路径不为空,比如:http://localhost/wstk/services/sayHelloService

if(realpath != null)

{

//如果请求wsdl,比如:http://localhost/wstk/services/sayHelloService?wsdl

if(wsdlRequested)

{

//创建sayHelloService的WSDL文件并传送至客户端

} else

//这里是利用url调用Web服务的入口,比如http://192.168.0.1/test/services/sayHelloService?method=sayHelloTo&aname=everybody

if(req.getParameterNames().hasMoreElements())

{

//如果客户端调用的方法正确,则Axis会调用相应的JavaBean,并把JavaBean的返回结果

//封装为Soap消息流返回给客户端。

}

}

}

而Axis怎样找到我们所请求的JavaBean呢?答案是server-config.wsdd文件。

server-config.wsdd

<?xml version="1.0" encoding="UTF-8"?>

<deployment xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns="http://xml.apache.org/axis/wsdd/">

<service name="sayHelloService" provider="java:RPC">

<parameter name="className" value="sayHello"/>

<parameter name="allowedMethods" value="sayHelloTo"/>

</service>

<handler type="java:org.apache.axis.handlers.http.URLMapper" name="URLMapper"/>

<transport name="http">

<requestFlow>

<handler type="URLMapper"/>

</requestFlow>

</transport>

</deployment>

WSDD是web service deployment descriptor的缩写。

最外面的<deployment>元素指示这是WSDD,并定义了java的名字空间。

接着的 <service>元素定义了service。一个service是一个目标链,包括请求request、内容提供者provider、响应response。

在这个例子中,我们指出service名字是sayHelloService ,provider是"java:RPC",它是axis 的标记,指示这是一个java的RPC service,

而处理它的真正的class是org.apache.axis.providers.java.RPCProvider。

接着我们要在<parameter>中告诉RPCProvider,它如何实例化并调用正确的class(如:com.foo.MyService)。

<parameter>元素的className指示class名,allowedMethods告诉引擎那些共用的方法要通过soap来调用。

"*"表示所有的公共方法,我们也列出方法名字列表,可以空格或逗号分割它们。

部分资料来源于:http://www.chinaunix.net/jh/26/171988.html

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有