WEB SERVICE大概是.NET中最引人瞩目的一个技术“亮点”了。事实上Microsoft在不遗余力的推动WEB SERVICE,力图使之成为新一代的分布式计算模式的标准。WEB SERVICE是Microsoft在COM/DCOM之后的最重要的技术革新。与以往不同的是,Microsoft这次的革新是建立在业界开放的标准之上的。SOAP,HTTP, WSDL以及UDDI并非Microsoft所有,所以在WEB SERVICE上的技术投入并不会将你“绑”在Microsoft身上。SUN, IBM以及ORACLE都提供自己的WEB SERVICE方案,所以你有选择,可以使用非Microsoft的其它方案,至少在理论上是这样。

简言之,WEB SERVICE其实就是在Web之上提供服务(SERVICE〕。客户端可以调用远程服务器端函数并得到结果,就像RMI,DCOM和COBRA一样。不同的是客户端和服务器端的“对话”使用的是业界标准而不是JAVA或Microsoft独有的技术。由于采用了HTTP作缺省通讯协议,使得WEB SERVICE可以透过各个企业,公司的防火墙,真正实现跨INTERNET的分布式计算。也因为HTTP,使得WEB SERVICE在本质上一些先天的限制,就像其它的WEB应用程序一样。HTTP是一种无态的(STATELESS)通讯协议,所以在HTTP之上的WEB SERVICE如何保持“状态(STATE)”就成为一个有趣的话题。在这里,我想就这个问题做一些讨论。

从一个简单的例子看WEB SERVICE的“无态性”

在Microsoft提供的VISUAL STUDIO.NET中,集成的开发环境将很多WEB SERVICE的繁琐细节隐藏了起来,尽量的想使开发者感到方便和简单,就像在开发普通的类(CLASS)和函数那样。但是你千万不能被表象所蒙蔽,从而导致一些最基本的错误。请看下面这个小例子。

 class Student : System.Web.Services.WebService
{
    private String name;
    public String Name
    {
        get{return name;}
        set{name=value;}
    }   
}

一眼看上去,这个Student类没有什么毛病。另外,你在客户端想这样的使用它。

localhost.Student student = new localhost.Student();
student.setName("Lao Wang");
String myInfo = student.getName();
...

这下应该没有问题了吧。但当你运行客户端程序的时候,你发现结果和你预料的不一样。getName函数返回值是NULL。奇怪,刚刚设置的"Lao Wang"哪儿去了呢?

如果你遇到这样的问题,那说明你被集成环境给蒙蔽了,没有知道程序究竟是怎么执行的。看起来你只创建了一个Student实例(Object),并两次调用它的函数。但实际情况却非如此。你没有创建一个Student实例,你只是创建了Student类的代理类的实例(Proxy Class)。Student类的实例是在服务器端创建的,而且是两次。你在客户端两次的函数调用在服务器端生成了两个实例,每个实例响应一次函数调用。两个实例之间没有任何联系,所以你把第一个实例的Name设为"Lao Wang"对于第二个实例来讲是全然无知的。现在,你可能体会到"无态"的涵义了吧。

如果你知道一些WEB SERVICE的背景REMOTING的话,这一点就更好理解了。WEB SERVICE的实例创建是属于REMOTING中"单一调用"方式的(SINGLE CALL)。意思是每一次的函数调用都会在服务器端创建一个新的实例。(REMOTING还支持Singleton和ClientActivation两种方法)

那么解决如何保存"状态"呢?就前面的这个小问题来说,你可以这样修改一下程序。

class Student : System.Web.Services.WebService
 {
    private String name;
    [WebMethod (EnableSession=true)]
    public String getName()
    {
        return (String)Session["NAME"];
    }
    [WebMethod (EnableSession=true)]
    public void setName(String aName)
    {
        Session["NAME"] = aName;
    }   
}

...
localhost.Student student = new localhost.Student();
student.CookieContainer = new System.Net.CookieContainer();
student.setName("Lao Wang");
String myInfo = student.getName();
...

这样一改,问题就解决了。其"奥秘"在于你引入了ASP.NET中的"会话状态"管理机制(SESSION STATE MANAGEMENT)。如果你做过ASP或ASP.NET开发的话,你就回马上明白这一点。就象我前面所说, WEB SERVICE是在WEB上提供的SERVICE,WEB上的许多东西在WEB SERVICE里同样适用。"会话状态"管理机制是WEB SERVICE中最普遍采用的一种保存"状态"的方法,它将信息存在于服务器端,所以适宜保存比较敏感的信息,例如信用卡号码,银行帐号什么的。并且SESSION中可以存放各种复杂的数据结构甚至是COM对象的实例,这使得它可以用来实现很复杂的状态保存。

posted on 2010-12-29 16:59  GIS飞行者  阅读(400)  评论(0编辑  收藏  举报