![]() |
|
Spaces home StephenChen's Tech SpacePhotosProfileFriendsMore ![]() | ![]() |
StephenChen's Tech Spacemake difference
VMware6安装Ubuntu8解决分辨率和鼠标滚轮问题
用VMware6安装Ub8的时候默认的分辨率是800*600的,基本上怎么改都改不了。实际上要改变Ub8的分辨率,需要安装一个工具,即是VMware-tool,这个工具一般VMware都会在左下角提示安装的,安装这个工具后就可以随意地选择适合自己的分辨率。 安装过程大致如下: 1.VMware菜单栏VM,选择Install VMware-tool,要注意在虚拟机系统已经开启的前提下才能进行这个操作;
至于滚轮问题,用root的权限打开/etc/X11/xorg.conf文件,相应地将下面的内容加上去,将原来是"Configured Mouse"的配置内容注释掉#或者是删除,然后重启即可。虽然基本上解决了滚轮的问题,但是通过滚轮切换桌面还是不行。 Section "InputDevice" [转]Session详解摘要:虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一技术。本文将详细讨论session的工作机制并且对在Java web application中应用session机制时常见的问题作出解答。 目录: 一、术语session session,中文经常翻译为会话,其本来的含义是指有始有终的一系列动作/消息,比如打电话时从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session。有时候我们可以看到这样的话“在一个浏览器会话期间,...”,这里的会话一词用的就是其本义,是指从一个浏览器窗口打开到关闭这个期间①。最混乱的是“用户(客户端)在一次会话期间”这样一句话,它可能指用户的一系列动作(一般情况下是同某个具体目的相关的一系列动作,比如从登录到选购商品到结账登出这样一个网上购物的过程,有时候也被称为一个transaction),然而有时候也可能仅仅是指一次连接,也有可能是指含义①,其中的差别只能靠上下文来推断②。 然而当session一词与网络协议相关联时,它又往往隐含了“面向连接”和/或“保持状态”这样两个含义,“面向连接”指的是在通信双方在通信之前要先建立一个通信的渠道,比如打电话,直到对方接了电话通信才能开始,与此相对的是写信,在你把信发出去的时候你并不能确认对方的地址是否正确,通信渠道不一定能建立,但对发信人来说,通信已经开始了。“保持状态”则是指通信的一方能够把一系列的消息关联起来,使得消息之间可以互相依赖,比如一个服务员能够认出再次光临的老顾客并且记得上次这个顾客还欠店里一块钱。这一类的例子有“一个TCP session”或者“一个POP3 session”③。 而到了web服务器蓬勃发展的时代,session在web开发语境下的语义又有了新的扩展,它的含义是指一类用来在客户端与服务器之间保持状态的解决方案④。有时候session也用来指这种解决方案的存储结构,如“把xxx保存在session里”⑤。由于各种用于web开发的语言在一定程度上都提供了对这种解决方案的支持,所以在某种特定语言的语境下,session也被用来指代该语言的解决方案,比如经常把Java里提供的javax.servlet.http.HttpSession简称为session⑥。 鉴于这种混乱已不可改变,本文中session一词的运用也会根据上下文有不同的含义,请大家注意分辨。 二、HTTP协议与状态保持 然而聪明(或者贪心?)的人们很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用,就像给有线电视加上点播功能一样。这种需求一方面迫使HTML逐步添加了表单、脚本、DOM等客户端行为,另一方面在服务器端则出现了CGI规范以响应客户端的动态请求,作为传输载体的HTTP协议也添加了文件上载、cookie这些特性。其中cookie的作用就是为了解决HTTP协议无状态的缺陷所作出的努力。至于后来出现的session机制则是又一种在客户端与服务器之间保持状态的解决方案。 让我们用几个例子来描述一下cookie和session机制之间的区别与联系。笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案: 由于HTTP协议是无状态的,而出于种种考虑也不希望使之成为有状态的,因此,后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。 三、理解cookie机制 正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie。 而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。意思是麦当劳的会员卡只能在麦当劳的店里出示,如果某家分店还发行了自己的会员卡,那么进这家店的时候除了要出示麦当劳的会员卡,还要出示这家店的会员卡。 cookie的内容主要包括:名字,值,过期时间,路径和域。 存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式。对于IE,在一个打开的窗口上按Ctrl-N(或者从文件菜单)打开的窗口可以与原窗口共享,而使用其他方式新开的IE进程则不能共享已经打开的窗口的内存cookie;对于Mozilla Firefox0.8,所有的进程和标签页都可以共享同样的cookie。一般来说是用javascript的window.open打开的窗口会与原窗口共享内存cookie。浏览器对于会话cookie的这种只认cookie不认人的处理方式经常给采用session机制的web应用程序开发者造成很大的困扰。 下面就是一个goolge设置cookie的响应头的例子
这是使用HTTPLook这个HTTP Sniffer软件来俘获的HTTP通讯纪录的一部分
浏览器在再次访问goolge的资源时自动向外发送cookie
使用Firefox可以很容易的观察现有的cookie的值
IE也可以设置在接受cookie前询问
这是一个询问接受cookie的对话框。 四、理解session机制 当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。 保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID,而。比如weblogic对于web应用程序生成的cookie,JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是JSESSIONID。 由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为http://...../xxx;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如下面的表单 在谈论session机制的时候,常常听到这样一种误解“只要关闭浏览器,session就消失了”。其实可以想象一下会员卡的例子,除非顾客主动对店家提出销卡,否则店家绝对不会轻易删除顾客的资料。对session来说也是一样的,除非程序通知服务器删除一个session,否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session。 恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。 五、理解javax.servlet.http.HttpSession 首先,Weblogic Server提供了一系列的参数来控制它的HttpSession的实现,包括使用cookie的开关选项,使用URL重写的开关选项,session持久化的设置,session失效时间的设置,以及针对cookie的各种设置,比如设置cookie的名字、路径、域,cookie的生存时间等。 一般情况下,session都是存储在内存里,当服务器进程被停止或者重启的时候,内存里的session也会被清空,如果设置了session的持久化特性,服务器就会把session保存到硬盘上,当服务器进程重新启动或这些信息将能够被再次使用,Weblogic Server支持的持久性方式包括文件、数据库、客户端cookie保存和复制。 复制严格说来不算持久化保存,因为session实际上还是保存在内存里,不过同样的信息被复制到各个cluster内的服务器进程中,这样即使某个服务器进程停止工作也仍然可以从其他进程中取得session。 cookie生存时间的设置则会影响浏览器生成的cookie是否是一个会话cookie。默认是使用会话cookie。有兴趣的可以用它来试验我们在第四节里提到的那个误解。 cookie的路径对于web应用程序来说是一个非常重要的选项,Weblogic Server对这个选项的默认处理方式使得它与其他服务器有明显的区别。后面我们会专题讨论。 关于session的设置参考[5] http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869 六、HttpSession常见问题 1、session在何时被创建 由于session会消耗内存资源,因此,如果不打算使用session,应该在所有的JSP中关闭它。 2、session何时被删除 3、如何做到在浏览器关闭时删除session 4、有个HttpSessionListener是怎么回事 5、存放在session中的对象必须是可序列化的吗 6、如何才能正确的应付客户端禁止cookie的可能性 7、开两个浏览器窗口访问应用程序会使用同一个session还是不同的session 8、如何防止用户打开两个浏览器窗口操作导致的session混乱 9、为什么在Weblogic Server中改变session的值后要重新调用一次session.setValue 10、为什么session不见了 七、跨应用程序的session共享 然而按照Servlet规范,session的作用范围应该仅仅限于当前应用程序下,不同的应用程序之间是不能够互相访问对方的session的。各个应用服务器从实际效果上都遵守了这一规范,但是实现的细节却可能各有不同,因此解决跨应用程序session共享的方法也各不相同。 首先来看一下Tomcat是如何实现web应用程序之间session的隔离的,从Tomcat设置的cookie路径来看,它对不同的应用程序设置的cookie路径是不同的,这样不同的应用程序所用的session id是不同的,因此即使在同一个浏览器窗口里访问不同的应用程序,发送给服务器的session id也可以是不同的。
根据这个特性,我们可以推测Tomcat中session的内存结构大致如下。
笔者以前用过的iPlanet也采用的是同样的方式,估计SunONE与iPlanet之间不会有太大的差别。对于这种方式的服务器,解决的思路很简单,实际实行起来也不难。要么让所有的应用程序共享一个session id,要么让应用程序能够获得其他应用程序的session id。 iPlanet中有一种很简单的方法来实现共享一个session id,那就是把各个应用程序的cookie路径都设为/(实际上应该是/NASApp,对于应用程序来讲它的作用相当于根)。 需要注意的是,操作共享的session应该遵循一些编程约定,比如在session attribute名字的前面加上应用程序的前缀,使得setAttribute("name", "neo")变成setAttribute("app1.name", "neo"),以防止命名空间冲突,导致互相覆盖。 在Tomcat中则没有这么方便的选择。在Tomcat版本3上,我们还可以有一些手段来共享session。对于版本4以上的Tomcat,目前笔者尚未发现简单的办法。只能借助于第三方的力量,比如使用文件、数据库、JMS或者客户端cookie,URL参数或者隐藏字段等手段。 我们再看一下Weblogic Server是如何处理session的。
从截屏画面上可以看到Weblogic Server对所有的应用程序设置的cookie的路径都是/,这是不是意味着在Weblogic Server中默认的就可以共享session了呢?然而一个小实验即可证明即使不同的应用程序使用的是同一个session,各个应用程序仍然只能访问自己所设置的那些属性。这说明Weblogic Server中的session的内存结构可能如下
对于这样一种结构,在session机制本身上来解决session共享的问题应该是不可能的了。除了借助于第三方的力量,比如使用文件、数据库、JMS或者客户端cookie,URL参数或者隐藏字段等手段,还有一种较为方便的做法,就是把一个应用程序的session放到ServletContext中,这样另外一个应用程序就可以从ServletContext中取得前一个应用程序的引用。示例代码如下, 应用程序A 应用程序B 值得注意的是这种用法不可移植,因为根据ServletContext的JavaDoc,应用服务器可以处于安全的原因对于context.getContext("/appA");返回空值,以上做法在Weblogic Server 8.1中通过。 那么Weblogic Server为什么要把所有的应用程序的cookie路径都设为/呢?原来是为了SSO,凡是共享这个session的应用程序都可以共享认证的信息。一个简单的实验就可以证明这一点,修改首先登录的那个应用程序的描述符weblogic.xml,把cookie路径修改为/appA访问另外一个应用程序会重新要求登录,即使是反过来,先访问cookie路径为/的应用程序,再访问修改过路径的这个,虽然不再提示登录,但是登录的用户信息也会丢失。注意做这个实验时认证方式应该使用FORM,因为浏览器和web服务器对basic认证方式有其他的处理方式,第二次请求的认证不是通过session来实现的。具体请参看[7] secion 14.8 Authorization,你可以修改所附的示例程序来做这些试验。 八、总结 javascript基础知识拾遗--表单
一、文本框 HTML中有两种不同类型的文本框,单行的(<input type=”text”/>)和多行的(<textarea></textarea>)。单行的文本框可以通过size属性来控制输入字符的数量,多行的<textarea>可以通过cols和rows指定文本框的宽和高,但初始值必须在<textarea>和</textarea>之间,并不能指定允许的最大字符数。两种文本框都可以使用length属性来获取当前文本框中文本长度。 选择文本可以通过focus()和select()两个方法并用使文本框获取焦点。除了blur和focus事件后,文本框还支持change事件和select事件。其中change事件是当用户更改内容后文本框失去焦点时发生(如果是通过value特性来更改内容则不会触发)。select事件是当一个或多个字符被选中时发生,无论是手工选中还是用select()方法。 注意change事件和blur事件的区别。只要文本框失去焦点,就触发blur事件,而change事件只有当文本框内的文本发生改变后,失去焦点时才触发。如果文本不变,但文本框失去焦点,那么只有blur事件被触发;如果文本发生了变化,则先触发change事件,然后触发blur事件。
二、列表框和组合框 列表框和组合框是通过HTML的<select/>元素来创建的。 访问选项: DOM方法: oListBox.options[1].firstChild.nodeValue; //显示text oListBox.options[1].getAttribute(“value”); //显示value HTML DOM方法: oListBox.options[1].text; oListBox.options[1].value; 每个option有一个index属性,表示它在options集合中的索引: oListBox.options[1].index; //输入1 由于options是一个集合,因此也可以通过length属性来获取options的数量。
更新选项: <select/>有一个selectedIndex特性表示当前选中选项的索引(如果没有选中则返回-1)。列表框可以选择多个选项,,只要将<select/>元素的multiple特性设置为”multiple”,这时selectedIndex返回的是第一个被选中的索引。 添加选项可以通过一系列的create*方法和appendChild方法来实现,而删除选项就可以直接这样oListBox.optioins[1]=null,或者oListBox.remove(1)。 C/C++面试题拾遗1.写出判断ABCD四个表达式的是否正确, 若正确, 写出经过表达式中 a的值(3分) 总结:(a++)不能作为左值进行赋值,但(++a)可以 2.某32位系统下, C++程序,请计算sizeof 的值(5分). 总结:sizeof(数组变量名)得到正确的数组大小(包含后面的'\0',strlen不包含最后的'\0'),指针的大小为4字节,函数参数传递的是数组指针 3. void Test(void){ 总结:free()后就不能再引用free的指针, 但是并不把指针所指的内存里的数据删除,只是告诉操作系统这块内存,已经不用了,系统可以用于其他的地方,所以free后这块内存中的数据是不可预测的, 而且free操作并不把指针设置为NULL.所以在使用free()时在后面加上设置为NULL的语句,以免对野指针的引用,是程序有不可预料的结果.进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。 4.头文件的作用 5.const与#define的比较 6.辨析 7.引用与指针的区别 8. 编写strcat函数(6分) 9.static有什么用途?(请至少说明两种) 10.写出float x 与“零值”比较的if语句。 11.数组指针 printf("%d,%d",*(a+1),*(ptr-1)); 12.操作字符串函数的源码 13.找出程序错误 14.判断宏输出 15.编写一个函数,作用是把一个char组成的字符串循环 16.memcpy int main () 17.memset int main () 18.编写类String的构造函数、析构函数和赋值函数 String& String::operator =(const String &rhs) String::~String() 19.const关键字的作用 20.C++中的空类,默认产生哪些类成员函数 21.一个由C/C++编译的程序占用的内存组成结构: [转]Javascript的IE和Firefox兼容性汇编以下以 IE 代替 Internet Explorer,以 MF 代替 Mozzila Firefox
javascript基础知识拾遗--DOM
一、DOM基础
除节点外,DOM还定义了一些助手对象,它们可以和节点一起使用,但不是DOM文档必有的部分。
二、使用DOM 1.访问相关结点 var oHtml = document.documentElement; //访问<html/>元素,IE5.5中会返回<body/>元素 var oHead = oHtml.firstChild; //访问<head/>元素,亦可oHtml.childNodes[0] var oBody = oHtml.lastChild; //访问<body/>元素,亦可oHtml.childNodes[1] 实际上正式地从列表中获取子节点的方法是使用item()方法(oHtml.childNodes.item(index))。不同浏览器在判断何为Text节点上存在一些差异。某些浏览器,如Mozilla,认为元素之间的空白都是Text节点;而另一些浏览器,如IE,会全部忽略这些空白。因此在获取节点总数和相邻的时候需要注意。 2.处理特性 只有Element才能有特性。Element节点的attributes属性其实是NamedNodeMap,它提供一些用于访问和处理其内容方法: getNamedItem(name)--返回nodename属性值等于name的节点; Eg: <p style="color:red" >Hello world!</p> Attr节点也有一个完全等同于(同时也完全同步于)nodeValue属性的value属性,并且有name属性和nodeName属性保持同步 因为这个方法有些累赘,DOM又定义了三个元素方法来帮助访问特性,这些方法使用起来相当地方便: 3.访问指定节点 (1)getElementsByTagName() 4.创建和操作节点 createElement()、createTextNode()、appendChild() 这三个函数作用分别是创建元素节点,创建文本节点,添加节点。 Eg: var oP = document.createElement(“p”); var oText = document.createTextNode(“Hello World!“); oP.appendChlid(oText); document.body.appendChild(oP); 值得注意的是,所有的DOM操作必须在页面完全载入后才能进行。当页面正在载入时,要向DOM插入相关代码是不可能的,因为在页面完全下载到客户端机器之前,是无法完全构建DOM树。因为这个原因,必须使用onload事件句柄 来执行所有的代码。 <body onload=”createMessage()”> .... </body> removeChild()、replaceChild()、insertBefore() 用于更新节点,分别是删除子节点,替换子节点,插入子节点 Eg: var oP = document.getElementById(“op”); oP.parentNode.replaceChild(newChild, oldChild); oP.parentNode.insertBefore(newChild, beforeChild); oP.parentNode.removeChild(oP); createDocumentFragment() 假如想创建十个新段落。 function addMessages() { 对碎片使用appendChild不是把文档碎片节点本身追加到元素中,而是仅仅追加碎片中的子节点,这意味着只需要进行一次屏幕刷新,具有相当好的性能提升。
三、HTML DOM 1.让特性像属性一样 大部分情况下,HTML DOM元素中包含的所有特性都是可作为属性。 2.table方法 为了协助建立表格,HTML DOM给<table/>,<tbody/>和<tr/>等元素添加了一些特性和方法。 <tbody/>元素添加了以下内容 <tr/>元素添加了以下内容 Eg: //create table var oTable = document.createElement(“table”); oTable.setAttribute(“border”, “1”); oTable.setAttribute(“width”, “100%”); //create the tbody var oTBody = document.createElement(“tbody”); oTable.appendChild(oTBody); //create first row oTBody.insertRow(0); oTBody.rows[0].insertCell(0); oTBody.rows[0].cells[0].appendChild(document.createTextNode(“Cell 1.1”)); //add table to document body document.body.appendChild(oTable); MVC与架构初探一、 MVC模式开发1. 什么是MVC模式MVC,model-view-controller,即模型-视图-控制器,MVC模式把应用程序的输入、逻辑处理和输出强制地分出三个部分。这三个核心的部分分别是模型、视图和控制器,这三个部分只负责完成各自需要处理的任务,无需涉及到其它部分的内部工作。使用MVC的目的是将模型和视图实现代码分离,也就是说令数据逻辑模型和用户界面分离,从而使同一个程序可以使用不同的表现形式和用户界面。控制器存在的目的是确保模型和视图的同步,一旦模型改变,视图也能够同步地更新,保证模型处理的逻辑结果能够及时地反映到用户界面上。 2. 模型 Model模型表示数据的载体,并包含着对数据进行逻辑处理的规则。模型充当着对业务流程的处理和相关业务规则的制定的角色,是MVC模式的主要核心。为了使模型能够应用于多种视图技术,由模型处理并返回的数据需要保持中立,即是说模型与数据格式无关,从而模型的代码能够被应用于多种视图。 3. 视图 View视图负责组织模型返回的内容,并将这些数据以指定的形式表现,代表着用户交互界面。对于Web应用程序,视图就是由HTML元素组成的界面,如jsp,php,aspx等等页面。视图将模型的数据呈现的同时,也负责从用户操作中获取数据,返回给模型和控制器处理。 4. 控制器 Controller控制器接受用户的输入并调用模型和视图去完成用户的需求。控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后确定用哪个视图来显示模型处理后返回的数据。控制器定义用户界面对用户输入的响应方式,负责把用户的动作转成针对于模型的操作。模型通过更新视图来反映数据的变化。 5. 应用MVC模式首先控制器接收用户的请求,并决定应该调用哪个模型来进行处理,然后模型用业务逻辑来处理用户的请求并返回数据,最后控制器用相应的视图模式化模型返回的数据,并通过表示层呈现给用户。 在基于JavaEE的开发上,JSP充当着视图的角色,Servlet负责完成控制器的接收请求和分发处理的工作,JavaBean完成大部分的业务处理和逻辑判断。 多个JSP视图可以对应一个JavaBean模型,从而可以减少代码的复制及代码的维护量,一旦JavaBean发生改变,也易于维护。 JavaBean返回的数据可以与显示的JSP分离。这些数据可以应用任何的显示技术,例如使用JSP页面、Velocity模板或者直接产生Excel文档等。 Web应用被分隔为三层,降低了各层之间的耦合,提供了应用的可扩展性。当某层被改变或者扩展时,对其他层的影响能够降到最低。 Servlet把不同的JavaBean和不同的JSP视图组合在一起,完成不同的请求。因此,在控制器层包含了用户请求权限的概念。 经典的MVC思想与Web应用的MVC思想存在一定的差别,主要是因为Web应用是一种请求/响应模式下应用,对于请求/响应应用,如果用户不对应发出请求,视图无法主动更新自己。 二、 模式与架构1. 系统架构说明软件架构包括对一个软件系统组织结构的重大决策。软件架构应该能够描述系统的结构以及系统如何支持业务和质量方面的需求。软件架构是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计。 软件体系结构是构建计算机系统的基础,软件架构作为一个系统的草图,其描述的对象是直接构成系统的抽象组件。各个组件之间的连接则明确和相对细致地描述组件之间的通讯。在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个类或者对象。在面向对象领域中,组件之间的连接通常用接口来实现。 软件系统的优劣可以通过性能,可伸缩性,可靠性,可使用性,可扩展性,可维护性,可管理性,安全性等方面进行考察和衡量。 2. 三层架构三层架构是JavaEE开发的经典架构,三层主要是表现层、中间层(业务逻辑层)和数据访问层,其中还有一个域模型层,贯穿在三层之间。三层体系将业务规则、数据访问和合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库进行交互。 中间层还可以进一步分成Web层、业务逻辑层、DAO层等等。Web层负责控制业务逻辑层与表现层的交互,调用业务逻辑层,并将业务逻辑层的数据返回给表现层作组织表现。Service层(业务逻辑层)负责实现业务逻辑,以DAO层为基础,通过对DAO组件的正面模式包装,完成系统所要求的业务逻辑。DAO层负责与持久化对象交互,该层封装了数据的增、删、查、改的操作。 3. MVC与三层架构MVC模式是一种设计思想,是指导软件开发过程中如何根据实际的问题组织系统的元素和抽象元素之间的关系。这种设计思想能够应用于广泛的程序开发领域。MVC设计与三层架构不冲突也不矛盾,三层架构是对MVC设计思想的一种客观体现和应用。 在三层架构中,表现层与MVC的View视图是一致的。中间层通过进一步的划分可以体现到MVC的设计思想和分层原理,三层架构中的中间层可以进一步划分Web层、业务逻辑层和DAO层,其中Web层与MVC的Controller控制器是一致,均充当着请求转发的职责。中间层的业务逻辑层、DAO层,域模型层,以及数据服务层充当了MVC的Model,负责完成系统的主要业务流程。 MVC作为一种设计思想,充分体现了一种如何以灵活性,低耦合,高复用的设计方案来组织系统的元素。三层架构在MVC设计思想的基础,结合实际的应用开发,对MVC设计思想中的元素进行细分再组织来实现一种富有灵活性,低耦合,高内聚,可复用的系统架构。 三、 MVC框架-Struts,Spring,Hibernate1. StrutsStruts是MVC模式的完整且典型的实现,对Model、View和Controller都提供了相应的实现,其具体的实现如下: Struts的Model部分由ActioinForm和JavaBean组成。其中ActionForm用于封装用户请求参数,所有的用户请求参数由系统自动封装成ActionForm对象;然后Action根据ActionForm里的请求参数处理用户请求。JavaBean则封装了底层的业务逻辑,包括数据库访问等等。 Strus的View部分采用JSP实现。Struts提供了丰富的标签库,通过这些标签库可以最大限度地减少脚本的使用,同时,这些标签库可以实现与Model的有效交互,并增加显示功能。 Struts的Controller由两个部分组成,系统核心控制器和业务逻辑控制器。系统核心控制器对应上图的Controller Servlet,这种控制器由Struts框架提供,继承了HttpServlet类,负责拦截所有的HTTP请求,然后根据用户请求决定是否需要调用业务逻辑控制器。业务逻辑控制器负责处理用户请求,但其本身不具有处理能力,而是通过调用Model来完成处理。业务逻辑控制器对应于上图的Action。 2. SpringSpring是一个轻量及的控制反转(IoC)和面向切面(AOP)的容器框架。Spring是为了解决企业应用开发的复杂性而创建的,但Spring的用途不仅限于服务器端的开发,Spring的优势能够在广泛的Java应用中得到体现。 控制反转,或者称为依赖注入,是指创建被调用者的工作不再由调用者来完成,通常由Spring容器来完成,然后注入到调用者。Spring采用动态及灵活的方式来管理各种对象,通过面向接口编程,结合依赖注入,使对象与对象之间的具体实现互相透明。Spring内置了大量的工厂模式和单态模式来实例化和管理Spring容器中的全部对象。 面向切面编程AOP,能够将系统组件和服务模块化,将它们声明式地应用在需要它们的地方,使得这些组件更加专注于自身的业务,而不需要知道和了解其涉及的系统服务。使开发者能以声明式、基于元数据访问企业级,合理地补充了OOP技术。 3. HibernateORM全称是Object/Relation Mapping,即对象/关系映射。ORM是一种技术,这种技术实现了面向对象的程序设计语言与关系数据库的映射,实现这种ORM技术的框架有多种,Hibernate是其中流行的一个。 Hibernate对JDBC进行了非常轻量级的对象封装,使得程序员在开发过程中可以随心所欲地使用对象编程思维来操纵数据库。通过内置的多个Hibernate核心接口对象:Session、SessionFactory、Transaction、Query和Configuration,Hibernate能够以对象的形式获取或者保存数据。 Hibernate通过映射文档,将Java类与数据库的表关联起来,并且有效地管理数据库的数据与Java类之间的转换,实现了数据库与程序的对象/关系映射。 4. 整合SSH实现MVCStruts和Spring都是相当优秀的MVC框架,通过Struts和Spring的整合能够弥补两个框架的不足,体现更强大的功能。Struts和Spring有三种整合方案,不同的方案实现程序的解耦程度不同。本人偏向于使用Spring的RequestProcessor来代替Struts的请求转发,这些通过Spring能控制请求的转发,能够使Action部署在Spring的容器中,由Spring统一管理Action和其他的业务对象,充分地利用了Spring的依赖注入的特性,同时也降低了Struts和Spring的耦合程度。Struts提供了控制器和表示层的控制,Spring负责管理所有的中间层组件对象。 DAO层通过对Hibernate提供的核心接口对象进行封装使用,充分地利用了Hibernate提供了ORM的持久化技术,通过面向对象的方式与数据库进行交互。Spring提供的DAO组件进一步简化了持久层访问,通过对SessionFactory的依赖注入简化了Session的控制。 [转]针对Web系统常用的功能测试方法浅析功能测试就是对产品的各功能进行验证,根据功能测试用例,逐项测试,检查产品是否达到用户要求的功能。针对Web系统的常用测试方法如下: 来源:中国IT实验室 SSH配置错误及解决方案拾遗问题描述: 解决方案:包冲突,去掉asm-2.2.3.jar成功启动
问题描述: 解决方案:工程没有添加dom4j.jar这个包
问题描述: 解决方案:原因是工具myEclipse在建立SessionFactory的时候,少加一个包 commons-pool-1.3.jar 补上去问题解决。
问题描述: 原因及解决方案:
问题描述: 解决方案:在struts-config.xml中配置了一个parameter="method",这个应该是在使用DispatchAction的时候忘了在action的配置中要加上parameter的属性设置。 javascript基础知识拾遗--事件
1.事件流 事件流有两种,分别是冒泡型事件流和捕获型事件流。冒泡型事件流是按照DOM的层次结构从里层向外层进行上溯,事件按照从最特定的事件目标到最不特定的事件目标的顺序进行触发,如下图中,从target一直向上触发事件到observer,以至到root。捕获型事件流和冒泡型是相反的事件触发过程,即在捕获型事件中,事件从最不精确的对象开始触发,然后到最精确的对象。 在IE中,支持冒泡型事件流。而DOM则同时支持两种事件模型(这就是为什么在DOM的监听函数中有第三个参数来识别事件处理函数所在的事件流),但是捕获型事件先发生,两种事件触及DOM中所有对象的,从document对象开始,也在document对象结束,也就是说事件的目标会连续接收两次事件,一次在捕获过程中,另一次在冒泡过程中,当然两次的事件处理函数可以不同。DOM事件模型最独特的性质是,文本节点也触发事件(在IE中不会),即点击文本,文本可以产生事件。
2.事件处理/监听函数 (1)IE 在IE中,每个元素和window对象都有两个方法:attachEvent()和detachEvent()。顾名思义,attachEvent()用来给一个事件附加事件处理函数,而detachEvent()用来将事件处理函数分离出来。每个方法都有两个参数:要分配的事件处理函数的名字(例如:onclick)及一个处理函数。 [Object].attachEvent(“name_of_event_handler”, fnHandler); [Object].detachEvent(“name_of_event_handler”, fnHandler); Eg: var fnClick = function() { alert(“Clicked!”); }; var oDiv = document.getElementById(“odiv”); oDiv.attachEvent(“onclick”, fnClick); //oDiv.onclick = fnClick 亦可 oDiv.detachEvent(“onclick”, fnClick); 可以使用多个attachEvent()来为一个事件添加多个处理函数,事件处理函数总是按照添加它们的顺序来进行调用。
(2)DOM DOM方法addEventListener()和removeEventListener()用来分配和移除事件处理函数。与IE不同,这些方法需要三个参数:事件名称,要分配的函数和处理函数是用于冒泡阶段还是捕获阶段。如果事件处理函数是用于捕获阶段,则第三个参数为true;用于冒泡阶段,则第三个参数为false。用removeEventListener()移除事件的时候要注意正确选择在冒泡阶段还是捕获阶段。如果添加在冒泡阶段中的处理函数,尝试在捕获阶段删除,这不会产生错误,但函数是不会删除的。 [Object].addEventListener(“name_of_event”, fnHandler, bCapture); [Object].removeEventListener(“name_of_event”, fnHandler, bCapture); Eg: var fnClick = function() { alert(“Clicked!”); }; var oDiv = document.getElementById(“oDiv”); oDiv.addEventListener(“click”, fnClick, false); oDiv.removeEventListener(“click”, fnClick, false); 与IE一样,也可以为一个事件添加多个事件处理函数,其执行顺序还是会按照指定它们的顺序进行调用。
3.事件对象 (1)获取事件对象 事件对象包含了事件发生的信息,事件对象只在发生事件时才被创建,且只有事件处理函数才能访问。所有事件处理函数执行完毕后,事件对象就被销毁了。 在IE中,事件对象是window对象的一个属性event。事件处理函数必须这样访问事件对象: oDiv.onclick = function() { var oEvent = window.event; } 尽管它是window对象的属性,event对象还是只能在事件发生时访问。所有的事件处理函数执行完毕后,事件对象就被销毁了。 在DOM标准中,event对象必须作为唯一的参数传给事件处理函数,做法如下: oDiv.onclick = function() { var oEvent = arguments[0]; } 或者可以直接命名参数,访问就更方便了: oDiv.onclick = function(oEvent) { }
(2)IE与DOM的事件对象相似总结 获取事件类型:var sType = oEvent.type; 获取按键代码(keydown/keyup事件):var iKeyCode = oEvent.keyCode; 检测Shift、Alt、Ctrl键:oEvent.shiftKey, oEvent.altKey, oEvent.ctrlKey 获取客户端坐标:oEvent.clientX, oEvent.clientY 获取屏幕坐标:oEvent.screenX, oEvent.screenY
(3)IE与DOM的事件对象区别总结 <1>获取事件的目标 目标是指触发事件的目标,IE目标只能是元素、文档或者窗口,而DOM兼容的浏览器也允许文本作为目标。 在IE中,目标包含在event对象的srcElement属性中: var oTarget = oEvent.srcElement; 在DOM兼容的浏览器中,目标包含在target属性中: var oTarget = oEvent.target; <2>获取字符代码 Ie和DOM都支持event对象的keyCode属性,它会返回按下按键的数值代码。如果按键代表一个字符(非Shift、Ctrl、Alt等),IE的keyCode返回字符代码(等于它的Unicode值): var iCharCode = oEvent.keyCode; 在DOM兼容的浏览器中,按键的代码和字符代码会有一个分离。对于按键是字符的处 | |||||||||