<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>cljspn</title>
    <description>1、多年项目管理和软件开发的工作经验，丰富的J2EE项目构建和实施经验 
2、两年客户服务的工作经验，具备良好的与客户沟通和协调的能力 
3、具备丰富的大规模互联网web应用的架构经验 
4、技术:基础扎实,具备1年的项目经理管理能力 ( 带领8人以上的团队开发 ) 
5、行业: 4年公安行业开发,参与五个以上大型公安行业项目系统的设计和开发 
6、特长:擅长钻研高新技术及制定各种标准, 很强的语言表达能力</description>
    <link>http://cljspn.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>设计模式之组合模式(Composite)</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/179526" style="color:red;">http://cljspn.javaeye.com/blog/179526</a>&nbsp;
          发表时间: 2008年04月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>　　Composite定义,将对象以树形结构组织起来,以达成&ldquo;部分－整体&rdquo; 的层次结构，使得客户端对单个对象和组合对象的使用具有一致性.注意：＂部分－整体＂应具有共同的接口或者是抽象类．</p><p>Composite比较容易理解，想到Composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时，Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。<br /><br />Composite好处:<br />1.使客户端调用简单，客户端可以一致的使用组合结构或其中单个对象，用户就不必关系自己处理的是单个对象还是整个组合结构，这就简化了客户端代码。<br />2.更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。</p><p>&nbsp;</p><p>如何使用Composite?<br />首先定义一个接口或抽象类，这是设计模式通用方式了，其他设计模式对接口内部定义限制不多，Composite却有个规定，那就是要在接口内部定义一个用于访问和管理Composite组合体的对象们（或称部件Component）.</p><p>&nbsp;</p><p>首先定义一个＂整体－部分＂的接口．也是Component的定义．</p><pre name="code" class="java">//设备，器材接口
public interface Equipment {
   //实际的价格
   double netPrice();
   //打折价格
   double discountPrice();
   boolean add(Equipment equipment);
   boolean remove(Equipment equipment);
   Iterator iter();
}</pre><p>&nbsp;Disk是组合体内的一个对象，或称一个部件，这个部件是个单独元素( Primitive)。</p><pre name="code" class="java">//硬盘
public class Disk implements Equipment {

	public boolean add(Equipment equipment) {
		// TODO Auto-generated method stub
		return false;
	}

	public double discountPrice() {
		// TODO Auto-generated method stub
		return 0.5;
	}

	public Iterator iter() {
		// TODO Auto-generated method stub
		return null;
	}

	public double netPrice() {
		// TODO Auto-generated method stub
		return 1;
	}

	public boolean remove(Equipment equipment) {
		// TODO Auto-generated method stub
		return false;
	}

}</pre><p>&nbsp;还有一种可能是，一个部件也是一个组合体，就是说这个部件下面还有'儿子'，这是树形结构中通常的情况，应该比较容易理解。现在我们先要定义这个组合体：</p><pre name="code" class="java">public class CompositeEquipment implements Equipment {
	private List&lt;Equipment&gt; equipments = new ArrayList&lt;Equipment&gt;();

	public boolean add(Equipment equipment) {
		// TODO Auto-generated method stub
		equipments.add(equipment);
		return true;
	}

	public double discountPrice() {
		double discountPrice = 0.0;
		for (Iterator&lt;Equipment&gt; iterator = equipments.iterator(); iterator
				.hasNext();) {
			discountPrice += ((Equipment) iterator.next()).discountPrice();
		}
		return discountPrice;
	}

	public Iterator&lt;Equipment&gt; iter() {
		return equipments.iterator();
	}

	public double netPrice() {
		double netPrice = 0.0;
		for (Iterator&lt;Equipment&gt; iterator = equipments.iterator(); iterator
				.hasNext();) {
			netPrice += ((Equipment) iterator.next()).netPrice();

		}
		return netPrice;
	}

	public boolean remove(Equipment equipment) {
		equipments.remove(equipment);
		return true;
	}

}
</pre><p>我们再看看CompositeEquipment的两个具体类:盘盒Chassis和箱子Cabinet，箱子里面可以放很多东西，如底板，电源盒，硬盘盒等；盘盒里面可以放一些小设备，如硬盘 软驱等。无疑这两个都是属于组合体性质的。</p><pre name="code" class="java">//箱子
public class Cabinet extends CompositeEquipment {
	public double netPrice() {
		return 1.0 + super.netPrice();
	}

	public double discountPrice() {
		return 0.5 + super.discountPrice();
	}
}
//盘盒
public class Chassis extends CompositeEquipment {
	public double netPrice() {
		return 1.0 + super.netPrice();
	}

	public double discountPrice() {
		return 0.5 + super.discountPrice();
	}
}</pre><p>&nbsp;</p><p>下面看一下测试：</p><pre name="code" class="java">public static void main(String[] args) {
		Cabinet cabinet = new Cabinet();

		Chassis chassis = new Chassis();
		// chassis.name = &quot;PC Chassis&quot; ;
		// 将PC Chassis装到Tower中 (将盘盒装到箱子里)
		cabinet.add(chassis);
		// 将一个10GB的硬盘装到 PC Chassis (将硬盘装到盘盒里)
		Disk disk = new Disk();
		// disk.name = &quot;10 GB&quot; ;
		chassis.add(disk);

		// 调用 netPrice()方法;
		System.out.println(&quot;netPrice=&quot; + cabinet.netPrice());
		System.out.println(&quot;discountPrice=&quot; + cabinet.discountPrice());

	}</pre><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/179526#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, 04 Apr 2008 18:04:19 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/179526</link>
        <guid>http://cljspn.javaeye.com/blog/179526</guid>
      </item>
      <item>
        <title>设计模式之命令（State）模式</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/174371" style="color:red;">http://cljspn.javaeye.com/blog/174371</a>&nbsp;
          发表时间: 2008年03月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp;&nbsp; 状态模式是在程序开发时，经常用到的模式。如果没有应用过，而实现业务功能。那你也一定是按照状态模式的路子走的，只不过你没有感觉到而已。它的实现，是要根据对象的内部状态变化，而自动执行相应的功能。<br />费话就不说了，请看一下源代码，这也是我研究设计模式时看到的一个例子，把其翻译成中文，使个位网友能够看懂些，由于水平有限，只能达到这样，还希望网友多指证，也算是抄来的哈哈，谢谢啊。</p><pre name="code" class="java">public class GumballMachine {
	//这就是那4个状态,每个状态都用一个不同的整数代表,他们符合状态图   
    final static int SOLD_OUT = 0;      //糖果售完状态   
    final static int NO_QUARTER = 1;    //没有钱状态   
    final static int HAS_QUARTER = 2;   //有钱状态   
    final static int SOLD = 3;      //售出糖果   
    //这个实例变量跟踪当前状态,一开始被设为&quot;糖果售完&quot;,因为糖果机安装时是没有装糖果的   
    int state = SOLD_OUT;   
    int count = 0;  //这个变量用来追踪机器内的糖果数目   
    //构造器初始糖果库存量当做参数,如果库存不为0的话,机器就进入&quot;没有钱&quot;的状态,等着你向里投钱
    public GumballMachine(int count) {   
        this.count = count;   
        if (count &gt; 0) {   
            state = NO_QUARTER;   
        }   
    }   
    
  //当把钱投入进来,就会执行这里   
    public void insertQuarter() {   
        if (state == HAS_QUARTER) {   
            //如果此时的状态为有钱状态，则通知顾客   
            System.out.println(&quot;你不能再向糖果机里投钱了&quot;);   
        } else if (state == NO_QUARTER) {   
            //如果是在&quot;没有25分钱&quot;的状态下,我们就接受25分钱,并将状态转换到&quot;有25分钱&quot;   
            state = HAS_QUARTER;   
            System.out.println(&quot;你可以向糖果机里投钱&quot;);   
        } else if (state == SOLD_OUT) {   
            //如果糖果售完,就拒绝收钱   
            System.out.println(&quot;糖果已经卖完，不能再向里投钱了&quot;);   
        } else if (state == SOLD) {   
            //如果顾客买到糖果,就需要稍等下,好让状态转换完毕,恢复到&quot;没有25分钱&quot;的状态
            System.out.println(&quot;已向你卖出一个糖果,请稍等,再向里投钱。&quot;);   
        }   
    }   
    //现在,如果顾客试着退回25分钱...   
    public void ejectQuarter() {   
        if (state == HAS_QUARTER) {   
            //如果有25分钱,就退钱,回到&quot;没有25分钱&quot;的状态   
            System.out.println(&quot;退钱成功&quot;);   
            state = NO_QUARTER;   
        } else if (state == NO_QUARTER) {   
            //如果没有25分钱,当然不能退回   
            System.out.println(&quot;没有钱，你不能退钱&quot;);   
        } else if (state == SOLD) {   
            //如果顾客已经转动手柄,就不能退钱了,他已经拿到糖果了
        	state = NO_QUARTER;
            System.out.println(&quot;对不起，糖果已经卖出不能退钱。&quot;);   
        } else if (state == SOLD_OUT) {   
            //如果糖果售完,就不可能接受25分钱,当然也不可能退钱   
            System.out.println(&quot;对不起，糖果已经卖完不能退钱&quot;);   
        }   
    }   
  //顾客试着转动手柄...   
    public void turnCrank() {   
        if (state == SOLD) {   
            //别想骗过机器拿2次糖果   
            System.out.println(&quot;不能再给你了&quot;);   
        } else if (state == NO_QUARTER) {   
            //我们需要先投入25分钱   
            System.out.println(&quot;你没有投钱糖果不能卖给你&quot;);   
        } else if (state == SOLD_OUT) {   
            //没有糖果了   
            System.out.println(&quot;糖果机中没有糖果了，你不能进行交易。&quot;);   
        } else if (state == HAS_QUARTER) {   
            //成功!他拿到糖果了.改变状态到&quot;售出糖果&quot;,然后调用机器的dispense()方法   
            System.out.println(&quot;请稍等，一会糖果你就可以拿到了...&quot;);   
            state = SOLD;   
            dispense();   
        }   
    }   
    //发放糖果   
    public void dispense() {   
        if (state == SOLD) {   
            //我们正在&quot;售出糖果&quot;状态   
            System.out.println(&quot;一个糖果将从这里出来....&quot;);   
            count = count - 1;   
            //我们在这里处理&quot;糖果售完&quot;的情况   
            if (count == 0) {//最后一颗,将机器设置到&quot;糖果售完&quot;状态   
                System.out.println(&quot;库存为零!&quot;);   
                state = SOLD_OUT;   
            } else {    //否则回到&quot;没有25分钱&quot;的状态   
                state = NO_QUARTER;   
            }   
        } else if (state == NO_QUARTER) {   //以下都不应该发生,但如果顾客这么做了,得到的应该是错误消息而不是糖果   
            System.out.println(&quot;你需要向糖果机里投钱。。&quot;);   
        } else if (state == SOLD_OUT) {   
            System.out.println(&quot;糖果已经卖没了&quot;);   
        } else if (state == HAS_QUARTER) {   
            System.out.println(&quot;请您稍等交易还没有结束。&quot;);   
        }   
    }   

}</pre><p>&nbsp;</p><p>测试就来自已写吧，我提供个思路，就是页面提供几个开关，即按纽、checkbox等在它们的单击事件上<span style="font-family: Arial">GumballMachine实例的内部状态改变。然后看其变化，就可以了。</span></p><p>大家看没看出来，这段代码还有一些&ldquo;怪的味道&rdquo;呀，这时如果业务变化了，如果客户是一个中奖的用户，需要糖果机吐出两块糖果，怎么办？，是不是还得在各个方法中把这个状态给加上呀，又得加一个if语句呢，这是一个业务发生了变化，如果业务要无限的变化下去，程序员是不是都要疯了，哈哈。所以要对其进行重构了。</p><p>要把这几个状态抽象出来。想到这里看一下代码就明白了。</p><pre name="code" class="java">public interface State {
	//投钱的状态
	public void insertQuarter();
	//退钱的状态
	public void ejectQuarter();
    //按下按纽状态
	public void turnCrank();
    //发放物品状态
	public void dispense();

}</pre><p>下面是几个实现这个状态接口的实现类。</p><p>&nbsp;</p><pre name="code" class="java">public class HasQuarterState implements State{
	GumballMachineTwo gumballMachine;   
    //增加一个随机数产生器,产生10%的机会   
    Random randomWinner = new Random(System.currentTimeMillis());   
    public HasQuarterState(GumballMachineTwo gumballMachine) {   
        this.gumballMachine = gumballMachine;   
    }   
    public void insertQuarter() {   //这是一个对当前状态不恰当的动作   
        System.out.println(&quot;不能再投钱了，已经有钱了。&quot;);   
    }   
    
    public void ejectQuarter() {    //退钱并转换状态到NoQuarterState   
        System.out.println(&quot;退钱返回&quot;);
        //把糖果机从有钱状态改成没钱状态
        gumballMachine.setState(gumballMachine.getNoQuarterState());   
    }   
    
    public void turnCrank() {   
        System.out.println(&quot;请稍等，一会糖果你就可以拿到了...&quot;);   
        int winner = randomWinner.nextInt(10);   
        //决定这个顾客是否赢了   
        if ((winner == 0) &amp;&amp; (gumballMachine.getCount() &gt; 1)) {   
            gumballMachine.setState(gumballMachine.getWinnerState());   
        } else {   
            gumballMachine.setState(gumballMachine.getSoldState());   
        }   
    }   
    public void dispense() {    //这是一个对当前状态不恰当的动作   
        System.out.println(&quot;请您稍等交易还没有结束。&quot;);   
    }   

}

public class NoQuarterState implements State {
	GumballMachineTwo gumballMachine;

	// 通过构造器得到糖果机的引用
	public NoQuarterState(GumballMachineTwo gumballMachine) {
		this.gumballMachine = gumballMachine;
	}

	// 分发物品
	public void dispense() {
		System.out.println(&quot;没有钱，不能分发糖果&quot;);   
	}

	// 退钱
	public void ejectQuarter() {
		System.out.println(&quot;没有钱，不能退钱&quot;);

	}

	// 投钱
	public void insertQuarter() {
		// TODO Auto-generated method stub

	}

	// 按纽操作
	public void turnCrank() {
		// TODO Auto-generated method stub

	}

}

public class SoldOutState implements State {
	GumballMachineTwo gumballMachine;

	public SoldOutState(GumballMachineTwo gumballMachine) {
		this.gumballMachine = gumballMachine;
	}

	public void dispense() {
		System.out.println(&quot;糖果已经卖没了&quot;); 

	}

	public void ejectQuarter() {
		System.out.println(&quot;对不起，糖果已经卖完不能退钱&quot;); 

	}

	public void insertQuarter() {
		System.out.println(&quot;糖果已经卖完，不能再向里投钱了&quot;);

	}

	public void turnCrank() {
		// TODO Auto-generated method stub

	}

}

public class SoldState implements State{
	GumballMachineTwo gumballMachine;   
    public SoldState(GumballMachineTwo gumballMachine) {   
        this.gumballMachine = gumballMachine;   
    }       
    //以下3个方法对此状态来说都是不恰当的   
    public void insertQuarter() {   
        System.out.println(&quot;已向你卖出一个糖果,请稍等,再向里投钱。&quot;);   
    }   
    public void ejectQuarter() {   
        System.out.println(&quot;对不起，糖果已经卖出不能退钱&quot;);   
    }   
    public void turnCrank() {   
        System.out.println(&quot;糖果已经卖出，不能再给你了&quot;);   
    }   
    //首先让机器发放糖果   
    public void dispense() {   
        gumballMachine.releaseBall();   
        if (gumballMachine.getCount() &gt; 0) {   
            gumballMachine.setState(gumballMachine.getNoQuarterState());   
        } else {   
            System.out.println(&quot;Oops, out of gumballs!&quot;);   
            gumballMachine.setState(gumballMachine.getSoldOutState());   
        }   
    }   

}

public class WinnerState implements State{
	GumballMachineTwo gumballMachine;   
    //下面都跟SoldState方法一样   
    public WinnerState(GumballMachineTwo gumballMachine) {   
        this.gumballMachine = gumballMachine;   
    }   
    public void insertQuarter() {   
        System.out.println(&quot;Please wait, we're already giving you a Gumball&quot;);   
    }   
    public void ejectQuarter() {   
        System.out.println(&quot;Please wait, we're already giving you a Gumball&quot;);   
    }   
    public void turnCrank() {   
        System.out.println(&quot;Turning again doesn't get you another gumball!&quot;);   
    }   
    //我们在这里发放出2颗糖果,然后进入NoQuarterState或SoldState   
    public void dispense() {   
        System.out.println(&quot;YOU'RE A WINNER! You get two gumballs for your quarter&quot;);   
        gumballMachine.releaseBall();   
        if (gumballMachine.getCount() == 0) {   
            gumballMachine.setState(gumballMachine.getSoldOutState());   
        } else {   
            gumballMachine.releaseBall();   
            if (gumballMachine.getCount() &gt; 0) {   
                gumballMachine.setState(gumballMachine.getNoQuarterState());   
            } else {   
                System.out.println(&quot;Oops, out of gumballs!&quot;);   
                gumballMachine.setState(gumballMachine.getSoldOutState());   
            }   
        }   
    }   

}
</pre><p>&nbsp;</p><p>下面是新的糖果类：</p><pre name="code" class="java">public class GumballMachineTwo {
	 //所有的状态都在这里   
    State soldOutState;   
    State noQuarterState;   
    State hasQuarterState;   
    State soldState;   
    
    State winnerState;//十次抽中一次的游戏,新的状态   
    //以及实例变量state   
    State state = soldOutState;   
    int count = 0;//记录糖果数量   
    public GumballMachineTwo(int numberGumballs) {        
        soldOutState = new SoldOutState(this);  //每一种状态也都创建一个状态实例   
        noQuarterState = new NoQuarterState(this);   
        hasQuarterState = new HasQuarterState(this);   
        soldState = new SoldState(this);   
        this.count = numberGumballs;   
        if (numberGumballs &gt; 0) {    //如果超过0颗糖果,状态设为noQuarterState   
            state = noQuarterState;   
        }    
    }   
    //委托给当前状态   
    public void insertQuarter() {   
        state.insertQuarter();   
    }   
    public void ejectQuarter() {   
        state.ejectQuarter();   
    }   
    //dispense()是一个内部动作方法,用户不可以直接要求机器发放糖果   
    public void turnCrank() {   
        state.turnCrank();   
        state.dispense();   
    }   
    //允许其他的对象将机器状态转换到不同的状态   
    void setState(State state) {   
        this.state = state;   
    }   
    //辅助方法释放出糖果,并将count实例变量值减1   
    void releaseBall() {   
        System.out.println(&quot;A gumball comes rolling out the slot...&quot;);   
        if (count != 0) {   
            count = count - 1;   
        }   
    }   
    int getCount() {   
        return count;   
    }   
    void refill(int count) {   
        this.count = count;   
        state = noQuarterState;   
    }   
    public State getState() {return state;}   
    public State getSoldOutState() {return soldOutState;}   
    public State getNoQuarterState() {return noQuarterState;}   
    public State getHasQuarterState() {return hasQuarterState;}   
    public State getSoldState() {return soldState;}   
    public State getWinnerState() {return winnerState;}   

}
</pre><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/174371#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, 21 Mar 2008 09:21:58 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/174371</link>
        <guid>http://cljspn.javaeye.com/blog/174371</guid>
      </item>
      <item>
        <title>设计模式之命令（Command）模式</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/173676" style="color:red;">http://cljspn.javaeye.com/blog/173676</a>&nbsp;
          发表时间: 2008年03月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><strong>&nbsp;&nbsp;&nbsp;&nbsp; Command定义如下：</strong> 将来自客户端的请求传入一个对象，无需了解这个请求激活的动作或有关接受这个请求的处理细节。</p><p>是不是有点迷糊。不知其说的是啥。哈哈。别着急下面听我慢慢到来。</p><p>&nbsp;</p><p>本人觉得，命令模式就是把一些具体的命令封装成一此具体的类，这此类实现同一个接口或者是抽象类。然后把这些类组织到起，然后统一来执行，完成一个具体的业务流程。</p><p>&nbsp;</p><p>它的优点是：解藉了发送者与接收者之间的联系。发送者调用一个操作，接收者接受请求执行相应的动作，说白了就是调用一个具体的类来执行相应的方法。因为使用Command模式解耦，发送者无需知道接受者任何接口。</p><p>比如说，对文件进行操作，如打开、关闭、打印。正常的操作就是用户点击&ldquo;打开&rdquo;按纽，就执行打开命令，在按纽的单击事件中写个方法就可以了。但如要应用Command模式，就要把其抽象出接口，把这三个操作封装成单独的类。也许有人要问，为什么要把简单的问题复杂化呢？。虽然在代码量上有所增加，这样做有利于代码的健壮性 可维护性 还有复用性。这是前人总结出来的经验。</p><p>&nbsp;</p><p>说了半天，如何使用呢，别说费话了，&ldquo;必需的&rdquo;。</p><p>&nbsp;</p><p>具体的Command模式代码各式各样,因为如何封装命令,不同系统,有不同的做法。</p><p>典型的Command模式需要有一个接口.接口中有一个统一的方法,这就是&quot;将命令/请求封装为对象。</p><p>&nbsp;</p><pre name="code" class="java">public interface Command {
　　public abstract void execute ( );
} 

</pre><p>&nbsp;</p><p>具体不同命令/请求代码是实现接口Command,下面有三个具体命令（打开命令、关闭命令、打印命令）</p><p>&nbsp;</p><pre name="code" class="java">public class Open implements Command {

　　public void execute( ) {
          System.out.println(&quot;打开&quot;);
　　}
} 
public class Close implements Command {

　　public void execute( ) {
          System.out.println(&quot;关闭&quot;);
　　}
}

public class Print implements Command {

　　public void execute( ) {
          System.out.println(&quot;打印&quot;);
　　}
}
</pre><p>&nbsp;</p><p>按照通常做法,我们就可以直接调用这三个Command,但是使用Command模式,我们要将他们封装起来,扔到黑盒子List里去:</p><pre name="code" class="java">public class producer{
　　public static List produceRequests() {
　　　　List queue = new ArrayList();
　　　　queue.add( new Open() );
　　　　queue.add( new Close() );
　　　　queue.add( new Print() );
　　　　return queue; 
　　}

}
</pre><p><br />这三个命令进入List中后,已经失去了其外表特征,以后再取出,也可能无法分辨出谁是Open谁是Close了,看下面客户端如何调用Command模式:</p><pre name="code" class="java">public class TestCommand {
　　public static void main(String[] args) {
　　　　
　　　　List queue = Producer.produceRequests();
　　　　for (Iterator it = queue.iterator(); it.hasNext(); )
　　　　　　
　//客户端直接调用execute方法，无需知道被调用者的其它更多类的方法名。
　　　　　　　　((Command)it.next()).execute();
　　

　　}
} 
</pre><p>&nbsp;</p><p>由此可见,调用者基本只和接口打交道,不合具体实现交互,这也体现了一个原则,面向接口编程,这样,以后增加第四个具体命令时,就不必修改调用者TestCommand中的代码了.<br /><br />理解了上面的代码的核心原理,在使用中,就应该各人有自己方法了,特别是在如何分离调用者和具体命令上,有很多实现方法,上面的代码是使用&quot;从List过一遍&quot;的做法.这种做法只是为了演示.</p>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/173676#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, 19 Mar 2008 11:19:25 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/173676</link>
        <guid>http://cljspn.javaeye.com/blog/173676</guid>
      </item>
      <item>
        <title>设计模式之策略模式(Strategy)</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/168095" style="color:red;">http://cljspn.javaeye.com/blog/168095</a>&nbsp;
          发表时间: 2008年03月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: Arial">策略模式的用意是针对一组算法或者说实现，将每一个算法（实现）封装到具有共同接口（抽象类）的独立的类中，从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。使用策略模式可以把行为和环境分割开来。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 环境类负责维持和查询行为类，各种算法则在具体策略中提供。由于算法和环境独立开来，<span style="color: #999999">算</span><span style="color: #000000">法的修改都不会影响环境和客户端。</span></span></p><p>&nbsp;</p><span style="font-family: Arial">先来看一没有用策略模式的类：</span><span style="font-family: Arial"><pre name="code" class="java">public class Output {
	public void OutputMethod(char flag) {
		switch (flag) {
		case 'A':
			System.out.println(&quot;Output flag A&quot;);
			break;
		case 'B':
			System.out.println(&quot;Output flag B&quot;);
			break;
		case 'C':
			System.out.println(&quot;Output flag C&quot;);
			break;
		default:
			break;
		}
	}
}</pre><p>&nbsp;</p><p>客户端调用：</p><pre name="code" class="java">Output output = new Output();
output.OutputMethod('B');</pre><p>策略模式由三部分实现：</p><p>A:&nbsp; <span style="font-family: Arial">抽象策略角色：<span style="font-family: Arial">策略类，通常由一个接口或者抽象类实现</span><br />B:&nbsp; 具体策略角色：<span style="font-family: Arial">包装了相关的算法和行为</span><br />C:&nbsp; 环境角色：<span style="font-family: Arial">持有一个策略类的引用，最终给客户端调用的。</span></span></p><p>&nbsp;</p><pre name="code" class="java">public interface Ioutput {
  void output();
}

public class Aoutput implements Ioutput {
     public void output() {
         System.out.println(&quot;Output flag A&quot;);
    }

}

public class Boutput implements Ioutput {
   public void output() {
      System.out.println(&quot;Output flag B&quot;);
  }

}

public class Context {
   private Ioutput output ;
   Context(Ioutput output){
       this.output = output ;
   }
   
   public void output(){
      output.output();
   }
}</pre><p>客户端调用：</p><pre name="code" class="java">Context context = new Context(new Aoutput());
context.output();
Context bcontext = new Context(new Boutput());
bcontext.output();</pre><p>&nbsp;</p><p><span style="color: #000000">策略模式优点:</span></p><p><span style="color: #000000">1.可以很方便的<span style="font-family: Arial">动态改变算法或行为</span></span></p><p><span style="color: #000000">2.<span style="font-family: Arial">避免使用多重条件转移语句</span></span></p><p><span style="color: #000000">策略模式缺点:</span></p><p><span style="font-family: Arial"><br /><span style="color: #000000">1.客户端必须知道所有的策略类，并自行决定使用哪一个策略类。<br />2.造成很多的策略类。</span></span></p></span>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/168095#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, 05 Mar 2008 12:03:13 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/168095</link>
        <guid>http://cljspn.javaeye.com/blog/168095</guid>
      </item>
      <item>
        <title>利用JS在两个窗体之间传递值。</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/164567" style="color:red;">http://cljspn.javaeye.com/blog/164567</a>&nbsp;
          发表时间: 2008年02月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          需求：<br />&nbsp;&nbsp; 在两个窗体之间传递消息。即：在父窗体处查询需要的数据。子窗体显示数据，在子窗体中选择一条需要数据，然后把其主健值回传给父窗体，后子窗体关闭。<br />注意：在子窗体处只能有一条数据被选中。<br />代码如下：<pre name="code" class="js">function check(obj,xh){
     var el = document.getElementsByTagName(&quot;input&quot;); 
     for(var i=0;i&lt;el.length;i++){
         if((el[i].type==&quot;checkbox&quot;)&amp;&amp;(el[i].name!=obj.name)){
              el[i].checked=false;
         }
     }
     window.returnValue = xh ;
     window.close() ;  
}</pre><p>&nbsp;注意：有的IE中window.close() ;&nbsp; 要结合&lt;base target=&quot;_self&quot;&gt;使用。否则关闭不了&nbsp; showModalDialog个窗体。&lt;base target=&quot;_self&quot;&gt;的存放位置为&lt;html&gt;与&lt;body&gt;之间。</p><p>&nbsp;</p><p><strong>showModalDialog和showModelessDialog数据传递技巧：</strong></p><p>现在需要在一个showModalDialog(或showModelessDialog)里读取或设置一个变量var_name</p><p>一般的传递方式：<br />　　window.showModalDialog(&quot;filename.htm&quot;,var_name)<br />&nbsp; 　//传递var_name变量<br />　&nbsp; 在showModalDialog(或showModelessDialog)读取和设置时：<br />&nbsp; 　alert(window.dialogArguments)//读取var_name变量<br />&nbsp;　window.dialogArguments=&quot;oyiboy&quot;//设置var_name变量<br />　这种方式是可以满足的，但是当你想在操作var_name同时再操作第二个变理var_id时呢？就无法再进行操作了。这就是这种传递方式的局限性。<br />　<br /><strong>以下是我建议使用的传递方式：<br /></strong>　　　window.showModalDialog(&quot;filename.htm&quot;,window)<br />　　　//不管要操作什么变量，只直传递主窗口的window对象<br />　　　在showModalDialog(或showModelessDialog)读取和设置时：<br />　　　alert(window.dialogArguments.var_name)//读取var_name变量<br />　　　window.dialogArguments.var_name=&quot;oyiboy&quot;//设置var_name变量</p><p>　　　同时我也可以操作var_id变量<br />　　　alert(window.dialogArguments.var_id)//读取var_id变量<br />　　　window.dialogArguments.var_id=&quot;001&quot;//设置var_id变量</p><p>　　　同样还可以对主窗口的任何对象进行操作，如form对象里的元素。<br />　　　window.dialogArguments.form1.index1.value=&quot;这是在设置index1元素的值&quot;</p>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/164567#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, 24 Feb 2008 13:36:28 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/164567</link>
        <guid>http://cljspn.javaeye.com/blog/164567</guid>
      </item>
      <item>
        <title>MSXML2.DOMDocument.3.0从XML中读取数据</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/164434" style="color:red;">http://cljspn.javaeye.com/blog/164434</a>&nbsp;
          发表时间: 2008年02月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>先有一个XML数据：</p><pre name="code" class="xml">&lt;?xml version=&quot;1.0&quot; ?&gt;
&lt;Order&gt;
  &lt;Account&gt;9900234&lt;/Account&gt;
  &lt;Item id=&quot;1&quot;&gt;
    &lt;SKU&gt;1234&lt;/SKU&gt;
    &lt;PricePer&gt;5.95&lt;/PricePer&gt;
    &lt;Quantity&gt;100&lt;/Quantity&gt;
    &lt;Subtotal&gt;595.00&lt;/Subtotal&gt;
    &lt;Description&gt;Super Widget Clamp&lt;/Description&gt;
  &lt;/Item&gt;
  &lt;Item id=&quot;2&quot;&gt;
    &lt;SKU&gt;6234&lt;/SKU&gt;
    &lt;PricePer&gt;22.00&lt;/PricePer&gt;
    &lt;Quantity&gt;10&lt;/Quantity&gt;
    &lt;Subtotal&gt;220.00&lt;/Subtotal&gt;
    &lt;Description&gt;Mighty Foobar Flange&lt;/Description&gt;
  &lt;/Item&gt;
  &lt;Item id=&quot;3&quot;&gt;
    &lt;SKU&gt;9982&lt;/SKU&gt;
    &lt;PricePer&gt;2.50&lt;/PricePer&gt;
    &lt;Quantity&gt;1000&lt;/Quantity&gt;
    &lt;Subtotal&gt;2500.00&lt;/Subtotal&gt;
    &lt;Description&gt;Deluxe Doohickie&lt;/Description&gt;
  &lt;/Item&gt;
  &lt;Item id=&quot;4&quot;&gt;
    &lt;SKU&gt;3256&lt;/SKU&gt;
    &lt;PricePer&gt;389.00&lt;/PricePer&gt;
    &lt;Quantity&gt;1&lt;/Quantity&gt;
    &lt;Subtotal&gt;389.00&lt;/Subtotal&gt;
    &lt;Description&gt;Muckalucket Bucket&lt;/Description&gt;
  &lt;/Item&gt;
  &lt;NumberItems&gt;1111&lt;/NumberItems&gt;
  &lt;Total&gt;3704.00&lt;/Total&gt;
  &lt;OrderDate&gt;07/07/2002&lt;/OrderDate&gt;
  &lt;OrderNumber&gt;8876&lt;/OrderNumber&gt;
&lt;/Order&gt;</pre><p>然后把Item结点的数据读出。</p><p>相关的JS函数如下：</p><pre name="code" class="js">&lt;script language=&quot;javascript&quot;&gt;
    var i = -1;
    var orderDoc = new ActiveXObject (&quot;MSXML2.DOMDocument.3.0&quot;);
    orderDoc.load(&quot;order.xml&quot;);
    var items = orderDoc.documentElement.selectNodes(&quot;/Order/Item&quot;);

    //获得结点文本
    function getNode(doc, xpath) {
      var retval = &quot;&quot;;
      var value = doc.documentElement.selectSingleNode(xpath);
      if (value) retval = value.text;
      return retval;
    }
    //下一条记录
    function getDataNext() {
      i++;
      if (i &gt; items.length - 1) i = 0;

      document.forms[0].SKU.value = getNode(orderDoc, &quot;/Order/Item[&quot; + i + &quot;]/SKU&quot;);
      document.forms[0].Price.value = getNode(orderDoc, &quot;/Order/Item[&quot; + i + &quot;]/PricePer&quot;);
      document.forms[0].Quantity.value = getNode(orderDoc, &quot;/Order/Item[&quot; + i + &quot;]/Quantity&quot;);
      document.forms[0].Total.value = getNode(orderDoc,&quot;/Order/Item[&quot; + i + &quot;]/Subtotal&quot;);
      document.forms[0].Description.value = getNode(orderDoc, &quot;/Order/Item[&quot; + i + &quot;]/Description&quot;);
    }
    //前一条记录

    function getDataPrev() {
      i--;
      if (i &lt; 0) i = items.length - 1;
      
      document.forms[0].SKU.value = getNode(orderDoc, &quot;/Order/Item[&quot; + i + &quot;]/SKU&quot;);
      document.forms[0].Price.value = getNode(orderDoc,&quot;/Order/Item[&quot; + i + &quot;]/PricePer&quot;);
      document.forms[0].Quantity.value = getNode(orderDoc, &quot;/Order/Item[&quot; + i + &quot;]/Quantity&quot;);
      document.forms[0].Total.value = getNode(orderDoc,&quot;/Order/Item[&quot;+ i + &quot;]/Subtotal&quot;);
      document.forms[0].Description.value = getNode(orderDoc, &quot;/Order/Item[&quot; + i + &quot;]/Description&quot;);
    }
&lt;/script&gt;</pre><p>下面是测试网页代码：</p><pre name="code" class="html">&lt;body onload=&quot;getDataNext()&quot;&gt;
&lt;form&gt;
  &lt;table border=&quot;0&quot;&gt;
    &lt;tr&gt;
	    &lt;td&gt;SKU&lt;/td&gt;
		&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;SKU&quot;&gt;&lt;/td&gt;
	&lt;/tr&gt;
    &lt;tr&gt;
	   &lt;td&gt;Price&lt;/td&gt;
	   &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;Price&quot;&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
	    &lt;td&gt;Quantity&lt;/td&gt;
		&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;Quantity&quot;&gt;&lt;/td&gt;
	&lt;/tr&gt;
    &lt;tr&gt;
	    &lt;td&gt;Total&lt;/td&gt;
		&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;Total&quot;&gt;&lt;/td&gt;
	&lt;/tr&gt;
    &lt;tr&gt;
	    &lt;td&gt;Description&lt;/td&gt;
		&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;Description&quot;&gt;&lt;/td&gt;
     &lt;/tr&gt;
  &lt;/table&gt;
    &lt;input type=&quot;button&quot; value=&quot;&lt;&lt;&quot; onClick=&quot;getDataPrev()&quot;&gt;
     &lt;input type=&quot;button&quot; value=&quot;&gt;&gt;&quot; onClick=&quot;getDataNext()&quot;&gt;
  &lt;/form&gt;
&lt;/body&gt;</pre><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/164434#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>Sat, 23 Feb 2008 15:13:04 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/164434</link>
        <guid>http://cljspn.javaeye.com/blog/164434</guid>
      </item>
      <item>
        <title>用JS and DOM生成表格</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/164207" style="color:red;">http://cljspn.javaeye.com/blog/164207</a>&nbsp;
          发表时间: 2008年02月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="js">&lt;script language=&quot;javascript&quot;&gt;
     function start(){
       mybody = document.getElementsByTagName  (&quot;body&quot;).item(0);
        mytable = document.createElement(&quot;TABLE&quot;);
        mytablebody = document.createElement(&quot;TBODY&quot;);
        for(j=0;j&lt;2;j++){
           mycurrent_row = document.createElement(&quot;TR&quot;);
           for(i=0;i&lt;2;i++){
               mycurrent_cell= document.createElement(&quot;TD&quot;);
              currenttext=document.createTextNode(&quot;cell is  row &quot;+j+&quot;,  column &quot;+i);
              mycurrent_cell.appendChild(currenttext);
              mycurrent_row.appendChild(mycurrent_cell);
           }
           mytablebody.appendChild(mycurrent_row);
       }
       mytable.appendChild(mytablebody);
       mybody.appendChild(mytable);
       mytable.setAttribute(&quot;border&quot;,&quot;2&quot;);
   }
  &lt;/script&gt;</pre>&nbsp;原来mybody = document.getElementsByTagName&nbsp; (&quot;body&quot;).item(0);是mybody =&nbsp;&nbsp;&nbsp;&nbsp; document.getElementsByTagName&nbsp; (&quot;body&quot;);写的，报错&ldquo;对象不支持属性或方法&rdquo;后来发现getElementsByTagName（）方法返回一个集合，所以改成代码中的写法通过。很不好找呀<br />
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/164207#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>Fri, 22 Feb 2008 14:01:02 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/164207</link>
        <guid>http://cljspn.javaeye.com/blog/164207</guid>
      </item>
      <item>
        <title>DOM和JAVASCRIPT访问页面上的元素</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/164118" style="color:red;">http://cljspn.javaeye.com/blog/164118</a>&nbsp;
          发表时间: 2008年02月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>访问方法：</p><ol><li>getElementById()：返回拥用传递给该方法的指定id的第一个对象的引用。</li><li>getElementsByName()：返回拥用传递该方法的指定name的对象集合。</li><li>getElementsByTagName()：返回拥用传递给该方法的指定tag名称的对象集合。</li></ol><p>如果在页面上有一个表格，</p><p>功能描述：获得记录数：</p><pre name="code" class="js">//要把表头去掉。
function getReorderCount(){
  var reocrders = document.getElementsByTagName(&quot;tr&quot;);
  return reocrders.length -1;
}</pre><p><span style="font-family: Courier New">也可以这样写：</span></p><p>&nbsp;</p><span style="font-family: Courier New"><pre name="code" class="js">var  table = document.getElementById(&quot;table1&quot;);
//这是表格的行数
table.rows.length;
//如查要获得数据的记录数要把表头给去掉。要减1.
</pre><p><span style="font-family: Courier New"><span style="font-family: Courier New">表格有rows与cells属性。其特点与<span style="font-family: Courier New"><span style="font-family: Courier New">getElementByTagName一样</span></span></span></span></p></span><p><span style="font-family: Courier New"><span style="font-family: Courier New">getElementByTagName</span>是文档接口（Document interface）和元素接口（Element interface）的中的方法，所以不管是根文档对象还是所有的元素对象都含有方法<span style="font-family: Courier New">getElementByTagName();</span><span style="font-family: Courier New"> </span></span></p><p><span style="font-family: Courier New">功能描述：获得表格的列数<pre name="code" class="js">function getColumnCount(){
   var reocrders = document.getElementsByTagName(&quot;tr&quot;);
    return reocrders.item(0).childNodes.length
}</pre>功能描述：获得除表头表格中元素的数据<pre name="code" class="js">function getCellData(){
   reocrders = document.getElementsByTagName(&quot;tr&quot;);
   for(j=1;j&lt;reocrders.length;j++){
       currentRow =  reocrders.item(j) ;
       cur_cells = currentRow.getElementsByTagName(&quot;td&quot;);   
       for(i=0;i&lt;cur_cells.length;i++){
            alert(cur_cells.item(i).childNodes.item(0).data);
       }
   }
}</pre>&nbsp;其中一个td单元中的数据也是一个结点对象，即文字结点</span></p>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/164118#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, 22 Feb 2008 10:51:14 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/164118</link>
        <guid>http://cljspn.javaeye.com/blog/164118</guid>
      </item>
      <item>
        <title>设计模式之－－动态代理</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/162760" style="color:red;">http://cljspn.javaeye.com/blog/162760</a>&nbsp;
          发表时间: 2008年02月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp; 动态代理类是一个在运行时由开发人员所指定的一列接口的实现。动态代理接口是一种由代理类实现的接口，并且是一个java.lang.reflect.Proxy类的实例。每一个代理实例都与一个调用处理器对象相联，这个调用处理器实现了java.lang.reflect.InvocationHandler接口。在代理实例上的一个方法调用是通过其中之一的代理接口被转发到与这个代理实例相联的调用处理的invoke方法上。一个java.lang.reflect.Method对象会决定那一个方法会被调用，一个类型为java.lang.Object的数组包含调用的参数。调用处理器会适当地解码方法的调用（encoded method invocation as appropriate），并且它（调用处理器）的返回结果被作为在代理实例上方法调用返回的结果而返回。</p><p>例如，我们已有和装饰器模式中一文中一样的接口IMyBusinessObject和业务类MyBusinessObject。现在当我们使用动态代理时，我必须编写一个调用处理器，因为java.lang.reflect.Proxy类将会用到它。</p><p>MyDebugInvocationHandler类看起来像下面那样：</p><pre name="code" class="java">public class MyDebugInvocationHandler implements InvocationHandler {
    private Object target ;
    
	public void setTarget(Object target) {
		this.target = target;
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
	    System.out.println(&quot;Going to execute method :&quot;+method.getName());
	    Object  retObject = method.invoke(target, args);
	    System.out.println(&quot;After execute method :&quot;+method.getName());
		return retObject;
	}

}</pre><p>&nbsp;在上面的例子中，invoke ()方法是很重要的，它是被java.lang.reflect.Proxy类所调用的。在这个方法里面，我们执行了一些额外的处理，然后转至真正的目标对象的处理（在这个例子中，是实例MyBusinessObject）。<br />因此我们的客户端应作如下编码：</p><pre name="code" class="java">IMyBusinessObject bo = new MyBusinessObject();
		MyDebugInvocationHandler aMyDebugInvocationHandler = new MyDebugInvocationHandler();
		aMyDebugInvocationHandler.setTarget(bo);
		IMyBusinessObject proxyObject = (IMyBusinessObject) Proxy
				.newProxyInstance(IMyBusinessObject.class.getClassLoader(),
						new Class[] { IMyBusinessObject.class },
						aMyDebugInvocationHandler);
 System.out.println(proxyObject.doExecute(&quot;Hello World&quot;)); 
</pre><p>&nbsp;</p><p>&nbsp;</p><p>输出结果：</p><pre name="code" class="java">Going to execute method :doExecute 
Here in MyBusinessObject doExecute: input :Hello World 
After execute method :doExecute 
Hello World </pre><p>&nbsp;在上面的代码中，我分别创建一个MyBusinessObject实例和一个MyDebugInvocationHandler实例。我们在MyDebugInvocationHandler中设定目标对象为MyBusinessObject。因此当invoke()方法被调用时，它能够把调求发向正确的目标。然后，我们使用java.lang.reflect.Proxy去创建一个IMyBusinessObject接口的代理对象。既然invoke()方法会处理java.lang.reflect.Mehtod类的生成并且其中没有特定的业务接口的方法，通常这些特定的业务接口的方法在每一个业务接口分别编写个业调用处理器是必须的,知道这一点是很重要的。还有，如果我们想实现一些横跨所有业务接口的横切面(cross-cutting aspect)，我们不必实现在业务接口中定义的所有业务方法。例如，为了在我们的业务方法中实现安全性，我们仅仅只须在一个地方编写一个方法去实现安全逻辑，这个安全方法我们将以通用的方法编写。</p><p>如果我们想在链中增加多个处理器，我们必须创建另一个调用处理器。然后在新定义的处理器中的setTarget()中我们把它设定为链中的前一个代理对象，而不是设定为MyBusinessObject对象。另一个调用处理器代码如下：</p><pre name="code" class="java">public class MyAnotherInvocationHandler implements InvocationHandler { 
      private Object target; 

      public void setTarget(Object target) { 
            this.target = target; 
      } 

      public Object invoke(Object proxy, Method method, Object[] args) 
                  throws Throwable { 
            System.out 
                        .println(&quot;AnotherConcreteDecorator: Going to execute method : doExecute&quot;); 
            if (method.getName().equals(&quot;doExecute&quot;) &amp;&amp; args != null 
                        &amp;&amp; args.length &gt;= 1) { 
                  if (args[0] instanceof String) { 
                        args[0] = args[0] + &quot; Modified by MyAnotherInterceptor&quot;; 
                  } 
            } 
            Object temp = method.invoke(target, args); 
            System.out 
                        .println(&quot;AnotherConcreteDecorator: After execute method : doExecute&quot;); 
            return temp; 
      } 

} 
</pre><p>&nbsp;</p><p>客户端代码如下：</p><pre name="code" class="java">IMyBusinessObject bo = new MyBusinessObject();
		MyDebugInvocationHandler aMyDebugInvocationHandler = new MyDebugInvocationHandler();
		aMyDebugInvocationHandler.setTarget(bo);
		IMyBusinessObject proxyObject = (IMyBusinessObject) Proxy
				.newProxyInstance(IMyBusinessObject.class.getClassLoader(),
						new Class[] { IMyBusinessObject.class },
						aMyDebugInvocationHandler);

		MyAnotherInvocationHandler aMyAnotherInvocationHandler = new MyAnotherInvocationHandler();
		aMyAnotherInvocationHandler.setTarget(proxyObject);
		IMyBusinessObject nextProxyObject = (IMyBusinessObject) Proxy
				.newProxyInstance(IMyBusinessObject.class.getClassLoader(),
						new Class[] {IMyBusinessObject.class},
						aMyAnotherInvocationHandler);
		
		System.out.println(nextProxyObject.doExecute(&quot;Hello World&quot;));
</pre><p>&nbsp;</p><p>输出结果：</p><pre name="code" class="java">AnotherConcreteDecorator: Going to execute method : doExecute
Going to execute method :doExecute
Here in MyBusinessObject doExecute: input :Hello World Modified by MyAnotherInterceptor
After execute method :doExecute
AnotherConcreteDecorator: After execute method : doExecute
Hello World Modified by MyAnotherInterceptor</pre><p><br />从上面的例子我们可以看出，用动态代理比静态装饰链用更少的代码为业务对象增加额外的行为。但是，如果我们像上面一样使用动态代理仍然有一些问题：当创建和链化动态代理时你仍然必须编写大量的代码，并且你还必须处理不如普通的对象创建或工厂方法的对象创建那么友善的代理接口API，还有，当我们需要代理我们的业务对象时，在多个位置重复一些代码并不是一个好主意。</p><p>下一篇博客将试图去解决这些问题。我将会编写一个暴露简单API的通用代理工厂（在其中隐藏代理对象的创建和链化），但仍可提供动态代理的扩展性。</p>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/162760#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, 17 Feb 2008 12:01:33 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/162760</link>
        <guid>http://cljspn.javaeye.com/blog/162760</guid>
      </item>
      <item>
        <title>设计模式之－－进行硬编码的静态装饰器模式和装饰器模式链化</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/162758" style="color:red;">http://cljspn.javaeye.com/blog/162758</a>&nbsp;
          发表时间: 2008年02月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>动态代理的背后思想是在一个对象的周围插入动态的行为但不改变对象的已有代码和接口。装饰器模式提供一种不必改变对象代码就可以装饰一个对象（改变它的行为）并向其增加横切面的方法。现在就用静态的装饰来实现具体的业务功能 </p><p>首先有一个简单业务接口：</p><pre name="code" class="java">public interface IMyBusinessObject { 
      public String doExecute(String in); 
} </pre><p>&nbsp;这个接口有一个业务对象类的实现。</p><pre name="code" class="java">public class MyBusinessObject implements IMyBusinessObject { 
public String doExecute(String in) { 
System.out.println(&quot;Here in MyBusinessObject doExecute: input :&quot; + in); 
return in; 
} 
} </pre><p>&nbsp;</p><p>现在想要在这个业对象类的方法doExecute之前与之后增加一些行为，装饰器模式使我们十分容易增加这个功能。现在定义一个抽象类，这个抽象类实现上面的业务接口。</p><pre name="code" class="java">public abstract class ADecorator implements IMyBusinessObject { 
      protected IMyBusinessObject target; 
  
      public void setTarget(IMyBusinessObject target) { 
            this.target = target; 
      } 
  
public ADecorator(){}; 
  
      public ADecorator(IMyBusinessObject target_) { 
            setTarget(target_); 
      } 
} 
</pre><p>&nbsp;</p><p>为什么要把设置业务对象的方法放到抽象类中呢，这也是重构的一种方法。就是把子类中设置业务对象的方法提到父类中。术语为方法上移。&nbsp;现在定义一个从ADedorator扩展来的具体类DebugConcreteDecorator，目的是在我们业务对象被调用之前和之后加入一些调试信息：</p><pre name="code" class="java">public class DebugConcreteDecorator extends ADecorator { 
  
  
      public DebugConcreteDecorator(IMyBusinessObject target_) { 
            super(target_); 
      } 
  
      public String doExecute(String in) { 
            System.out 
                        .println(&quot;DebugConcreteDecorator: before method : doExecute &quot;); 
            String ret = target.doExecute(in); 
            System.out.println(&quot;DebugConcreteDecorator: after method : doExecute &quot;); 
            return ret; 
      } 
} 
</pre><p>&nbsp;</p><p>现在在客户端，我们调用业务对象：</p><pre name="code" class="java">IMyBusinessObject aIMyBusinessObject = new MyBusinessObject(); 
IMyBusinessObject wrappedObject = new DebugConcreteDecorator( 
aIMyBusinessObject); 
wrappedObject.doExecute(&quot;Hello World&quot;); </pre><p>&nbsp;输出结果如下：</p><pre name="code" class="java">DebugConcreteDecorator: before method : doExecute 
Here in MyBusinessObject doExecute: input :Hello World 
DebugConcreteDecorator: after method : doExecute </pre><p>实际的业务方法调用之前链化装饰器----调用一个装饰器后再调用另一个装饰器。让我们再定义另一个装饰器去展示这个方法：</p><pre name="code" class="java">public class AnotherConcreteDecorator extends ADecorator { 
  
      public AnotherConcreteDecorator( 
                  IMyBusinessObject target_) { 
            super(target_); 
      } 
  
      public String doExecute(String in) { 
            System.out 
                        .println(&quot;AnotherConcreteDecorator: Going to execute method : doExecute&quot;); 
            in = in + &quot; Modified by AnotherConcreteDecorator&quot;; 
            String ret = target.doExecute(in); 
            System.out 
                        .println(&quot;AnotherConcreteDecorator: After execute method : doExecute&quot;); 
            return ret; 
      } 
  
} 
</pre><p>&nbsp;</p><p>上面的代码片段通过在业务方法输入的字符参数后增加(&quot; Modified by AnotherConcreteDecorator&quot;)字符串，从而实现对其进行了修改。如果我们想链化装饰器，在客户端，我们可以编写如下的代码：</p><p>&nbsp;</p><pre name="code" class="java">IMyBusinessObject aIMyBusinessObject = new MyBusinessObject(); 
IMyBusinessObject wrappedObject = new AnotherConcreteDecorator( 
            new DebugConcreteDecorator(aIMyBusinessObject)); 
wrappedObject.doExecute(&quot;Hello World&quot;); </pre><p>&nbsp;</p><p>在上面的代码片段中，我在创建一个DebugConcreteDecorator实例时，向其传递了一个实际的业务对象实例。然后用一个刚才定义的notherConcreteDecorator实例去包装DebugConcreteDecorator实例。AntherConcreteDecorator首先在输入参数后增加字符串对其进行修改，然后调用DebugConcreteDecorator实例的doExecute()方法。这时，DebugConcreteDecorator会记录doExectute()方法的输出的条目，然后调用doExecute()去调用实际业务对象的doExecute()方法。<br />它的返回路径以相反的顺序。在从实际的业务对象(MyBusinessObject)doExecute()方法返回之后，DebugConcreteDecorator余下代码将被执行。于是，调用返回至AnotherConcreteDecorator实例并执行余下的部份代码。</p><p>输出结果如下：</p><pre name="code" class="java">AnotherConcreteDecorator: Going to execute method : doExecute 
DebugConcreteDecorator: before method : doExecute 
Here in MyBusinessObject doExecute: input :Hello World Modified by AnotherConcreteDecorator 
DebugConcreteDecorator: after method : doExecute 
AnotherConcreteDecorator: After execute method : doExecute </pre><p>&nbsp;</p><p>静态装饰器有一个问题：不知大家注意到没有DebugConcreteDecorator 或 AnotherConcreteDecorator中doExecute()方法。它对目标对象doExecute()方法的调用进行了硬编码。并且，如果我们在IMyBusinessObject接口中定义另一个方法，我们必须改写所有装饰器并提供这个方法的实现。于是，在实践中，我们可能会因有许多装饰器和在每个装饰器中有大量的代码而止步。</p><p>下一篇博客用一个动态代理可以帮助我们去掉这些硬编码，此外，我们不必在每个装饰器去实现和改写业务接口中的每个方法。</p>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/162758#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, 17 Feb 2008 11:33:10 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/162758</link>
        <guid>http://cljspn.javaeye.com/blog/162758</guid>
      </item>
      <item>
        <title>树型数据结构SQL语句的写法</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/155977" style="color:red;">http://cljspn.javaeye.com/blog/155977</a>&nbsp;
          发表时间: 2008年01月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">&nbsp;</pre><p>&nbsp;在一个关系数据库中，可以表现分等级的信息。</p><p>建立的表结构如下： </p><pre name="code" class="java">CREATE TABLE employee (
emp_id          NUMBER (4) CONSTRAINT emp_pk PRIMARY KEY,
fname           VARCHAR2 (15) NOT NULL, 
lname           VARCHAR2 (15) NOT NULL, 
dept_id         NUMBER (2) NOT NULL,
manager_emp_id  NUMBER (4) CONSTRAINT emp_fk REFERENCES employee(emp_id),
salary          NUMBER (7,2) NOT NULL,
hire_date       DATE NOT NULL, 
job_id          NUMBER (3)
);
</pre><p>&nbsp;</p><p>如果manager_emp_id&nbsp;字段为空则表明这条记录为根结点。</p><p>简单的分级查询：</p><ol><li>找出根结点，执行如下语句：<pre name="code" class="java">SELECT emp_id, lname, dept_id, manager_emp_id, salary, hire_date 
FROM employee 
WHERE manager_emp_id IS NULL;
</pre>&nbsp;</li><li>找出结点的父结点，本例中就是显示每个雇员的经理姓名，执行如下语句：<pre name="code" class="java">SELECT e.lname &quot;Employee&quot;, m.lname &quot;Manager&quot; 
FROM employee e, employee m 
WHERE e.manager_emp_id = m.emp_id;
</pre>&nbsp;</li><li>找出所有的页节点，本例中就是找出所有的普通雇员，使用如下语句：<pre name="code" class="java">SELECT emp_id, lname, dept_id, manager_emp_id, salary, hire_date 
FROM employee e
WHERE emp_id NOT IN 
(SELECT manager_emp_id FROM employee 
WHERE manager_emp_id IS NOT NULL);</pre></li><li><pre name="code" class="java">能完成同样功能的语句如下：</pre></li><li><pre name="code" class="java"><strong>&nbsp;&nbsp; SELECT emp_id, lname, dept_id, manager_emp_id, salary, hire_date 
</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>FROM employee e</strong>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>WHERE NOT EXISTS </strong>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>(SELECT emp_id FROM employee e1 WHERE e.emp_id = e1.manager_emp_id);</strong>
</pre>&nbsp;</li></ol><p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong></p><p><strong>复杂的查询：oralce提供对于Ansi Sql的一些扩展。</strong></p><p><strong>start with........connect by 子句</strong></p><p><strong>proir 操作符</strong></p><p><strong>level伪列</strong></p><p><strong>语法如下：</strong></p><p><strong>start with connection1 connect by connection2</strong></p><p><strong>start with connection1 指定根元素。能满足connection1认为是根元素。它可以包函子查询。</strong></p><p><strong>connect by connection2指定父行与子行的关系，connection2必须包函prior操作符，用来确定父行里的列，connection2不能包函子查询。</strong></p><ol><li><strong>查找父结点与其子结点的结果，使用如下语句：<pre name="code" class="java">SELECT lname, emp_id, manager_emp_id
FROM employee
START WITH manager_emp_id IS NULL
CONNECT BY PRIOR emp_id = manager_emp_id</pre>&nbsp;</strong></li><li>level伪列--返回每行属于哪一层，使用如下语句：<pre name="code" class="java">SELECT level, lname, emp_id, manager_emp_id
            FROM employee
            START WITH manager_emp_id IS NULL
            CONNECT BY manager_emp_id = PRIOR emp_id;
</pre>&nbsp;</li><li>如何检查员工a是否可以管理员工b，由于a可能不是b的主管经理，所以我们不能直接通过manager_emp_id来判断，可以使用如下语句：<pre name="code" class="java">SELECT emp_id, lname, dept_id, manager_emp_id, salary, hire_date 
            FROM employee
            WHERE lname = 'SMITH'
            START WITH lname = 'JONES'
            CONNECT BY manager_emp_id = PRIOR emp_id</pre>&nbsp;</li><li>列出员工及他管理的员工的工资总数：<pre name="code" class="java">SELECT t2.lname, t2.salary,
            (SELECT SUM(t1.salary) FROM employee t1
            START WITH t1.lname = t2.lname
            CONNECT BY t1.manager_emp_id = PRIOR t1.emp_id) sum_salary
            FROM employee t2;
</pre>&nbsp;</li></ol><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/155977#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, 15 Jan 2008 12:40:57 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/155977</link>
        <guid>http://cljspn.javaeye.com/blog/155977</guid>
      </item>
      <item>
        <title>另人无奈的SOA</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/155110" style="color:red;">http://cljspn.javaeye.com/blog/155110</a>&nbsp;
          发表时间: 2008年01月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          现在漫天飞的SOA真是让人无奈。面向服务框架，公司现在正在做这个东东，基于sca与sdo的，我现在看相关的资料，看的一头雾水，不知道从何处下手。那位能说一下。
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/155110#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>Fri, 11 Jan 2008 15:55:30 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/155110</link>
        <guid>http://cljspn.javaeye.com/blog/155110</guid>
      </item>
      <item>
        <title>应用applet的个人经验</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/151104" style="color:red;">http://cljspn.javaeye.com/blog/151104</a>&nbsp;
          发表时间: 2007年12月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这些想法只是个人在做工程中遇到的，也是个人的想法，如不有对之处请各位网友指正。如果再遇到还要对此文进行修改。<br />1、在web中applet类不能放到WEB-INF目录下。
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/151104#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>Thu, 27 Dec 2007 08:49:25 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/151104</link>
        <guid>http://cljspn.javaeye.com/blog/151104</guid>
      </item>
      <item>
        <title>CAS入门配置</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/145873" style="color:red;">http://cljspn.javaeye.com/blog/145873</a>&nbsp;
          发表时间: 2007年12月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          环境：Windows XP + JDK 1.5 + Tomcat 5.0<br /><strong>1.1</strong>第一步： 生成服务器端密钥并保存到密钥库文件中，应用JDK命令如下（下面的命令不再说　　　　　出处）<br />　　　　<br />keytool　-genkey -alias tomcat -keyalg RSA –keystore keystore.jks<br /><br />注解：-alias 自定义别名，可以随便起名，这里取tomcat<br />     -keyalg 加密算法，主要两种方式：RSA采用MD5加RSA算法加密密钥，DSA 采用SH　　　　　　　　A1加DSA算法加密密钥，此处采用RSA；<br />　　　-keystore 密钥库文件。<br />按照提示填写相应的信息，但是系统提示“您的名字与姓氏时是什么”你应写上你的IP地址，这样配置客户端时就可以异步访问了。<br /><br />第二步：把密钥文件导出成服务端证书<br />keytool -export -file myserver.cer -alias tomcat -keystore keystore.jks<br /><br />由keystore.jks文件中的tomcat别名项导出myserver.cert服务端证书。当系统提示输入密码时，输入第一步没的密码。<br /><br />第三步： 将服务端证书导入JVM信任库中。<br />keytool -import -keystore %JAVA_HOME%/jre/lib/security/cacerts -file myserver.cer -alias tomcat<br /><br />将服务端证书myserver.cert以别名tomcat导入JVM的信任库中，JVM信任库文件cacerts的默认密码为<u>changeit</u><br /><br />如果想观看信任库中的证书可以写如下命令：<br />keytool -list -v -keystore %JAVA_HOME%/jre/lib/security/cacerts >d:\aa.txt<br /><br />">" 把内容输出到哪个目录下，本例子输出到D盘的aa.txt文件中。<br /><strong>1.2</strong>部署CAS服务器<br />下载cas-server-3.1.1，把cas-server-3.1.1\modules下的cas-server-webapp-3.1.1.war改成cas.war把其放到tomcat下的Webapp下。<br /><strong>1.3</strong>在应用中加入Yale Java Client配置<br />  (1)把在Yale Java Client解压目录中找到cas-client-java-2.1.1\dis\casclient.　jar，将其COPY到应用中的WEB-INF/lib包下。<br />(2)在应用部署描述文件Web.xml中加入<br />&lt;filter><br />	&lt;filter-name>CASFilter&lt;/filter-name><br />	&lt;filter-class>edu.yale.its.tp.cas.client.filter.CASFilter&lt;/filter-class><br />       &lt;init-param><br />            &lt;param-name>edu.yale.its.tp.cas.client.filter.loginUrl&lt;/param-name><br />            &lt;param-value>https://172.10.0.156:8443/cas/login&lt;/param-value><br />		&lt;!--这里的server是服务端的IP--><br />       &lt;/init-param><br />       &lt;init-param><br />            &lt;param-name>edu.yale.its.tp.cas.client.filter.validateUrl&lt;/param-name><br />            &lt;param-value>https://172.10.0.156:8443/cas/proxyValidate&lt;/param-value><br />	   &lt;!--这里的serName是服务端的主机名，而且必须是，我们同样可以用服务端的IP。--><br />       &lt;/init-param><br />       &lt;init-param><br />           &lt;param-name>edu.yale.its.tp.cas.client.filter.serverName&lt;/param-name><br />           &lt;param-value>172.10.0.156:8080&lt;/param-value><br />	   &lt;!--client:port就是需要CAS需要拦截的地址和端口，一般就是这个TOMCAT所启动的IP和port--><br />       &lt;/init-param><br />&lt;/filter><br />&lt;filter-mapping><br />       &lt;filter-name>CASFilter&lt;/filter-name><br />       &lt;url-pattern>/servlet/*&lt;/url-pattern><br />    &lt;!--这里的设置是针对servlets-examples的，针对jsp-examples设置为/*--><br />&lt;/filter-mapping><br />参数解释：<br />edu.yale.its.tp.cas.client.filter.loginUrl 用户未登录情况下，访问应用系统的受保护资源时将会跳转到的登录页面URL，这里的值即是对应于部署的Yale CAS Server的登录页。<br />edu.yale.its.tp.cas.client.filter.validateUrl 用来校验ST(Service Ticket)。<br />edu.yale.its.tp.cas.client.filter.serverName    客户端的访问时的主机地址。<br /><br /><strong>1.4 </strong> 启动Tomcat，当访问客户端受保护资源时，CASFilter将访问重定向到CAS Server进行登录，输入用户名和密码（用户名和密码相同即可）。若登录成功，CAS Server 将访问又重定向回原客户端。
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/145873#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, 04 Dec 2007 14:42:32 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/145873</link>
        <guid>http://cljspn.javaeye.com/blog/145873</guid>
      </item>
      <item>
        <title>观察者模式的应用</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/143521" style="color:red;">http://cljspn.javaeye.com/blog/143521</a>&nbsp;
          发表时间: 2007年11月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>这上一周项目组想做一个权限的东东，通过用户的的权限，看能不能执行某个业务方法，然后我模拟了一个环境。今天上班写出来与网友分享：</p>
<p>先有两个业务类</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;BusinessA&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;a()&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">&quot;println&nbsp;A&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>} &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;BusinessB&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;b()&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">&quot;println&nbsp;B&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>还要有被观察的对象类</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;UserObersered&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Observable&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;codeChange(Object&nbsp;obj)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setChanged(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;user&nbsp;=&nbsp;(User)obj&nbsp;; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;notifyObservers(user.getMarkcode()); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
还要有一个业务方法实现类，这个类是通过上面两个业务类完成一个具体的业务。
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Service&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Observer{ &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;List&lt;String&gt;&nbsp;list&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ArrayList&lt;String&gt;(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;businessMethod()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">&quot;start&nbsp;service&nbsp;&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(list.contains(</span><span class="string">&quot;1&quot;</span><span>))&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;BusinessA.a(); </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">throw</span><span>&nbsp;</span><span class="keyword">new</span><span>&nbsp;Exception(</span><span class="string">&quot;您没有这个权限访问此方法.&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">else</span><span>&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BusinessB.b(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">&quot;end&nbsp;service&nbsp;&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;update(Observable&nbsp;arg0,&nbsp;Object&nbsp;arg1)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(arg1&nbsp;</span><span class="keyword">instanceof</span><span>&nbsp;String[])&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>&nbsp;(</span><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;((String[])&nbsp;arg1).length&nbsp;-&nbsp;</span><span class="number">1</span><span>;&nbsp;i&nbsp;&gt;=&nbsp;</span><span class="number">0</span><span>;&nbsp;i--)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add(((String[])&nbsp;arg1)[i]); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;businessMethod(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
做好这此这后做一下测试：
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>UserObersered&nbsp;userOber&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;UserObersered(); &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Service&nbsp;service&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Service(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userOber.addObserver(service); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;user&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;User(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;markcode&nbsp;=&nbsp;{</span><span class="string">&quot;1&quot;</span><span>,</span><span class="string">&quot;2&quot;</span><span>}; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.setMarkcode(markcode); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userOber.codeChange(user);&nbsp;&nbsp;</span></li>
</ol>
</div>
对markcode进行修改就能看到具体的效果。
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/143521#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, 26 Nov 2007 10:15:50 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/143521</link>
        <guid>http://cljspn.javaeye.com/blog/143521</guid>
      </item>
      <item>
        <title>内因决定一切</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/142603" style="color:red;">http://cljspn.javaeye.com/blog/142603</a>&nbsp;
          发表时间: 2007年11月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          真正的强盛，来自对力量的约束。真正的勇敢，来自对自我的控制
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/142603#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, 22 Nov 2007 11:34:07 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/142603</link>
        <guid>http://cljspn.javaeye.com/blog/142603</guid>
      </item>
      <item>
        <title>看李嘉诚新闻随心所想</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/142203" style="color:red;">http://cljspn.javaeye.com/blog/142203</a>&nbsp;
          发表时间: 2007年11月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>性格才是命运的决定因素。</p>
<p>在人生的不同阶段要不停的反思自问：&ldquo;我有什么心愿？我有宏伟的梦想，我懂不懂得什么是节制的热情？我有拼战命运的决心，我有没有面对恐惧的勇气？我有信息有机会，有没有实用智慧的心思？</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/142203#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, 21 Nov 2007 08:41:00 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/142203</link>
        <guid>http://cljspn.javaeye.com/blog/142203</guid>
      </item>
      <item>
        <title>设计模式之Bridge模式</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/138051" style="color:red;">http://cljspn.javaeye.com/blog/138051</a>&nbsp;
          发表时间: 2007年11月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这几天闲着没事，看一下Bridge模式。它是实现<span style="color: #ff0000"><strong>对象</strong></span>与<span style="color: #ff0000"><strong>行为</strong></span>分离的。做一下小例子与大家分享：<img src="../../../javascripts/fckeditor/editor/images/smiley/msn/wink_smile.gif" alt="" />，希望能与大家交流。</p><p>现定义一个对数据对象操作的接口：</p><div class="code_title">java 代码</div><div class="dp-highlighter"><ol class="dp-j"><li class="alt"><span><span class="keyword">package</span><span>&nbsp;org.mvc.webtier; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">interface</span><span>&nbsp;Operator&nbsp;{ &nbsp;&nbsp;</span></li><li><span>&nbsp;String&nbsp;work(String&nbsp;arg); &nbsp;&nbsp;</span></li><li class="alt"><span>} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li></ol></div>实现上边的这个接口： <div class="code_title">java 代码</div><div class="dp-highlighter"><ol class="dp-j"><li class="alt"><span><span class="keyword">package</span><span>&nbsp;org.mvc.webtier; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Insert&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Operator{ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;work(String&nbsp;arg)&nbsp;{ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span><span class="comment">//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub </span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="string">&quot;insert&nbsp;&quot;</span><span>+arg; &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>}</span><span class="keyword">package</span><span>&nbsp;org.mvc.webtier; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Update&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Operator&nbsp;{ &nbsp;&nbsp;</span></li><li><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;work(String&nbsp;arg)&nbsp;{ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="comment">//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub </span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="string">&quot;update&nbsp;&quot;</span><span>&nbsp;+&nbsp;arg; &nbsp;&nbsp;</span></li><li><span>&nbsp;} &nbsp;&nbsp;</span></li><li class="alt"><span>} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li></ol></div><p>定义数据对象的抽象类：</p><div class="code_title">java 代码</div><div class="dp-highlighter"><ol class="dp-j"><li class="alt"><span><span class="keyword">package</span><span>&nbsp;org.mvc.webtier; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Table&nbsp;{ &nbsp;&nbsp;</span></li><li><span>&nbsp;</span><span class="keyword">protected</span><span>&nbsp;Operator&nbsp;impl&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;work(); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;Operator&nbsp;getImpl()&nbsp;{ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;impl; &nbsp;&nbsp;</span></li><li><span>&nbsp;} &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setImpl(Operator&nbsp;impl)&nbsp;{ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">this</span><span>.impl&nbsp;=&nbsp;impl; &nbsp;&nbsp;</span></li><li><span>&nbsp;} &nbsp;&nbsp;</span></li><li class="alt"><span>} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li></ol></div><p>具体的数据对象继承上面的这个抽象类：</p><p>&nbsp;</p><div class="code_title">java 代码</div><div class="dp-highlighter"><ol class="dp-j"><li class="alt"><span><span class="keyword">package</span><span>&nbsp;org.mvc.webtier; &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Table1&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Table{ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;</span><span class="annotation">@Override</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;work()&nbsp;{ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="comment">//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub </span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;System.out.println(</span><span class="keyword">this</span><span>.impl.work(</span><span class="string">&quot;Table1&quot;</span><span>)); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">package</span><span>&nbsp;org.mvc.webtier; &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Table2&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Table{ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;</span><span class="annotation">@Override</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;work()&nbsp;{ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="comment">//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub </span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;System.out.println(</span><span class="keyword">this</span><span>.impl.work(</span><span class="string">&quot;Table2&quot;</span><span>)); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>} &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li></ol></div><p>根据具体的业务就可以对具体的数据对象进行操作了。</p><div class="code_title">java 代码</div><div class="dp-highlighter"><ol class="dp-j"><li class="alt"><span><span>Table&nbsp;tbl1&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Table1(); &nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;tbl1.setImpl(</span><span class="keyword">new</span><span>&nbsp;Insert()); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;tbl1.work(); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;tbl1.setImpl(</span><span class="keyword">new</span><span>&nbsp;Update()); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;tbl1.work(); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li><span>Table&nbsp;tbl2&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Table2(); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;tbl2.setImpl(</span><span class="keyword">new</span><span>&nbsp;Update()); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;tbl2.work(); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;tbl2.setImpl(</span><span class="keyword">new</span><span>&nbsp;Insert()); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;tbl2.work(); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li></ol></div><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://cljspn.javaeye.com/blog/138051#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, 05 Nov 2007 13:29:20 +0800</pubDate>
        <link>http://cljspn.javaeye.com/blog/138051</link>
        <guid>http://cljspn.javaeye.com/blog/138051</guid>
      </item>
      <item>
        <title>如何解决自定义PropertyEditor问题</title>
        <author>cljspn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cljspn.javaeye.com">cljspn</a>&nbsp;
          链接：<a href="http://cljspn.javaeye.com/blog/136702" style="color:red;">http://cljspn.javaeye.com/blog/136702</a>&nbsp;
          发表时间: 2007年10月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>今天做了了一个自定义PropertyEditor出现问题，字符串解析错误。下面我把相应的类与自定义的PropertyEditor写出，希望有人帮我解决一下：</p>
<p>&nbsp;</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;org.beans.beanwrapper; &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Address&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;String&nbsp;street; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;String&nbsp;doorNum; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;String&nbsp;postCode; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;getStreet()&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;street; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setStreet(String&nbsp;street)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.street&nbsp;=&nbsp;street; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;getDoorNum()&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;doorNum; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setDoorNum(String&nbsp;doorNum)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.doorNum&nbsp;=&nbsp;doorNum; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;getPostCode()&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;postCode; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setPostCode(String&nbsp;postCode)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.postCode&nbsp;=&nbsp;postCode; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>} &nbsp;&nbsp;</span></li>
</ol>
</div>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;org.beans.beanwrapper; &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Person&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;String&nbsp;name; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;Address&nbsp;address; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;getName()&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;name; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setName(String&nbsp;name)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.name&nbsp;=&nbsp;name; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;Address&nbsp;getAddress()&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;address; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setAddress(Address&nbsp;address)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.address&nbsp;=&nbsp;address; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>} &nbsp;&nbsp;</span></li>
</ol>
</div>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;org.beans.beanwrapper; &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;java.beans.PropertyEditorSupport; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;org.springframework.util.StringUtils; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;AddressProptertyEditor&nbsp;</span><span class="keyword">extends</span><span>&nbsp;PropertyEditorSupport&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setAsTest(String&nbsp;text)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;支持的格式为&nbsp;streeValue,doorNumValue,postCode </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">&quot;使用自己的编辑器。&quot;</span><span>);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(text&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;||&nbsp;!StringUtils.hasText(text))&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">throw</span><span>&nbsp;</span><span class="keyword">new</span><span>&nbsp;IllegalArgumentException(</span><span class="string">&quot;老大，不能为空啊！&quot;</span><span>);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">else</span><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;strArr&nbsp;=&nbsp;StringUtils.tokenizeToStringArray(text,</span><span class="string">&quot;,&quot;</span><span>);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Address&nbsp;add&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Address();&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add.setStreet(strArr[</span><span class="number">0</span><span>]);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add.setDoorNum(strArr[</span><span class="number">1</span><span>]);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add.setPostCode(strArr[</span><span class="number">2</span><span>]);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setValue(add);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>} &nbsp;&nbsp;</span></li>
</ol>
</div>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;org.jms.beans.test; &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;junit.framework.TestCase; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;org.springframework.context.ApplicationContext; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">import</span><span>&nbsp;org.springframework.context.support.ClassPathXmlApplicationContext; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;org.beans.beanwrapper.*; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;BeanWrapperTest&nbsp;</span><span class="keyword">extends</span><span>&nbsp;TestCase&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;testWrapper()&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext&nbsp;context&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ClassPathXmlApplicationContext( &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="string">&quot;classpath:resource/applicationContext.xml&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Person&nbsp;person&nbsp;=&nbsp;(Person)&nbsp;context.getBean(</span><span class="string">&quot;person&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(person.getAddress()); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>} &nbsp;&nbsp;</span></li>
</ol>
</div>
<p>自定义PropertyEditor注册配置文件如下</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">&quot;customEditorConfigurer&quot;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">&quot;org.springframework.beans.factory.config.CustomEditorConfigurer&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;customEditors&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">map</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">entry</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">&quot;org.beans.beanwrapper.Address&quot;</span><span class="tag">&gt;</span><span class="comments">&lt;!--&nbsp;属性类型&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">&quot;org.beans.beanwrapper.AddressProptertyEditor&quot;</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--对应Address的编辑器&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">entry</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">map</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">&quot;person&quot;</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">&quot;org.beans.beanwrapper.Person&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;name&quot;</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">&quot;Tom&quot;</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;address&quot;</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">&quot;朝阳区,Soho&nbsp;1601,010101&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>出现问题的代码如下：</p>
<div class="code_title">ruby 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-rb">
    <li class="alt"><span><span>org.springframework.beans.factory.BeanCreationException:&nbsp;Error&nbsp;creating&nbsp;bean&nbsp;with&nbsp;name&nbsp;'person'&nbsp;</span><span class="keyword">defined</span><span>&nbsp;</span><span class="keyword">in</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;path&nbsp;resource&nbsp;[resource/applicationContext.xml]:&nbsp;Error&nbsp;setting&nbsp;property&nbsp;values;&nbsp;nested&nbsp;exception&nbsp;is&nbsp;org.springframework.beans.PropertyBatchUpdateException;&nbsp;nested&nbsp;PropertyAccessExceptions&nbsp;(1)&nbsp;are: &nbsp;&nbsp;</span></span></li>
    <li class=""><span>PropertyAccessException&nbsp;1:&nbsp;org.springframework.beans.TypeMismatchException:&nbsp;Failed&nbsp;to&nbsp;convert&nbsp;property&nbsp;value&nbsp;of&nbsp;type&nbsp;[java.lang.</span><span class="builtin">String</span><span>]&nbsp;to&nbsp;required&nbsp;type&nbsp;[org.beans.beanwrapper.Address]&nbsp;</span><span class="keyword">for</span><span>&nbsp;property&nbsp;'address';&nbsp;nested&nbsp;exception&nbsp;is&nbsp;java.lang.IllegalArgumentException:&nbsp;朝阳区,Soho&nbsp;1601,010101 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>Caused&nbsp;by:&nbsp;org.springframework.beans.PropertyBatchUpdateException;&nbsp;nested&nbsp;PropertyAccessException&nbsp;details&nbsp;(1)&nbsp;are: &nbsp;&nbsp;</span></li>
    <li class=""><span>PropertyAccessException&nbsp;1: &nbsp;&nbsp;</span></li>
    <li class="alt"><span>org.springframework.beans.TypeMismatchException:&nbsp;Failed&nbsp;to&nbsp;convert&nbsp;property&nbsp;value&nbsp;of&nbsp;type&nbsp;[java.lang.</span><span class="builtin">String</span><span>]&nbsp;to&nbsp;required&nbsp;type&nbsp;[org.beans.beanwrapper.Address]&nbsp;</span><span class="keyword">for</span><span>&nbsp;property&nbsp;'address';&nbsp;nested&nbsp;exception&nbsp;is&nbsp;java.lang.IllegalArgumentException:&nbsp;朝阳区,Soho&nbsp;1601,010101 &nbsp;&nbsp;</span></li>
    <li class=""><span>Caused&nbsp;by:&nbsp;java.lang.IllegalArgumentException:&nbsp;朝阳区,Soho&nbsp;1601,010101 &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;java.beans.PropertyEditorSupport.setAsText(Unknown&nbsp;Source) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.springframework.beans.TypeConverterDelegate.convertValue(TypeConverterDelegate.java:253) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:177) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:127) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:775) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:608) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;org.springframework.beans.A