<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>ttitfly的笔记</title>
    <description></description>
    <link>http://ttitfly.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>javascript---类的继承</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/194252" style="color:red;">http://ttitfly.javaeye.com/blog/194252</a>&nbsp;
          发表时间: 2008年05月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1.<span style="color: red">第一种方式,冒充对象的方式.(利用js里的每一个方法名都是一个Function对象)</span><br /><br /><pre name="code" class="java">

//第一种方式,冒充对象的方式.(利用js里的每一个方法名都是一个Function对象)
function Parent(username){
	this.username = username;
	this.say = function(){
		alert(this.username);
	}
}

function Child(username,password){
	
	this.temp = Parent;//temp指向Parent所指向的地方 。 利用js里的每一个方法名都是一个Function对象,指向一个方法。
	this.temp(username);//初始化方法里的内容
	delete this.temp;//temp没有用了。可以直接删除掉.this不可以丢了
	
	
	//Parent(username);//这样写表面看起来是正确的，其实是错误的。因为只有new出来的对象才有this,所以调用Parent里的this就没有值了
	
	
	this.password = password;
	this.hello = function(){
		alert(this.password);
	}
}

var parent = new Parent("zhangsan");
parent.say();//zhangsan

var child = new Child("lisi","123456");
child.say();//lisi
child.hello();//123456
</pre><br /><br />2.<span style="color: red">第二种方式：call()函数方式</span><br /><br />call()函数是Function对象的一个函数，具体用法如下<br /><pre name="code" class="java">
//call()函数是Function对象的一个函数
//具体用法如 
function test(str){
	alert(this.username + ","  + str);
}

var o = new Object();
o.username = "zhangsan";
test.call(o,"123456");//zhangsan,123456 .因为每个Function 对象都有一个call()方法，而函数名就是一个Function对象.call()函数的第一个参数是test函数里的this.
</pre><br /><br />所以继承可以这样实现：<br /><pre name="code" class="java">
function Parent(username){
	this.username = username;
	this.say = function(){
		alert(this.username);
	}
}
function Child(username,password){
	Parent.call(this,username);
	this.password = password;
	this.hello = function(){
		alert(this.password);
	}
}
var parent = new Parent("zhangsan");
parent.say();//zhangsan

var child = new Child("lisi","123456");
child.say();//lisi
child.hello();//123456
</pre><br /><br /><br />3.<span style="color: red">第三种实现方式:apply()函数方式，apply()和call()是一样的，只不过参数传递不同而已,apply的参数为数组</span><br /><br /><pre name="code" class="java">
//第三种实现方式:apply()函数方式，apply()和call()是一样的，只不过参数传递不同而已,apply的参数为数组
//所以继承可以这样实现

function Parent(username){
	this.username = username;
	this.say = function(){
		alert(this.username);
	}
}
function Child(username,password){
	Parent.apply(this,new Array(username));
	this.password = password;
	this.hello = function(){
		alert(this.password);
	}
}
var parent = new Parent("zhangsan");
parent.say();//zhangsan

var child = new Child("lisi","123456");
child.say();//lisi
child.hello();//123456
</pre><br /><br /><br />4.<span style="color: red"> 第4种方式:原型链实现继承</span><br /><br /><pre name="code" class="java">
//原型链实现继承
function Parent(){
}
Parent.prototype.hello = "hello";
Parent.prototype.sayHello = function(){
	alert(this.hello);
}

function Child (){
}
Child.prototype = new Parent();//关键

Child.prototype.world = "world";
Child.prototype.sayWorld = function(){
	alert(this.world);
}

var child = new Child();
child.sayHello();
child.sayWorld();
</pre><br /><br />5.<span style="color: red">第五种方式:混合模式实现继承</span><br /><pre name="code" class="java">
//混合模式实现继承
function Parent(hello){
	this.hello = hello;
}
Parent.prototype.sayHello = function(){
	alert(this.hello);
}

function Child(hello,world){
	this.world = world;
	Parent.call(this,hello);//关键

}
Child.prototype = new Parent(); //关键
Child.prototype.sayWorld = function(){
	alert(this.world);
}

var child = new Child("hello","world");
child.sayHello();
child.sayWorld();
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/194252#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 19 May 2008 10:10:38 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/194252</link>
        <guid>http://ttitfly.javaeye.com/blog/194252</guid>
      </item>
      <item>
        <title>javascript---类的构建</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/193663" style="color:red;">http://ttitfly.javaeye.com/blog/193663</a>&nbsp;
          发表时间: 2008年05月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          javascript里构建类主要有4种方式<br />1.构造方式定义类<br />2.原型方式定义类<br />3.构造和原型结合方式创建类<br />4.动态的原型方式<br /><br />各有优缺点,具体如下<br />1.<span style="color: red">构造方式定义类，优点:多个实例对象不共享类的属性值，缺点:每个实例对象都会产生出一个函数say</span><br /><br /><pre name="code" class="java">
//构造方式定义类，优点:多个实例对象不共享类的属性值，缺点:每个实例对象都会产生出一个函数say
function User(){
	this.username = "zhangsan";//this.不能丢
	
	this.say = function(){//this.不能丢
		alert("username:" + this.username );//this.不能丢
	}
	//下面注释的这种写法不对
//	function say(){
//		alert("username:" + this.username );
//	}
}

var user = new User();
user.username = "lisi";
user.say();//username:lisi

var user1 = new User();
user1.say();//username:zhangsan,不受user对象的影响
</pre><br /><br />//多个实例对象不共享类的属性值:<br /><pre name="code" class="java">
//多个实例对象不共享类的属性值，如下:
function User(){
	this.username = new Array();//this.不能丢
	
	this.say = function(){//this.不能丢
		alert("username:" + this.username );//this.不能丢
	}
}

var user = new User();
user.username.push("zhangsan");
user.say();//username:zhangsan

var user1 = new User();
user1.say();//user1的username为空，不为zhangsan,因为user1的属性值不受user影响
</pre><br /><br />2.<span style="color: red">原型方式定义类,缺点:类的属性值如果是引用类型的(非Number和String类型)，则多个实例对象共享</span><br /><pre name="code" class="java">
//原型方式定义类,缺点:类的属性值如果是引用类型的(非Number和String类型)，则多个实例对象共享
function User(){
}
User.prototype.username = "zhangsan";
User.prototype.say = function(){
	alert("username: " + this.username );
}

var user = new User();
user.username = "lisi";
user.say();//username:lisi

var user1 = new User();
user1.say();//username:zhangsan
</pre><br /><br />类的属性值如果是引用类型的(非Number和String类型)，则多个实例对象共享：<br /><pre name="code" class="java">
//类的属性值如果是引用类型的(非Number和String类型)，则多个实例对象共享,如下
function User(){
}
User.prototype.username = new Array();
User.prototype.say = function(){
	alert("username: " + this.username );
}

var user = new User();
user.username.push("zhangsan") ;
user.say();//username:zhangsan

var user1 = new User();
user1.say();//username:zhangsan,因为user1属性也会受到user的影响，user1和user指向同一引用，即共享同一属性
</pre><br /><br />3.<span style="color: red">构造和原型结合方式创建类:优点:类的方法只会产生一个，不会产生大量方法,同时属性还不共享;缺点:属性和方法分开定义不是太好。</span><br /><br /><pre name="code" class="java">
//构造和原型结合方式创建类:优点:类的方法只会产生一个，不会产生大量方法,同时属性还不共享;缺点:属性和方法分开定义不是太好。
function User(){
	this.username = "zhangsan";
}
User.prototype.say = function(){
	alert("username: " + this.username );
}
var user = new User();
alert(user.username);
</pre><br /><br />4.<span style="color: red">动态的原型方式:优点:类的方法只会产生一个，不会产生大量方法,同时属性还不共享,同时属性和方法不是分开定义的</span><br /><br /><pre name="code" class="java">
////动态的原型方式:优点:类的方法只会产生一个，不会产生大量方法,同时属性还不共享,同时属性和方法不是分开定义的

function User(){
	this.username = "zhangsan";
	
	if(typeof User.flag == "undefined"){
		alert("execute...");
		User.prototype.say = function(){
			alert("username: " + this.username );
		}
		
		User.flag = true;
	}
}

var user1 = new User();//execute...
var user2 = new User();//不会打印出execute...，则说明方法只创建了一次，即方法只会产生一个
user1.say();//username
</pre><br /><br />总结:<br /><span style="color: red">构造方式定义类:缺点:类里的方法，每个实例对象都会产生一个，导致产生大量方法;优点:所有实例对象都单独拥有一份类里的属性，即属性不共享<br />原型方法定义类:缺点:所有实例对象都共同拥有一份类里的属性，即属性共享。优点:类的方法只会产生一个，不会产生大量方法<br />构造和原型结合方式创建类:优点:类的方法只会产生一个，不会产生大量方法,同时属性还不共享;缺点:属性和方法分开定义不是太好。<br />动态的原型方式:优点:类的方法只会产生一个，不会产生大量方法,同时属性还不共享,同时属性和方法不是分开定义的</span>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/193663#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 16 May 2008 14:37:03 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/193663</link>
        <guid>http://ttitfly.javaeye.com/blog/193663</guid>
      </item>
      <item>
        <title>javascript特性二(备忘)</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/193279" style="color:red;">http://ttitfly.javaeye.com/blog/193279</a>&nbsp;
          发表时间: 2008年05月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1. js里的数组<br /><br /><pre name="code" class="java">
//数组定义，第一种定义方式
var arr = new Array();
//数组赋值
arr.push(1);
arr.push(2);
arr[2] = 3;
alert(arr.length);//3

//第二种定义方式
var arr1 = [];
arr1.push(1);
arr1.push(2);
arr1[2] = 3;
alert(arr1.length);//3

//第三种定义方式
var arr2 = [1,2,3,4,5];
arr2[5] = 6;
alert(arr2.length);//6


//数组排序sort()方法
var arr3 = [1,4,2];
arr3.sort();
alert(arr3);//1,2,4

//
var arr3 = [1,4,23];
arr3.sort();
alert(arr3);//1,23,4  顺序不对的原因是因为js里排序会先转换为字符串，再根据ascii码进行排序。所以23排在了4的前面

// 
function compare(num1,num2)
{
	//因为排序前都转化成了字符串，所以要给parse成int,可以用函数parseInt()函数
     var temp1 = parseInt(num1);
     var temp2 = parseInt(num2);
     if(temp1 &lt; temp2)
     {
     	return -1;
     }else if(temp1 == temp2){
     	return 0;
     }else{
     	return 1;
     }
}

var arr4 = [1,4,23];
arr4.sort(compare);//1,4,23 因为通过自定义函数compare进行了转换
alert(arr4);
</pre><br /><br />2.<br /><pre name="code" class="java">
User = function (){
}
User.prototype.name = "zhangsan";
//User.name = "zhangsan";//错误定义
		
var u = new User();
u.password = "123456";
//u.prototype.password = "987654";//错误定义
alert(u.name);
alert(u.password);
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/193279#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 15 May 2008 14:40:02 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/193279</link>
        <guid>http://ttitfly.javaeye.com/blog/193279</guid>
      </item>
      <item>
        <title>Extjs2.0---事件处理</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/193088" style="color:red;">http://ttitfly.javaeye.com/blog/193088</a>&nbsp;
          发表时间: 2008年05月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="color: red">Extjs里的事件处理,只有继承了Ext.util.Observable类才具有事件功能</span><br /><br />1.先看一个简单点的例子<br /><pre name="code" class="java">//Extjs里的事件处理,只有继承了Ext.util.Observable类才具有事件功能

Employee = function(){
	this.addEvents("test");//注册事件,该事件名字为：test
}

Ext.extend(Employee,Ext.util.Observable);

todo = function(){
	alert("event was fired");
}

var em = new Employee();
em.on("test",todo);//将方法绑定到事件test上
em.fireEvent("test");//触发事件test</pre><br /><br /><br />2.<br />页面代码：<br /><pre name="code" class="java">&lt;input type="button" name="button1" id="button1" value="button1" /></pre><br /><br />js代码：<br /><pre name="code" class="java">
todo = function(){
	alert("event was fired");
}

//window.onload = function(){}等价于Ext.onReady(function(){});页面加载完后就执行该函数
Ext.onReady(function() {
		//返回的button1是Observable的子类，所以具有事件处理功能
		var button1 = Ext.get("button1");//返回的Element对象,不等价于document.getElementById("button1")
//		var button1 = Ext.getDom("button1");//返回的HTMLElement对象,等价于document.getElementById("button1");
		
		alert(button1.id);//button1
		
//		button1.addListener("click",todo);//addListener与on是一样
//		button1.addListener("mouseover",todo);
		
		
		//通过EventManager来实现
		Ext.EventManager.addListener(button1,"click",todo);
		Ext.EventManager.addListener(button1,"mouseover",todo);
		
	}
)
</pre><br /><br /><br />3.<br /><pre name="code" class="java">
todo = function(){
	alert(this.id);//此处的this由addListener的第3个参数决定
}


Ext.onReady(function() {
		//返回的button1是Observable的子类，所以具有事件处理功能
		var button1 = Ext.get("button1");
		
		//先打印出button1,再打印出ext-gen1,刚好与addListener添加的顺序相反
		button1.addListener("click",todo,this);//todo函数打印出:ext-gen1
		button1.addListener("click",todo,button1);//todo函数打印出:button1
	}
)
</pre><br /><br />4.<br /><pre name="code" class="java">
todo = function(){
	alert(this.id);//此处的this由addListener的第3个参数决定
}
Ext.onReady(function(){
		var button1 = Ext.get("button1");
		//addListener的第4个参数是个配置选项，所以需要用{},有4个配置选项，delay(触发事件多久后执行指定的函数),scope(如果第3个参数设置了,此处可以省),single(事件触发一次后，就被移走，以后再触发该事件无效),buffer（缓存区，也就是多长时间内触发该事件大于1次都认为是1次）
		//delay和buffer同时使用时有错误，具体原因还不知道是为什么?
		button1.addListener("click",todo,button1,{delay:3000,single:false});//因为button1也属于Observable类的子类，所以查看文档时可以直接查看Observable中的addListener方法
	}
)
</pre><br /><br />5.<br /><pre name="code" class="java">
//window.onload = function(){}等价于Ext.onReady(function(){});  页面加载完后就执行该函数
Ext.onReady(function(){
		alert("ok1");
		function AA(){
			alert("ok2");
		}
	}
)
//只会打印出ok1,ok2不会被打印出来。因为页面加载完后会去执行函数function()，但是function()函数里的函数(或叫类)AA则不会去执行的。
</pre><br /><br /><pre name="code" class="java">
Ext.onReady(function(){
		alert("ok1");
		function AA(){
			alert("ok2");
		}
		new AA();
	}
)

//这样ok1和ok2都会被打印出来，因为new AA()去调用了
</pre><br /><br /><br />6.等价写法：<br /><pre name="code" class="java">
todo = function(){
	alert(this.id);//此处的this由addListener的第3个参数决定
}
Ext.onReady(function(){
		var button1 = Ext.get("button1");
		
		//第一种写法
//		button1.addListener("click",todo,button1);
//		button1.addListener("mouseover",todo,button1);
		
		//第二种写法
//		button1.on({click:todo,mouseover:todo,scope:button1});

		//第三种写法
		button1.on(
			{
				click:{scope:button1,delay:3000,fn:todo},
				mouseover:{scope:button1,delay:1000,fn:todo}
			}
		);
		
		
		
	}
)
</pre><br /><br />7.<pre name="code" class="java">
Ext.onReady(
	function(){
		alert("ok1");//ok1
		AA = function(){
			alert("ok2");//ok2		
		};
		//同时定义多个属性和方法
		AA.prototype = {
			aa:1,
			bb:2,
			a:function(){
				alert("aa");//因为没有调用，所以不会打印出来
			},
			b:function(){
				alert("bb");//因为没有调用，所以不会打印出来
			}
		}
		new AA();
		
	}
)
</pre><br /><br />8.事件处理EventObject<br /><pre name="code" class="java">

Ext.onReady(function(){
	var win = new Ext.Window({
		title:'hello',
		html:'world',
		width:400,
		height:300
	});
	win.show();
	//查看Extjs的文档：Ext.Window中的Public Events部分查看到:move : ( Ext.Component this, Number x, Number y ) ,默认3个参数，所以才有得下面函数的c,x,y
	win.on("move",moving);
})

moving = function(c,x,y){
	alert(c.id);
	alert(x);
	alert(y);
}
</pre><br /><br /><span style="color: red">另一个例子:</span><br /><br /><br />页面代码：<br /><pre name="code" class="java">
&lt;a href="http://www.baidu.com" id="baidu">百度&lt;/a>
</pre><br />js代码：<br /><pre name="code" class="java">
//事件处理EventObject

todo = function(e){//EventObject,在这里可以理解为：EventObject是HTMLElement对象的click事件的默认参数
	alert(this.id);//baidu
	var htmlEl = e.getTarget();//返回值是HTMLElement,得到事件触发的目标，这里也就是指&lt;A>连接标签
	alert(htmlEl.innerText);//打印出:"百度"  （HTMLElement有innerHTML和innnerText方法。 Element没有）
	e.stopEvent();//阻止事件继续发生，也就是&lt;A>标签不会跳转到baidu页面了
	
	//获得实际传递参数值
	alert(arguments.length);//3
	alert(arguments[2].aa);//test
	alert(arguments[2]["aa"]);//test
	
}
Ext.onReady(
	function(){
		var  baidu = Ext.get("baidu");
		baidu.on("click",todo,baidu,{aa:'test'});
	}
)
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/193088#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 14 May 2008 20:38:50 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/193088</link>
        <guid>http://ttitfly.javaeye.com/blog/193088</guid>
      </item>
      <item>
        <title>Extjs2.0---继承</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/193046" style="color:red;">http://ttitfly.javaeye.com/blog/193046</a>&nbsp;
          发表时间: 2008年05月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Extjs2.0里通过Ext.extend方法实现继承<br /><br /><pre name="code" class="java">
//父类定义
BaseClass = function(){
	//begin
	this.cry = function(){//this.不能丢
		alert("crying....");
	}
	//end
}

BaseClass.prototype.name="";
BaseClass.prototype.say = function(){
	alert("say parent");
}
BaseClass.prototype.talk = function(){
	alert("talk parent");
}
//子类定义
SubClass = function(){
	SubClass.superclass.constructor.call(this);//调用父类构造函数,也就是执行BaseClass里的begin--->end中间的代码。如果这行代码注释掉，则begin---->end中间的代码不会初始化，但是父类用prototype构造的属性和方法任然会初始化
	//js里子类实例化时是不会去自己调用父类的构造函数的
	this.walk = function(){//this.必须要加上，否则SubClass的实例对象没有办法引用到该walk方法
		alert("i'm warking");
	}
}
//继承,第3个参数{}，覆盖或者扩展父类方法，该参数也可以不要
Ext.extend(SubClass,BaseClass,{
	say:function(){
		alert("overide say");
	},
	jump:function(){
		alert("jumping");
	}
	
});
var sb = new SubClass();
sb.say();//overide say
sb.walk();//i'm warking
sb.jump();//jumping
sb.talk();//talk parent
sb.cry();//crying....
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/193046#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 14 May 2008 17:47:53 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/193046</link>
        <guid>http://ttitfly.javaeye.com/blog/193046</guid>
      </item>
      <item>
        <title>javascript特性一(备忘)</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/192643" style="color:red;">http://ttitfly.javaeye.com/blog/192643</a>&nbsp;
          发表时间: 2008年05月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1.js不支持重载，因为js里的函数都是一个对象，js里有个隐含对象Function,所有的js函数都是一个Function类型的对象。比如：<br /><pre name="code" class="java">
function add(number)
{
   alert("hello");
}
</pre><br />等价于<br /><pre name="code" class="java">
var add = new Function("number","alert('hello');");
</pre><br /><br />由于js里每一个函数里都隐含一个对象叫<span style="color: red">arguments</span>,该arguments是一个数组，通过arguments可以获得到实际传递参数的个数(arguments.length)及实际传递参数的值(arguments[0],arguments[1]...)<br />所以可以通过arguments对象来<span style="color: red">模拟重载</span>，如下：<br /><pre name="code" class="java">
function add()
{
	if(arguments.length == 1)
	{
	      alert(arguments[0] + 10);
	}
	if(arguments.length == 2)
	{
               alert(arguments[0] + arguments[1] + 10);
	}
			
	}
}
add(5);
add(5,1);
</pre><br /><br />2.每个函数的名字都有一个属性叫length,“<span style="color: red">属性名.length </span>”获得该函数能接受参数的个数。<br />如：<br /><pre name="code" class="java">
function a1()
{
}
function a2(number)
{
}
		
alert(a1.length);//0
alert(a2.length);//1
</pre><br /><br />3.JavaScript中有五种原始基本数据类型：Undefined,Null,Boolean,Number,String<br /><br />Undefined数据类型的值只有一个：undefined<br /><br />Null数据类型的值只有一个：null<br /><br />Boolean数据类型的值只有两个：true，false<br /><br />Number数据类型的值有很多：数字即可<br /><br />String a = "hello";和String a = new String("hello");是不一样的。有点类似java里的对象。String a = "hello"只是在栈内存里生成，String a = new String("hello");则堆内存里生成"hello"值，栈内容里变量a指向堆内存。<br /><br />4.<span style="color: red">typeof</span>一元操作符，它的返回值有五个：undefined,boolean,number,string,object<br /><br />5.<span style="color: red">alert(函数名)</span>  是把该函数的函数名及函数体都给打印出来。方便调试 javascript.<br /><br />如：<br /><pre name="code" class="java">
function test()
{
    var a = "aa";
}
alert(test());//undefined
alert(test);//function test(){ var a = "aa";}
<span style="color: red">对于函数来说，如果其不返回值，那么其返回值就为undefined</span>
</pre><br /><br />6.<br /><pre name="code" class="java">
var s ;//变量s1未定义
alert(typeof s);//undefined
alert(typeof s1);//undefined
alert(s);//undefined
alert(s1);//报错
</pre><br /><br />7.<span style="color: red">null与undefined的关系：undefined实际上从null派生而来</span><br /><br /><pre name="code" class="java">alert(undefined == null);//true</pre><br /><br />8.<span style="color: red">对于函数定义中的变量来说，加var表示局部变量，不加var表示全局变量</span><br /><br />9.javascript里 ，Object类是所有类的父类，类的强制转换有三种：Boolean(value),Number(value),String(value)<br /><br />Object 对象有个方法叫：propertyIsEnumerable("属性名")<br />所以所有子类都有该方法，如果 "对象.propertyIsEnumerable("属性名")"为true，则表示该属性可以通过for(var temp  in  对象的实例名)来进行遍历出来。<br />如：<br /><br /><pre name="code" class="java">
var o = new Object();
alert(o.propertyIsEnumerable("prototype"));//false,说明prototype是不可以通过for(var temp in )进行遍历出来的

</pre><br /><span style="color: red">Object对象里的所有属性propertyIsEnumerable都为 false</span><br /><pre name="code" class="java">
var o = new Object();
for(var temp  in  o)
{
	alert(temp);	//一个都不会打印出来	
}
</pre><br /><br />可以把o改为内置window对象，就可以打印出来很多了。<br /><br /><br />10.定义对象后增加属性或删除属性<br /><pre name="code" class="java">
var o = new Object();
o.name="test";
alert(o.name);//test
delete o.name;
alert(o.name);//undefined 
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/192643#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 13 May 2008 16:48:53 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/192643</link>
        <guid>http://ttitfly.javaeye.com/blog/192643</guid>
      </item>
      <item>
        <title>自定义标签调用资源文件</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/192399" style="color:red;">http://ttitfly.javaeye.com/blog/192399</a>&nbsp;
          发表时间: 2008年05月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="color: red">自定义标签处理类一般都继承TagSupport或BodyTagSupport</span><br />1.先看一个普通的最简单的自定义标签程序。<br /><span style="color: red">A:创建标签的处理类</span><br /><pre name="code" class="java">
package com.test.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;

@SuppressWarnings("serial")
public class HelloTag extends TagSupport {

	//doStartTag返回的都是BODY相关,doEndTag返回的都是PAGE相关
	@Override
	public int doStartTag() throws JspException {
		try {
			//通过PageContext对象的getOut()方法获得JspWriter对象输出内容
			this.pageContext.getOut().write("hello");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return Tag.EVAL_BODY_INCLUDE;
	}

}

</pre><br /><br /><span style="color: red">B:创建标签库描述文件</span><br /><pre name="code" class="xml">
&lt;?xml version="1.0" encoding="ISO-8859-1" ?>
&lt;!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
&lt;taglib>
	&lt;tlib-version>1.0&lt;/tlib-version>
	&lt;jsp-version>1.2&lt;/jsp-version>
	&lt;short-name>hello taglib test&lt;/short-name>
	&lt;uri>/hellotag&lt;/uri>
	
	&lt;tag>
	     &lt;!--Tag名字 -->
		&lt;name>hello&lt;/name>
		&lt;!-- 该Tag对应的处理类 -->
		&lt;tag-class>com.test.tag.HelloTag&lt;/tag-class>
		&lt;!-- 该 Tag的body内容为空  -->
		&lt;body-content>empty&lt;/body-content>
	&lt;/tag>
&lt;/taglib>
</pre><br /><br /><span style="color: red">C.在JSP文件中引入标签库，然后插入标签</span><br />jsp里有两种引用方式：<br />&lt;%@ taglib uri="/WEB-INF/hello.tld" prefix="aa" %>或者<br />&lt;%@ taglib uri="/hellotag" prefix="aa" %><br /><pre name="code" class="java">
&lt;%@ page language="java"  pageEncoding="UTF-8"%>
&lt;%@ taglib uri="/hellotag" prefix="aa" %>


&lt;html>
  &lt;body>
    &lt;aa:hello/>
  &lt;/body>
&lt;/html>
</pre><br /><br />输出结果为：hello<br /><br />2.自定义标签库引用资源文件<br /><span style="color: red">A:首先在应用程序根目录下建立一个资源文件比如叫:helloworld.properties</span>,内容为：<br /><pre name="code" class="java">
hello.title=tagTitle
hello.content=tagContent
</pre><br /><span style="color: red">B:建立一个Servlet，在启动时加载该Servlet,在init方法里读取</span>helloworld.properties文件内容。<br /><pre name="code" class="java">
package com.test.tag;

import java.io.InputStream;
import java.util.Properties;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

@SuppressWarnings("serial")
public class TagServlet extends HttpServlet {
	public void init() throws ServletException {
		System.out.println("init not param");
	}
    //init(ServletConfig config)存在，则init()方法则不会执行。如果init(ServletConfig config)不存在，则init()方法会执行
	@Override
	public void init(ServletConfig config) throws ServletException {
		try{
			System.out.println("init have param");
			Properties p = new Properties();
			//通过ServletContext读取资源文件
			ServletContext context = config.getServletContext();
			InputStream in = context.getResourceAsStream("/helloworld.properties");
			
			p.load(in);
			in.close();
			//设置属性key-value到context中
			context.setAttribute("prop", p);
		}catch(Exception e){
			e.printStackTrace();
		}
		
	}
	

}

</pre><br /><span style="color: red">C:创建标签库的处理类：</span><br /><pre name="code" class="java">
package com.test.tag;

import java.util.Properties;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;

@SuppressWarnings("serial")
public class HelloTagByResource extends TagSupport {
	private String title;
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	//在doStartTag和doEndTag里写都可以。不要误认为："遇到标签的起始标记时，还没有解析到其属性title,所以放在doStartTag里写会报错"
	@SuppressWarnings("static-access")
	@Override
	public int doStartTag() throws JspException {
		try{
//			Properties p = (Properties)this.pageContext.getAttribute("ps",this.pageContext.APPLICATION_SCOPE);
			Properties p = (Properties)this.pageContext.getAttribute("ps",PageContext.APPLICATION_SCOPE);
			String str = p.getProperty(title);
			this.pageContext.getOut().print(str);
		}catch(Exception e){
			e.printStackTrace();
		}
		return Tag.EVAL_BODY_INCLUDE;
	}
//	@Override
//	public int doEndTag() throws JspException {
//		try{
////			Properties p = (Properties)this.pageContext.getAttribute("ps",this.pageContext.APPLICATION_SCOPE);
//			Properties p = (Properties)this.pageContext.getAttribute("ps",PageContext.APPLICATION_SCOPE);
//			String str = p.getProperty(title);
//			this.pageContext.getOut().print(str);
//		}catch(Exception e){
//			e.printStackTrace();
//		}
//		return Tag.EVAL_PAGE;
//	}

	
	
}

</pre><br /><span style="color: red">D:创建自定义标签的描述文件</span><br /><pre name="code" class="xml">
&lt;?xml version="1.0" encoding="ISO-8859-1" ?>
&lt;!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
&lt;taglib>
	&lt;tlib-version>1.0&lt;/tlib-version>
	&lt;jsp-version>1.2&lt;/jsp-version>
	&lt;short-name>hello taglib test&lt;/short-name>
	&lt;uri>/hellotag&lt;/uri>
	
	&lt;tag>
	     &lt;!--Tag名字 -->
		&lt;name>hello&lt;/name>
		&lt;!-- 该Tag对应的处理类 -->
		&lt;tag-class>com.test.tag.HelloTag&lt;/tag-class>
		&lt;!-- 该 Tag的body内容为空  -->
		&lt;body-content>empty&lt;/body-content>
	&lt;/tag>
	
	&lt;tag>
	     &lt;!--Tag名字 -->
		&lt;name>message&lt;/name>
		&lt;!-- 该Tag对应的处理类 -->
		&lt;tag-class>com.test.tag.HelloTagByResource&lt;/tag-class>
		&lt;!-- 该 Tag的body内容为空  -->
		&lt;body-content>empty&lt;/body-content>
		&lt;!-- 属性定义 -->
		&lt;attribute>
			&lt;name>title&lt;/name>
			&lt;required>true&lt;/required>
		&lt;/attribute>
	&lt;/tag>
&lt;/taglib>
</pre><br /><span style="color: red">E:jsp里引用</span><pre name="code" class="java">
&lt;%@ page language="java"  pageEncoding="UTF-8"%>
&lt;%@ taglib uri="/hellotag" prefix="aa" %>


&lt;html>
  &lt;body>
    &lt;aa:message title="hello.title"/>&lt;br/>
    &lt;aa:message title="hello.content"/>
  &lt;/body>
&lt;/html>

</pre><br /><br />输出内容为：<br />tagTitle<br />tagContent
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/192399#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 12 May 2008 22:28:28 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/192399</link>
        <guid>http://ttitfly.javaeye.com/blog/192399</guid>
      </item>
      <item>
        <title>Extjs2.0常用备忘</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/190645" style="color:red;">http://ttitfly.javaeye.com/blog/190645</a>&nbsp;
          发表时间: 2008年05月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          继承关系:Component--->BoxComponent---->Container----->Panel---各种具体Panel<br /><br />1.MessageBox<br /><pre name="code" class="java">
Ext.MessageBox.alert("ok");


   Ext.Msg.show({
	   title:'Save Changes?',
	   msg: 'You are closing a tab that has unsaved changes. Would you like to save your changes?',
	   //值只能为MessageBox里Public Properties中的Button config
	   buttons: Ext.Msg.YESNOCANCEL,
	   //fn为回调
//	   fn: processResult,
	   animEl: 'elId',
	   //值只能为：值只能为MessageBox里Public Properties中的The CSS class
	   icon: Ext.MessageBox.WARNING
	});
</pre><br /><br />2.布局处理Viewport<br /><pre name="code" class="java">
  	  var viewport = new Ext.Viewport({
  	     id:'desk',
  	     layout:'border',
  	     items:[{region:'north',height:50},{region:'west',width:200},{region:'center'}]
  	    }	
  	  		
  	  );
</pre><br /><br />3.Panel<br /><pre name="code" class="java">
  	var panel = new Ext.Panel({
//  	        renderTo:'hello'可以替换掉panel.render("hello");
  	    id:'hello',
  	    title:'panlehell',
  	    width:200,
  	    height:200
  		
  	});
  	panel.render("hello");

</pre><br /><br />4.TabPanel<br /><pre name="code" class="java">
 var tabPanel = new Ext.TabPanel({
    	    renderTo:'hello',
    	    activeTab: 0,
    		width:200,
    		height:200,
    		items:[
    		{title:'hello1',html:'hello1 content!'},//默认是Panel
    		new Ext.Panel({title:'hello2',html:'hello2 content'}),
    		new Ext.tree.TreePanel(  {title:'树面板',loader:new Ext.tree.TreeLoader(),root:new Ext.tree.AsyncTreeNode( {text:'根节点',children:[ { leaf:true,text:'叶子1' }, { leaf:true,text:'叶子2' } ]  } )  }  ),
    		  {xtype:'treepanel',title:'树面板',loader:new Ext.tree.TreeLoader(),root:new Ext.tree.AsyncTreeNode( {text:'根节点',children:[ { leaf:true,text:'叶子1' }, { leaf:true,text:'叶子2' } ]  } )  }  
    		]
    	}
    );
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/190645#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 07 May 2008 16:44:26 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/190645</link>
        <guid>http://ttitfly.javaeye.com/blog/190645</guid>
      </item>
      <item>
        <title>Jetty简单介绍</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/190437" style="color:red;">http://ttitfly.javaeye.com/blog/190437</a>&nbsp;
          发表时间: 2008年05月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1.jetty是一个类似tomcat的服务器，可以通过程序来控制它启动和停止。<br /> 官网:http://www.mortbay.org<br />2.myeclipse里集成了jetty的插件，可以进行配置并启动jetty服务器。<br />3.通过java代码实现jetty服务器的启动。<br /><br /><pre name="code" class="java">
package com.jetty;

import org.mortbay.http.SocketListener;
import org.mortbay.jetty.Server;

public class JettyTest {


	public static void main(String[] args) throws Exception {
		//定义一个Server对象
		Server server = new Server();
		
		SocketListener socket = new SocketListener() ;
		socket.setPort(9999);
		//设置服务端口号
		server.addListener(socket);
		//设置Context
		server.addWebApplication("/test1", "D:\\java\\jetty-5.1.12\\webapps\\template");
		//启动
		server.start();
		
	}

}

</pre><br />通过地址可以访问 ： http://localhost:9999/test1/
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/190437#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 07 May 2008 02:22:31 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/190437</link>
        <guid>http://ttitfly.javaeye.com/blog/190437</guid>
      </item>
      <item>
        <title>用Cactus做容器内单元测试</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/190414" style="color:red;">http://ttitfly.javaeye.com/blog/190414</a>&nbsp;
          发表时间: 2008年05月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1.cactus 属于jakarta下面的一个子项目，具体下载地址：<a href="http://jakarta.apache.org/cactus/index.html" target="_blank">http://jakarta.apache.org/cactus/index.html</a><br /><br />2. 在web.xml里配置<br /><pre name="code" class="java">
 &lt;servlet>
    &lt;servlet-name>ServletTestRunner&lt;/servlet-name>
    &lt;servlet-class>org.apache.cactus.server.runner.ServletTestRunner&lt;/servlet-class>
    &lt;/servlet>
  &lt;servlet-mapping>
    &lt;servlet-name>ServletTestRunner&lt;/servlet-name>
    &lt;url-pattern>/ServletTestRunner&lt;/url-pattern>
  &lt;/servlet-mapping>
  
  
  &lt;servlet>
    &lt;servlet-name>ServletTestRedirector&lt;/servlet-name>
    &lt;servlet-class>org.apache.cactus.server.ServletTestRedirector&lt;/servlet-class>
  &lt;/servlet>
  &lt;servlet-mapping>
    &lt;servlet-name>ServletTestRedirector&lt;/servlet-name>
    &lt;!--这个url-pattern的值必须为/ServletRedirector,不能换成其它-->
    &lt;url-pattern>/ServletRedirector&lt;/url-pattern>
  &lt;/servlet-mapping>
</pre><br /><br />3.写个Servlet类<br /><pre name="code" class="java">
public class FirstServlet extends HttpServlet {
       public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		if(isLogin(request)){
			System.out.println("success");
		}else{
			System.out.println("fail");
			request.getSession().setAttribute("user", "users");
		}
		
	}

         public boolean isLogin(HttpServletRequest request){
		if(null == request.getSession().getAttribute("user")){
			return false;
		}else{
			return true;
		}
	}

}
</pre><br /><br />对其里面的方法isLogin进行测试<br /><br />4.测试类：FirstServletTest<br /><pre name="code" class="java">
import junit.framework.Assert;

import org.apache.cactus.ServletTestCase;

public class FirstServletTest extends ServletTestCase {

	public void testIsLogin(){
		FirstServlet test = new FirstServlet();
		boolean result = test.isLogin(request);
		Assert.assertEquals(false, result);
	}

}


</pre><br /><br /><span style="color: red">A:用浏览器的方式进行测试</span><br />TestAll（不需要继承任何类）代码<br /><pre name="code" class="java">
import junit.framework.Test;
import junit.framework.TestSuite;

public class TestAll {
	
	public static Test suite(){
		TestSuite suite = new TestSuite("test all");
		suite.addTestSuite(FirstServletTest.class);
		return suite;
	}

}

</pre><br /><br />启动服务,地址栏输入:http://localhost:8080/cactusTest/ServletTestRunner?suite=com.test.TestAll<br />则会以xml的形式返回测试结果，如果想以html的形式更直观的观察测试结果则需要下载cactus-report.xsl,并将该文件放在当前应用的根目录下。然后地址栏输入：<br />http://localhost:8080/cactusTest/ServletTestRunner?suite=com.test.TestAll&xsl=cactus-report.xsl，客户端会把服务器返回的xml结果根据该xsl转换成直观的html形式，<span style="color: red">在客户端进行转换</span>。如果想让服务器端直接返回的是html的形式，而不是xml的形式，那么需要在web.xml里加个&lt;init-param>参数，如下：<br /><pre name="code" class="java">
&lt;servlet>
    &lt;servlet-name>ServletTestRunner&lt;/servlet-name>
    &lt;servlet-class>org.apache.cactus.server.runner.ServletTestRunner&lt;/servlet-class>
    &lt;init-param>
    	&lt;param-name>xsl-stylesheet&lt;/param-name>
    	&lt;param-value>cactus-report.xsl&lt;/param-value>
    &lt;/init-param>
    
  &lt;/servlet>
</pre><br />这样的话，只需要输入:http://localhost:8080/cactusTest/ServletTestRunner?suite=com.test.TestAll&transform=fds,<span style="color: red">transform的值可以随意</span>，那么服务器端会自己将xml形式的测试结果直接转换成html，然后返回给客户端，就不需要客户端自己做转换了。<br /><br /><span style="color: red">B:像普通的java application应用的TestCase一样直接在IDE里运行测试</span><br />FirstServletTest2测试类<br /><pre name="code" class="java">
package com.test;

import junit.framework.Assert;

import org.apache.cactus.ServletTestCase;
import org.apache.cactus.WebRequest;
import org.apache.cactus.WebResponse;

public class FirstServletTest2 extends ServletTestCase {

	/**
	 *每个测试方法前都会去执行
	 */
	public void begin(WebRequest request){
		System.setProperty("cactus.contextURL", "http://localhost:8080/cactusTest");
		System.out.println("begin");
	}
	/**
	 *只是在isLogin测试方法前才会去执行
	 */
	public void beginIsLogin(WebRequest request){
		System.out.println("begin isLogin");
	}
	
	public void setUp(){
		System.out.println("setUp");
	}
	public void testIsLogin(){
		FirstServlet test = new FirstServlet();
		boolean result = test.isLogin(request);
		Assert.assertEquals(false, result);
	}
	public void tearDown(){
		System.out.println("tearDown");
	}
	/**
	 *每个测试方法后都会去执行
	 */
	public void end(WebResponse response){
		System.out.println("end");
	}
	
	/**
	 *只是在isLogin测试方法后才会去执行
	 */
	public void endIsLogin(WebResponse response){
		System.out.println("end isLogin");
	}

}

</pre><br />1 Cactus的执行流程分为两部分：客户端（Client）与服务器端（Server）<br /><br />2 客户端部分：首先构造出准备向服务器端发送的请求参数。<br /><br />客户端通过begin及beginXXX方法构造好请求参数后，与服务器端建立一个HTTP连接，然后向服务器端发送请求<br /><br />3 服务器端：最重要的类是ServletTestRedirector类，它是一个Servlet，它收到客户端发送来的请求，然后通过反射生成测试类的实例，接下来调用其setUp,textXXX,tearDown方法，执行完毕后，向客户端发送响应（Response）<br /><br />4. 客户端：收到响应后，执行endXXX，end方法，完成测试流程。<br /><br />5. 在客户端执行的方法：begin,beginXXX,endXXX,end.<br /><br />6. 在服务器端执行的方法：setUp,testXXX,tearDown.<br /><br /><span style="color: red">也就是说测试类(FirstServletTest2 )被实例化了2次,在客户端实例化了一次，在服务器端也实例化了一次(ServletTestRedirector通过反射生成测试类的实例)</span><br />实际上<span style="color: red">客户端和服务器端进行的是2次连接</span>，第一次是进行请求运行要测试的方法，第二次是将测试结果返回给客户端，即2次连接。<span style="color: red">只有服务器端的session是有值的，客户端的session是没有值的。</span>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/190414#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 06 May 2008 23:16:24 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/190414</link>
        <guid>http://ttitfly.javaeye.com/blog/190414</guid>
      </item>
      <item>
        <title>Failed to install Tomcat6 service(Tomcat6安装失败解决方法)</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/190282" style="color:red;">http://ttitfly.javaeye.com/blog/190282</a>&nbsp;
          发表时间: 2008年05月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          转载 :http://www.handandaily.com/blog/2007/11/16/Java/498.html<br />Failed to install Tomcat6 service <br /><br />check your settings and permissions<br /><br /> Ignore and continue anyway<br /><br /> <br /><br />WINDOWS 系统因为电脑之前安装过tomcat 的5.028、5.514等版本。 删除tomcat 5时,<br />只是简单的删除安装文件夹，“服务”中还有tomcat5服务，<br />安装tomcat6时就会报错Failed to install Tomcat6 service,并且程序不能运行。<br />找到报错的日志,显示下列的错误$tomcat_install/logs/jakarta_service_date.log,显示：<br />“<br />[2007-05-31 18:20:33] [420  service.c] [error] 名称已用作服务名或服务显示名。<br />[2007-05-31 18:20:33] [606  prunsrv.c] [error] Failed installing Tomcat6 service<br />”<br />从“$tomcat_install\Tomcat 5.0\bin”目录中找到service.bat，在命令行中执行：service remove tomcat5<br />即可把“服务”中还有tomcat5服务删除，然后就可以正常安装。
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/190282#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 06 May 2008 16:24:50 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/190282</link>
        <guid>http://ttitfly.javaeye.com/blog/190282</guid>
      </item>
      <item>
        <title>tomcat5.5日志配置</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/190277" style="color:red;">http://ttitfly.javaeye.com/blog/190277</a>&nbsp;
          发表时间: 2008年05月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          tomcat5.5日志配置：<br />从Tomcat5.5后，默认设置下并不会记录应用日志，但是如果启动tomcat报类似严重: Error listenerStart这样的错误很难知道具体是什么原因。所以有时需要让它产生应用日志。具体办法如下:<br />新建log4j.properties:<br /><pre name="code" class="java">
log4j.rootLogger=info,Console,R 

log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
#log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
log4j.appender.Console.layout.ConversionPattern=%d{yy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n 

log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=${catalina.home}/logs/tomcat.log 
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy.MM.dd HH:mm:ss} %5p %c{1}(%L):? %m%n 

log4j.logger.org.apache=info, R
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=DEBUG, R 
log4j.logger.org.apache.catalina.core=info, R
log4j.logger.org.apache.catalina.session=info, R 


</pre><br />然后把新建的log4j.properties放在%CATALINA_HOME%/common/classes目录里面，注意，如果%CATALINA_HOME%/common/lib目录下没有log4j.jar和commons-logging.jar,一定要添加进去。 <br /><br />      还有一点要提醒的是最后4行是Tomcat日志会记录的信息设置，在开发机上这么设置就可以，在运行服务器上最好不要设置成DEBUG,否则服务器的空间会很快满了
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/190277#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 06 May 2008 16:13:47 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/190277</link>
        <guid>http://ttitfly.javaeye.com/blog/190277</guid>
      </item>
      <item>
        <title>装饰(Decorator)模式</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/186731" style="color:red;">http://ttitfly.javaeye.com/blog/186731</a>&nbsp;
          发表时间: 2008年04月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          装饰(Decorator)模式:也叫包装模式，Adaptor模式也可以叫包装模式，不过有本质的区别，Adaptor模式没有使原有功能增强<br />Decorator模式使原有功能增强，而且不是通过子类来实现功能增强的。<br /><br />装饰模式主要特色：<br /><br />1.用来扩展特定<span style="color: red">对象</span>的功能，<span style="color: red">不是扩充某个类的功能</span>。<br />2.不需要子类，防止由于子类而导致的复杂和混乱<br />3.对于一个给定的对象，同事可能有不同的装饰对象，客户端可以通过它的需要选择合适的装饰对象<br /><br />java.io包下类大量使用到装饰模式。<br /><br />装饰模式主要角色<br />1.抽象构件角色:给出一个抽象接口，以规范准备接受附加责任的对象<br />2.具体构件角色:定义一个将要接收附加责任的类<br />3.装饰角色：<span style="color: red">持有一个构件对象的实例</span>，并定义一个与抽象构件接口一致的接口<br />4.具体装饰角色:负责给构件对象"贴上"附加的责任<br /><br /><br /><pre name="code" class="java">
package com.pattern.decorator;
/**
 * 抽象构件角色
 */
public interface Component {

	public void doSomething();
}

</pre><br /><pre name="code" class="java">
package com.pattern.decorator;
/**
 * 具体构件角色
 */
public class ConcreteComponent implements Component {

	public void doSomething() {
		System.out.println("功能A");
	}

}

</pre><br /><pre name="code" class="java">
package com.pattern.decorator;
/**
 * 装饰角色
 */
public class Decorator implements Component {
    //拥有一个抽象构件对象
	private Component component;
	public Decorator(Component component){
		this.component = component;
	}
	public void doSomething() {
		component.doSomething();
	}

}

</pre><br /><pre name="code" class="java">
package com.pattern.decorator;
/**
 * 具体装饰角色一
 */
public class ConcreteDecorator1 extends Decorator {

	public ConcreteDecorator1(Component component){
		super(component);
	}
	
	public void doSomething(){
		super.doSomething();
		this.doAnotherthing();
		
	}
	private void doAnotherthing(){
		System.out.println("功能B");
	}
}

</pre><br /><pre name="code" class="java">
package com.pattern.decorator;
/**
 * 具体装饰角色二
 */
public class ConcreteDecorator2 extends Decorator {

	public ConcreteDecorator2(Component component){
		super(component);
	}
	
	public void doSomething(){
		super.doSomething();
		this.doAnotherthing();
		
	}
	private void doAnotherthing(){
		System.out.println("功能C");
	}
}

</pre><br /><pre name="code" class="java">
package com.pattern.decorator;
/**
 * 客户端
 */
public class Client {
	
	public static void main(String[] args){
   //扩充了component 对象的功能。
		Component component = new ConcreteDecorator2(new ConcreteDecorator1(new ConcreteComponent()));
		component.doSomething();
	}
}

</pre><br /><br />运行结果：<br />功能A<br />功能B<br />功能C
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/186731#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 25 Apr 2008 13:07:13 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/186731</link>
        <guid>http://ttitfly.javaeye.com/blog/186731</guid>
      </item>
      <item>
        <title>缺省适配器模式和模板方法模式</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/186411" style="color:red;">http://ttitfly.javaeye.com/blog/186411</a>&nbsp;
          发表时间: 2008年04月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          缺省适配器模式和模板方法模式。<br /><br />缺省适配器模式：当一个接口有很都方法时，所有的实现类都需要实现该接口的所有方法。即使不需要的方法也需要空实现。这时就需要一个适配器类。该适配器类主要是实现该接口的所有方法（一般都空实现）。给真正的子类带来方便。<br /><br />模板方法模式:父类定义了几个方法。并规定了这几个方法的具体执行流程(哪个方法先执行，哪个方法后执行)，然后其子类实现这些方法。
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/186411#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 24 Apr 2008 15:31:27 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/186411</link>
        <guid>http://ttitfly.javaeye.com/blog/186411</guid>
      </item>
      <item>
        <title>适配器(Adapter)模式(包装模式)</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/186111" style="color:red;">http://ttitfly.javaeye.com/blog/186111</a>&nbsp;
          发表时间: 2008年04月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          适配器(Adapter)模式也叫包装模式，主要有两种实现形式:<br />A:类适配器模式<br />B:对象适配器模式<br /><br />都有三种角色<br />1:Target:供客户端调用<br />2:Adaptee:具体调用角色<br />3:Adapter:包装角色<br /><br /><br /><br />A:类适配器模式<br /><pre name="code" class="java">
package com.pattern.adapter.classadapter;
/**
 * 客户端要使用的目标类
 *
 */
public interface Target {
	
	public void method1();

}

</pre><br /><pre name="code" class="java">
package com.pattern.adapter.classadapter;

public class Adaptee {
	
	public void method2(){
		System.out.println("执行...");
	}

}

</pre><br /><pre name="code" class="java">
package com.pattern.adapter.classadapter;
//继承Adaptee类
public class Adapter extends Adaptee implements Target {

	//包装类
	public void method1() {
		this.method2();
	}

}

</pre><br /><pre name="code" class="java">
package com.pattern.adapter.classadapter;
//适配器模式也叫包装模式
public class Client {
	//类适配器模式
	public static void main(String[] args){
		Target target = new Adapter();
		target.method1();
	}

}


</pre><br />B:对象适配器模式<br /><br /><pre name="code" class="java">
package com.pattern.adapter.objectadapter;
/**
 * 客户端要使用的目标类
 *
 */
public interface Target {
	public void method1();
}

</pre><br /><pre name="code" class="java">
package com.pattern.adapter.objectadapter;

public class Adaptee {
	
	public void method2(){
		System.out.println("执行...");
	}

}

</pre><br /><pre name="code" class="java">
package com.pattern.adapter.objectadapter;

//不继承Adaptee类
public class Adapter implements Target {

	private Adaptee adaptee ;
	public Adapter(Adaptee adaptee){
		this.adaptee = adaptee;
	}
	
	public void method1() {
		adaptee.method2();
	}

}

</pre><br /><pre name="code" class="java">
package com.pattern.adapter.objectadapter;
//适配器模式也叫包装模式
public class Client {
	//对象适配器模式
	public static void main(String[] args){
		Target target = new Adapter(new Adaptee());
		target.method1();
	}

}

</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/186111#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 23 Apr 2008 23:40:26 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/186111</link>
        <guid>http://ttitfly.javaeye.com/blog/186111</guid>
      </item>
      <item>
        <title>java List&lt;String&gt;集合 传递值给js的数组</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/185103" style="color:red;">http://ttitfly.javaeye.com/blog/185103</a>&nbsp;
          发表时间: 2008年04月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">
&lt;script>
var intIndex=0;arrList = new Array();

arrList = "${result}".replace('[','').replace(']','').split(',');

&lt;/script>

</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/185103#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 21 Apr 2008 18:12:31 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/185103</link>
        <guid>http://ttitfly.javaeye.com/blog/185103</guid>
      </item>
      <item>
        <title>组合(Composite)模式</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/181022" style="color:red;">http://ttitfly.javaeye.com/blog/181022</a>&nbsp;
          发表时间: 2008年04月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          组合(Composite)模式主要角色：<br />1.Component角色<br />2.Leaf角色<br />3.Composite角色<br /><pre name="code" class="java">package com.pattern.composite;
/**
 * 组件抽象角色
 *
 */
public interface Component {
	
	public void run();

}
</pre><br /><pre name="code" class="java">package com.pattern.composite;
/**
 * 叶子角色
 *
 */
public class Leaf implements Component{
	
	public void run(){
		System.out.println(" run invoked...");
	}

}
</pre><br /><pre name="code" class="java">package com.pattern.composite;

import java.util.ArrayList;
import java.util.List;
/**
 * 组合角色
 * 实现组件角色接口，并且添加，删除的也是组件角色
 * 
 * Composite本来可以再包含Leaf和Composite的。而 Leaf和Composite 又都属于 Component，所以增加，删除 的是Component
 * 
 * 组合模式主要分为2种
 * 
 * 1 透明式

	添加Component对象的操作定义在Component角色中，这样的话不仅Composite需要实现这些方法，Leaf也需要实现这些方法，
	而这些方法对于Leaf来说没有任何意义，不过将系统实现统一起来了，因此对用户来说透明（用户无需区分Composite还是Leaf）
	，因为这些角色中都具备这些方法。
	
   2 安全式

	添加Component对象的操作定义在Composite角色中，这样的话Leaf就无需实现这些方法（因为Leaf本身根本不需要实现这些方法）
 *
 */
public class Composite  implements Component{
	
	List&lt;Component> list = new ArrayList&lt;Component>();
	
	//添加
	public void addComponent(Component component){
		list.add(component);
	}
	//删除
	public void removeComponent(Component component){
		list.remove(component);
	}
	
	//get
	public List&lt;Component> getAll(){
		return list;
	}
	
	public void run(){
		for(Component component : list){
			component.run();
		}
	}

}

</pre><br /><pre name="code" class="java">package com.pattern.composite;

public class Client {

	public static void main(String[] args){
		Leaf leaf1 = new Leaf();
		Leaf leaf2 = new Leaf();
		Leaf leaf3 = new Leaf();
		
		Composite composite = new Composite();
		
		composite.addComponent(leaf1);
		composite.addComponent(leaf2);
		
		Composite composite1 = new Composite();
		composite1.addComponent(composite);
		composite1.addComponent(leaf3);
		
		composite1.run();
		
	}
}
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/181022#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Apr 2008 21:05:49 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/181022</link>
        <guid>http://ttitfly.javaeye.com/blog/181022</guid>
      </item>
      <item>
        <title>命令模式</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/180645" style="color:red;">http://ttitfly.javaeye.com/blog/180645</a>&nbsp;
          发表时间: 2008年04月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          命令模式主要包括几个角色<br />1.接受者角色（相当于厨师）<br />2.请求者角色(相当于顾客)<br />3.命令角色<br />4.具体命令角色<br />5.客户角色<br /><br />具体代码如:<br /><br /><pre name="code" class="java">
package com.pattern.command;
/**
 *接受者（相当于厨师）
 */
public class Receiver {
	
	public void doReceiverAction(){
		System.out.println("接受者执行完毕");
	}

}

</pre><br /><br /><pre name="code" class="java">
package com.pattern.command;
/**
 *命令角色
 */
public interface Command {
	
	public void execute();

}

</pre><br /><br /><pre name="code" class="java">
package com.pattern.command;

/**
 * 具体命令角色,调用接受者执行具体命令。自己不能执行具体命令，所以需要创建一个接受者对象
 */
public class CommandImpl implements Command{

	private Receiver receiver;
	public CommandImpl(Receiver receiver){
		this.receiver = receiver;
	}
	public void execute(){
		receiver.doReceiverAction();
	}
}

</pre><br /><br /><pre name="code" class="java">
package com.pattern.command;
/**
 * 请求者角色，需要发出一个命令，所以需要创建一个命令角色的对象.(相当于顾客)
 */
public class ReqRole {

	private Command command;
	public ReqRole(Command command){
		this.command = command;
	}
	public  void  doAction(){
		command.execute();
	}
	
}

</pre><br /><br /><pre name="code" class="java">
package com.pattern.command;
/**
 *客户角色
 */
public class Test {
	
	public static void main(String[] args){
		
		Receiver receiver = new Receiver();//接受者。不和任何对象关联
		
		Command command = new CommandImpl(receiver);//构建一个命令角色。因为自己不执行任何命令，真正执行命令的是接受者，所以需要传递一个接受者对象
		
		ReqRole reqRole = new ReqRole(command);//请求角色。因为需要请求一个命令，所以需要接受一个命令角色对象
	
		reqRole.doAction();
	}
	

}

</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/180645#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 08 Apr 2008 23:01:11 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/180645</link>
        <guid>http://ttitfly.javaeye.com/blog/180645</guid>
      </item>
      <item>
        <title>sqlserver2005获取连接失败解决办法</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/179024" style="color:red;">http://ttitfly.javaeye.com/blog/179024</a>&nbsp;
          发表时间: 2008年04月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          sqlserver2005获取连接失败：com.microsoft.sqlserver.jdbc.SQLServerException: 到主机  的 TCP/IP 连接失败，解决办法：<br />安装完数据库后设置ICP/IP协议启动，具体如下：<br />   （1）打开SQL Server Configuration Manager<br />   （2）转到SQL Server 2005 Network Configuration->Protocols for MAHAIBO<br />   （3）将TCP/IP设置为Enabled（启用）<br />   （4）双击TCP/IP项，转到IP Addresses页<br />   （5）IP All中设置TCP Port为1433<br />   （6）重新启动服务<br /><br />即可。<br /><br /><pre name="code" class="java">
package org.test.db;

import java.sql.Connection;
import java.sql.DriverManager;

public class Conn {
	
	private static  String url = "jdbc:sqlserver://localhost:1433;DatabaseName=frame";
	private static  String username = "sa";
	private static  String password = "123456";
	private static  String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
	
	public static Connection getConnection(){
		Connection conn = null;
		try{
			Class.forName(driver);
			conn = DriverManager.getConnection(url,username,password);
		}catch(Exception e){
			e.printStackTrace();
		}
		return conn;
	}

}
</pre><br /><br />用JUnit单元测试如下：<br /><pre name="code" class="java">
package org.test.db;

import java.sql.Connection;

import org.junit.Assert;
import org.junit.Test;

public class ConnTest {

	@Test
	public void testGetConnection() {
		Connection conn = Conn.getConnection();
		Assert.assertNotNull(conn);
	}

}

</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/179024#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 02 Apr 2008 23:48:44 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/179024</link>
        <guid>http://ttitfly.javaeye.com/blog/179024</guid>
      </item>
      <item>
        <title>JUnit4中参数化测试</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/178496" style="color:red;">http://ttitfly.javaeye.com/blog/178496</a>&nbsp;
          发表时间: 2008年04月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          JUnit4中参数化测试要点：<br /><br />1. 测试类必须由Parameterized测试运行器修饰<br /><br />2. 准备数据。数据的准备需要在一个方法中进行，该方法需要满足一定的要求：<br /><br /> 1）该方法必须由Parameters注解修饰<br /> 2）该方法必须为public static的<br /> 3）该方法必须返回Collection类型<br /> 4）该方法的名字不做要求<br /> 5）该方法没有参数<br /><br />如：<br />测试方法：<br /><pre name="code" class="java">
public int add(int a,int b){
		return a+b;
	}
</pre><br /><br />测试代码：<br /><pre name="code" class="java">
package org.test;

import java.util.Arrays;
import java.util.Collection;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
 * 参数化测试的类必须有Parameterized测试运行器修饰
 *
 */
@RunWith(Parameterized.class)
public class AddTest3 {

	private int input1;
	private int input2;
	private int expected;
	
	/**
	 * 准备数据。数据的准备需要在一个方法中进行，该方法需要满足一定的要求：

		 1）该方法必须由Parameters注解修饰
		 2）该方法必须为public static的
		 3）该方法必须返回Collection类型
		 4）该方法的名字不做要求
		 5）该方法没有参数
	 * @return
	 */
	@Parameters
	@SuppressWarnings("unchecked")
	public static Collection prepareData(){
		Object [][] object = {{-1,-2,-3},{0,2,2},{-1,1,0},{1,2,3}};
		return Arrays.asList(object);
	}
	
	public AddTest3(int input1,int input2,int expected){
		this.input1 = input1;
		this.input2 = input2;
		this.expected = expected;
	}
	@Test
	public void testAdd(){
		Add add = new Add();
		int result = add.add(input1, input2);
		Assert.assertEquals(expected,result);
	}
	
}

</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/178496#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 01 Apr 2008 17:17:33 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/178496</link>
        <guid>http://ttitfly.javaeye.com/blog/178496</guid>
      </item>
      <item>
        <title>struts备忘（转）</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/178065" style="color:red;">http://ttitfly.javaeye.com/blog/178065</a>&nbsp;
          发表时间: 2008年03月31日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          =======&lt;html:messages>============<br />Action 中 :<br />    ActionMessages message = new ActionMessages();<br />    message.add(" 消息句柄 ",new ActionMessage(" 资源文件中 Key 值 ",String 类型描述信息 ));<br />    this.addMessages(request,message);<br />    return ActionForward;<br />JSP 页面中 :<br />    &lt;html:messages id=" 指定使用消息的标识 " property=" 消息句柄 " message="true|false"><br />       &lt;bean:write name=" 以上所指 ID 标识 "/><br />    &lt;/html:messages> <br /><br />==========&lt;html:errors>==============<br />Action 中 :<br />    ActionMessages message = new ActionMessages();<br />    message.add(" 消息句柄 ",new ActionMessage(" 资源文件中 Key 值 ",String 类型描述信息 ));<br />    this.saveErrors(request,message);<br />    return ActionForward;<br />JSP 页面中 :<br />    &lt;html:errors property=" 消息句柄 "/> <br /><br />如果Action中这样设定(false)，页面的提示信息将不从资源文件里读取:<br />    ActionMessages message = new ActionMessages();<br />    message.add("消息句柄",new ActionMessage("String类型描述信息",false));<br />    this.saveErrors(request,message);<br />    return ActionForward;<br />JSP页面:<br />    &lt;html:errors/>或&lt;html:errors property="消息句柄"/> <br /><br /><br /><br /><br /><br /><br />&lt;logic:messagesPresent>和&lt;logic:messagesNotPresent>标签<br />&lt;logic:messagePresent>和&lt;logic:messageNotPresent>标签用来判断是否在request范围内在在指定的<br /><br />ActionMessages(或其子类ActionErrors)  对象, 以及在ActionMessages 对象中是否存特定的信息<br /><br />&lt;logic:messagesPresent>    存在指定信息<br />&lt;logic:messagesNotPresent> 不存在指定信息<br /><br />A. name 属性 : 指定request 范围内检索ActionMessages 对象的属性key.<br />B. message 属性 : 如果为 true , 则从request 范围内检索属性key 为Globals.MESSAGE_KEY 的ActionMessages , 此时name 属性指定值无效; 如果为false , 则根据 name属性指定key, 从request 范围内检索ActionMessages 对象; 如果此时没有设置name 属性, 则默认的属性key 为lobals.ERROR_KEY.<br />C. property 属性 : 指定从 ActionMessages 对象中检索某条消息的消息 key.<br /><br />流程:<br />(1) 把 name 变量赋值给局部变量 key, 这个变量将用于在 request范围内检索 ActionMessages 对象.<br />(2) 如果 message 变量为 true , 就把局部变量 key 设为 Globals.MESSAGE_KEY 此时设置 name 是无效的.<br />(3) 调用 TagUtils.getInstance().getActionMessages(pageContext, key) 方法, 获得 request 范围内的ActionMessages 对象.<br />(4) 如果 property 变量不为null, 将再判断在 ActionMessages 对象中是否包含由property变量指定的消息key.<br /><br /><br />&lt;%<br />    ActionErrors errors = new ActionErrors();<br />    errors.add("totallylost", new ActionMessage("application.totally.lost"));<br />    request.setAttribute(Globals.ERROR_KEY, errors);<br />    request.setAttribute("myerrors", errors);<br />%><br />1. 从request 范围内检索属性key 为Globals.ERROR_KEY 的 ActionMessages 对象, 其判断结果为 true 将执行标签主体内容.<br />&lt;logic:messagesPresent><br />    Yes, there are errors.<br />&lt;/logic:messagesPresent><br /><br />2. 从request 范围内检索key为"myerrors" 的ActionMessages 对象,其判断结果为true, 将执行标签主体的内容.<br />&lt;logic:messagesPresent name = "myerrors"><br />    Yes, there are errors in myerrors collection.<br />&lt;/logic:message><br /><br />3. 从request 范围内检索属性key 为Globals.MESSAGE_KEY的ActionMessages 对象, 由于不存在这样的ActionMessags 对象, 其判断结果为 true, 将执行标签主体内容.<br />&lt;logic:messagesNotPresent message = "true"><br />    There are no normal messages.<br />&lt;/logic><br /><br />4. 从request 范围内检索属性 key 为Globals.ERROR_KEY 的ActionMessages 对象, 然后再从ActionMessages 对象中检索消息key 为"noSuchError" 的消息, 由于不存在这样的消息, 其判断结果为true , 将执行标签主体内容.<br />&lt;logic:messagesNotPresent property = "noSuchError"><br />    There is no error name "SuchError".<br />&lt;/logic:messageNotPresent><br /><br />5. 从 request 范围内检索属性key 为Globals.ERROR_KEY 的ActionMessages 对象, 然后再从ActionMessages 对象中检索消息key 为"totallylost" 的消息, 判断结果为true, 将执行标签主体的内容.<br />&lt;logic:messagesPresent property = "totallylost"><br />    There is an error named "totallylost".<br />&lt;/logic:messagePresent>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/178065#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 31 Mar 2008 15:14:50 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/178065</link>
        <guid>http://ttitfly.javaeye.com/blog/178065</guid>
      </item>
      <item>
        <title>Junit4</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/177850" style="color:red;">http://ttitfly.javaeye.com/blog/177850</a>&nbsp;
          发表时间: 2008年03月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          junit4比junit3.8有了较大的改进，主要体现在<br />1.增加了Annotation注解。<br />2.类不需要extends TestCase<br />3.方法名可以随便起<br />4.通过Annotation注解(@Test)来体现某个类为测试类<br />5.对异常处理方面有了较大改进,如：@Test(expected = Exception.class)通过expected参数大大简化了处理<br />6.新增了@BeforeClass,全局只执行一次。junit3.8里没有这样的方法。<br /><br /><pre name="code" class="java">

package org.test;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/**
 * 不需要再继承TestCase
 *
 */
public class AddTest2 {
	public AddTest2(){
		System.out.println("constructor invoked!");
	}
	private static Add add ;
	
	/**
	 * junit4里新增的特性，必须是static的，全局只执行一次，在所以测试方法前执行,并且是在该测试类的构造函数执行前执行。仅执行一次
	 */
	@BeforeClass
	public static void globalInit(){
		add = new Add();
		System.out.println("global init");
	}
	/**
	 * 相当于junit3.8里的setUp()，每个测试方法执行前都会执行一次
	 */
	@Before
	public void init(){
		System.out.println("init");
	}
	/**
	 * 相当于junit3.8里的tearDown
	 */
	public void destroy(){
		System.out.println("destroy");
	}
	/**
	 * junit4里方法名字可以随便起，但是必须满足
	 * 1）public
	 * 2) void
	 * 3) 方法没有参数
	 */
	@Test
	public void myAdd(){
		int result = add.add(3, 5);
		Assert.assertEquals(8, result);
	}

}
</pre><br />执行结果：<br />global init<br />constructor invoked!<br />init<br /><br /><br /><br /><pre name="code" class="java">
package org.test;

import org.junit.Test;

public class DivideTest2 {
	
	private Divide divide ;
	public void init(){
		divide = new Divide();
	}
	/**
	 * 加了expected参数意思是，该方法必须抛出该异常，否则测试失败
	 * @throws Exception
	 */
	@Test(expected = Exception.class)
	public void myDivide() throws Exception{
		int result = divide.divide(10, 0);
	}

}


</pre><br /><br /><br /><pre name="code" class="java">
package org.test;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
 * RunWith注解的参数value值必须是一个测试运行器，也就是必须是org.junit.runner.Runner类或其子类。org.junit.runners.Suite是Runner的子类
 *
 */
@RunWith(Suite.class)
@Suite.SuiteClasses({AddTest2.class,DivideTest2.class})
public class TestAll1 {

}
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/177850#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 30 Mar 2008 21:58:34 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/177850</link>
        <guid>http://ttitfly.javaeye.com/blog/177850</guid>
      </item>
      <item>
        <title>JUnit3.8</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/177835" style="color:red;">http://ttitfly.javaeye.com/blog/177835</a>&nbsp;
          发表时间: 2008年03月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">package org.test;
package org.test;

import junit.swingui.TestRunner;

public class Add {
	
	public int add(int a,int b){
		return a+b;
	}
	
	public static void main(String[] args){
		TestRunner runner = new TestRunner();
		runner.run(AddTest.class);
	}

}


</pre><br /><br /><pre name="code" class="java">
package org.test;

import junit.framework.Assert;
import junit.framework.TestCase;

public class AddTest extends TestCase {
	
	private Add add = null;
	 
	@Override
	protected void setUp() throws Exception {
		add = new Add();
	}

	/**满足条件
	 * 1)必须是public
	 * 2)必须是void
	 * 3)必须以test开头
	 * 4)必须无参数
	 */
	public void testAdd(){
		int result = add.add(3, 5);
		Assert.assertEquals(8, result);
	}

}

</pre><br /><br /><pre name="code" class="java">
package org.test;

public class Divide {
	
	public int divide(int a,int b) throws Exception{
		if(0 == b){
			throw new Exception("除数不能为0");
		}
		return a/b;
	}

}

</pre><br /><br /><pre name="code" class="java">
package org.test;

import junit.framework.Assert;
import junit.framework.TestCase;

public class DivideTest  extends TestCase {
	
	private Divide divide = null;
	 
	@Override
	protected void setUp() throws Exception {
		divide = new Divide();
	}

	/**满足条件
	 * 1)必须是public
	 * 2)必须是void
	 * 3)必须以test开头
	 * 4)必须无参数
	 */
	public void testDivide(){
		int result = 0;
		try {
			result = divide.divide(10, 2);
		} catch (Exception e) {
			e.printStackTrace();
		}
		Assert.assertEquals(5, result);
	}
	
	public void testDivide0(){
		
		Throwable tx = null;
		try {
			int result = divide.divide(10, 0);
			Assert.fail();//"出错了"的意思
		} catch (Exception e) {
			tx = e;
		}
		
		Assert.assertNotNull(tx);
		Assert.assertEquals(Exception.class, tx.getClass());
		Assert.assertEquals("除数不能为0", tx.getMessage());
		
	}
}

</pre><br /><br /><pre name="code" class="java">
package org.test;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class TestAll extends TestCase {
	
	/**
	 * 方法必须这样写
	 * @return
	 */
	public static  Test suite(){
		TestSuite suite = new TestSuite();
		
		suite.addTestSuite(DivideTest.class);
		suite.addTestSuite(AddTest.class);
		
		return suite;
	}

}

</pre>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/177835#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 30 Mar 2008 20:55:39 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/177835</link>
        <guid>http://ttitfly.javaeye.com/blog/177835</guid>
      </item>
      <item>
        <title>mysql主辅库同步</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/171485" style="color:red;">http://ttitfly.javaeye.com/blog/171485</a>&nbsp;
          发表时间: 2008年03月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          主库:192.168.40.4 DB:testsyn table:users<br />辅库:192.168.40.5<br /><br />1.配置主库my.cnf<br /><pre name="code" class="java">
[mysqld]
log-bin=mysql-testsyn-bin --主库二进制日志文件名的前缀
binlog-do-db=testsyn      --要同步的数据库
server-id = 1             --serverid和辅库不同即可

</pre><br /><br />启动mysql<br /><br /><span style="color: red">创建用户testsyn.拥有replication slave权限</span><br /><pre name="code" class="java">grant replication slave on *.* to "testsyn"@"192.168.40.%" identified by 'testsyn' with grant option;</pre><br /><br />查看主库状态：<br /><br /><pre name="code" class="java">show master status;</pre><br /><br />2.配置辅库my.cnf<br /><pre name="code" class="java">
server-id = 2
master-host = 192.168.40.4
master-user = testsyn 
master-password = testsyn
master-port = 3306
master-connect-retry = 5  --重试间隔时间
replicate-do-db = testsyn    --同步db
#replicate-wild-do-table = user%.%
#replicate-do-db = itemcontent
#replicate-do-db = srcstore

</pre><br /><br />启动mysql<br /><br />查看辅库状态：<br /><pre name="code" class="java"> show slave status;</pre><br />说明:<br />Slave_IO_Running:连接到主库,并读取主库的日志到本地，生成本地日志文件<br />Slave_SQL_Running：读取本地日志文件，并执行日志里的sql<br /><br />3.把主库上的数据dump到辅库上<br /><br /><br />主库：192.168.40.4:<br /><pre name="code" class="java">mysqldump --opt --master-data -uspider -pcrawler testsyn > /home/mahaibo/dump-testsyn &</pre><br /><br /><span style="color: red">注意参数：--master-data</span><br /><br />辅库:192.168.40.5<br /><span style="color: red">先建立库:create database testsyn;</span><br /><br />导入：<br /><pre name="code" class="java">stop slave

mysql -uspider -pcrawler testsyn &lt; /home/mahaibo/dump-testsyn 


start slave;</pre><br /><br /><span style="color: red">必须先停止stop slave，然后才能导入</span><br /><br />4.在主库192.168.40.4上在users表里插入一条数据：<br />insert into users (username,password) values ('test1','test1');<br /><br />辅库上的users表里也相应的有了数据。<br /><br />5.查看主库二进制日志文件内容：<br /><span style="color: red"> show binlog events;<br /></span><br /><br /><br />注意：<br />1.主辅库同步主要是通过<span style="color: red">二进制日志</span>来实现同步的。<br />2.在启动辅库的时候必须<span style="color: red">先把数据同步</span>，<span style="color: red">并删除日志目录下的：master.info文件</span>。因为master.info记录了上次要连接主库的信息，如果不删除，即使my.cnf里进行了修改，也不起作用。因为读取的还是master.info文件里的信息。
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/171485#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 14 Mar 2008 17:54:58 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/171485</link>
        <guid>http://ttitfly.javaeye.com/blog/171485</guid>
      </item>
      <item>
        <title>DWR系统学习笔记一</title>
        <author>ttitfly</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ttitfly.javaeye.com">ttitfly</a>&nbsp;
          链接：<a href="http://ttitfly.javaeye.com/blog/169183" style="color:red;">http://ttitfly.javaeye.com/blog/169183</a>&nbsp;
          发表时间: 2008年03月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1.官方网站下载:<a href="http://getahead.org/dwr/download" target="_blank">http://getahead.org/dwr/download</a><br />2.dwr.jar拷贝到lib目录下<br />3.web.xml<br /><pre name="code" class="java">
&lt;servlet>
    &lt;servlet-name>dwr-invoker&lt;/servlet-name>
    &lt;servlet-class>org.directwebremoting.servlet.DwrServlet&lt;/servlet-class>
    &lt;init-param>
      &lt;param-name>debug&lt;/param-name>
      &lt;param-value>true&lt;/param-value>
      &lt;!--开发阶段把debug设置为true,可以http://localhost:8080/dwrtest/dwr进行详细查看-->
    &lt;/init-param>
    &lt;init-param>
      &lt;param-name>activeReverseAjaxEnabled&lt;/param-name>
      &lt;param-value>true&lt;/param-value>
    &lt;/init-param>
    &lt;init-param>
      &lt;param-name>initApplicationScopeCreatorsAtStartup&lt;/param-name>
      &lt;param-value>true&lt;/param-value>
    &lt;/init-param>
    &lt;init-param>
      &lt;param-name>maxWaitAfterWrite&lt;/param-name>
      &lt;param-value>100&lt;/param-value>
    &lt;/init-param>
    &lt;init-param>   
            &lt;param-name>crossDomainSessionSecurity&lt;/param-name>   
            &lt;param-value>false&lt;/param-value>   
    &lt;/init-param>

    &lt;load-on-startup>1&lt;/load-on-startup>
  &lt;/servlet>
  &lt;servlet-mapping>
	    &lt;servlet-name>dwr-invoker&lt;/servlet-name>
	    &lt;url-pattern>/dwr/*&lt;/url-pattern>
  &lt;/servlet-mapping>

</pre><br /><br />4.在WEB-INF下建立dwr.xml<br /><pre name="code" class="java">
&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">

&lt;dwr>

  &lt;allow>
    &lt;create creator="new" javascript="service">
      &lt;param name="class" value="helloworld.Service"/>
      &lt;include method="sayHello"/>
    &lt;/create>
  &lt;/allow>

&lt;/dwr>
</pre><br /><br /><span style="color: red">注:&lt;create>标签里的属性javascript的值有2个意思。<br />一：把相应的类生成一个js文件，那么该js文件的名字。<br />二：前台调用该类的某个方法时的引用名字。</span><br /><br />5.Service.java<br /><pre name="code" class="java">
package helloworld;

public class Service {

	public String sayHello(String yourname){
		return "hello :" + yourname;
	}
}


</pre><br /><br />6.和WEB-INF位于同一目录下的helloworld.jsp:<br /><br /><pre name="code" class="java">
&lt;%@ page language="java" pageEncoding="UTF-8"%> 
&lt;html> 
&lt;head>
	 &lt;title>
		 My JSP 'first_dwr.jsp' starting page
	 &lt;/title> 
	 &lt;script type='text/javascript' src='dwr/util.js'>&lt;/script> 
	 &lt;script type='text/javascript' src='dwr/engine.js'>&lt;/script>
	 &lt;script type='text/javascript' src='dwr/interface/service.js'> &lt;/script> 
	 &lt;script type="text/javascript"> 
	 	
	 	function show(){
	 		var str = $("text").value;
	 		service.sayHello(str,callBack);//not callBack();
	 	}
	 	function callBack(data)//not (var data)
	 	{
	 		dwr.util.setValue("showName",data,{escapeHtml:true});
	 	}
	 &lt;/script> 
  
 &lt;/head>
 
 &lt;body>
 
  &lt;input type="text" id="text" >&lt;input type="button" onclick="show()" value="submit">
  &lt;div id="showName">&lt;/div>
 
 &lt;/body> 
 
 &lt;/html>

</pre><br /><br />注：<br /><span style="color: red">1.util.js和engine.js都不需要从下载的dwr的源文件包里拷贝过来。<br />2.service.js文件是动态生成的。该js文件的名字由dwr.xml里的&lt;create>标签的属性javascript的值决定<br />3.如果把util.js和engine.js拷贝到工程里并且引用目录变为：<br />&lt;script type='text/javascript' src='scripts/util.js'>&lt;/script> <br />&lt;script type='text/javascript' src='scripts/engine.js'>&lt;/script><br />那么dwr.util.setValue("showName",data,{escapeHtml:true});这些函数用不了。</span><br />4.<br /><pre name="code" class="java">
                function show()
                {
	 		var str = $("text").value;
	 		service.sayHello(str,callBack);//not callBack();
	 	}
</pre><br /><span style="color: red"><br />回调函数直接写名字，不用带参数。<br />service.sayHello,为什么是service，而不是其它？因为：由dwr.xml里的&lt;create>标签的属性javascript的值决定<br /></span><br /><br /><pre name="code" class="java">
	 	function callBack(data)//not (var data)
	 	{
	 		dwr.util.setValue("showName",data,{escapeHtml:true});
	 	}
</pre><br /><span style="color: red"><br />function callBack(var data) 加var类型就不对了。<br />{escapeHtml:true}的意思是对html标签进行过滤，也就是html内容原样输出。&lt;html>输出为&lt;html>，&lt;>输出为&lt;><br />{escapeHtml:false}的意思是对html标签不进行过滤，也就是html内容不输出。&lt;html>不输出 ，&lt;>输出为&lt;>，因为&lt;>不为html标签<br /></span><br /><br />5. &lt;script type='text/javascript' src='dwr/util.js'>&lt;/script> <br />   &lt;script type='text/javascript' src='dwr/engine.js'>&lt;/script><br />   &lt;script type='text/javascript' src='dwr/interface/service.js'> &lt;/script><br />/dwr/util.js <span style="color: red">以/开头代表服务器的web应用目录(对tomcat而言，就是${tomcat_home}/webapp)，对本例而言，应该改为;/dwrtest/dwr/util.js</span><br />dwr/util.js  <span style="color: red">不以/开头的代表当前文件的目录，对本例而言，就是helloworld.jsp所在目录</span>
          <br/>
          <span style="color:red;">
            <a href="http://ttitfly.javaeye.com/blog/169183#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 07 Mar 2008 17:14:49 +0800</pubDate>
        <link>http://ttitfly.javaeye.com/blog/169183</link>
        <guid>http://ttitfly.javaeye.com/blog/169183</guid>
      </item>
  </channel>
</rss>