随笔:93 文章:11 评论:22 引用:0
首页 发新随笔
发新文章 联系 聚合管理

学习知识难免会忘记,关键是在忘记之后,下次遇到时能够通过快捷的方法来回忆,并尽量达到忘记之前的状态。总结也许是日后回忆的一种有效方法,前些日子看了javascript的function,总结如下:

学习function重要的就是明白当程序运行到函数声明的时候,并不执行该函数,当其他函数调用所声明的函数时,该函数才被执行,也就是英文说的function is complied,but not executed until you call it.

再有就是函数在声明时创建变量。例如function(){}就创建了一个变量,虽然这个变量是匿名的。

js 代码
  1. var a=function(){};   
  2.   
  3. var a=function(x,y){}(1,2);   

第一条语句是定义一个匿名function,并将该函数赋给a变量。第二条语句是定义一个匿名function,并调用将该函数的返回结果赋值给a变量。

function add(a,b){};则是定义了一个function,该function的名字是add,相当于一个名为add的变量指向该function。

看看以下代码,感觉挺有意思:

js 代码
  1. function myFunction(){alert("Old");};   
  2.   
  3. var savedFunction=myFunction;   
  4.   
  5. myFunction=function(){alert("New");};   
  6.   
  7. myFunction();   //prints"New"   
  8.   
  9. savedFunction(); //prints"Old"   

在调用myFuction函数的时候,打印出New字符串,代码的第二行明确指出savedFunction=myFunction,但是在调用 savedFunction的时候会出现Old字符串,这种情况应该引起java同行的注意,在javascript中,指针指向的是代码片段,执行第二 行的时候,savedFucntion指向的是myFuction所指向的代码片段 myFunction code(第一行),然而在第三行myFunction指针由先前的代码片段myFunction code改变为代码片段function(){alert("New")} code的时候,先前的代码片段仍然未消失,被savedFunction所指向,这也就解释了为什么最后程序打印出的字符串仍是Old。

对于Function关键字来说仅在特殊情况下用到,一般就用function,这里就不再介绍了。

prototype属性对于初学js的人来说比较迷惑,这里大致的总结如下:

一般的变量没有prototype属性,constructor function有prototype属性,也就是声明的function(){}变量,js中的每个对象都有一个_proto_和 constructor属性,如果一个对象由constructor function生成,例如:

js 代码
  1. function Ball(message){   
  2.   
  3. alert(message);   
  4.   
  5. };   
  6.   
  7. var ball0=new Ball("executing");   

解释以下,最后一行代码等同于:

js 代码
  1. var ball0=new Object();   
  2.   
  3. ball0.construct=Ball;//将属性construct指向代码片段Ball code   
  4.   
  5. ball0.construct("executing"); //执行该代码片段   

接着说,如果一个对象由constructor function生成,则该对象ball0的_proto_属性指向它的构造函数的prototype属性,也就是指向constructor function(这里是前三行代码)所具有的prototype属性,因此凡是用该constructor function生成的对象,都带有该function的prototype属性。

posted @ 2009-05-03 08:39 redcoatjk 阅读(178) | 评论 (0)编辑 收藏
 

什么叫事务? 这些就是数据库特有的术语了。懒虫在这里口头解释:就是把多件事情当做一件事情来处理。也就是大家同在一条船上,要活一起活,要over一起over !

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transactionend transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

例如:在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。

事务是恢复和并发控制的基本单位。

事务应该具有4个属性:原子性、一致性、隔离性、持续性。这四个属性通常称为ACID特性

原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。

一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。


   我为什么要使用事务? 俺这里再举个很俗很俗的例子:

     俺到银行存钱,于是有这么几个步骤:
       1、把钱交给工作人员;2、工作人员填单;3、将单子给我签字;4、工作人员确认并输入电脑。

   要是,要是我把钱交给工作人员之后,进行到3我签字了。那哥们突然心脏病发作,over掉了,那,我的钱还没有输入电脑,但我却交了钱又签字确认了,而并没有其他任何记录。我岂不是要亏死了???我的血汗钱啊!赶紧退给我!!

   于是,在数据库里产生了这么一个术语:事务(Transaction),也就是要么成功,要么失败,并恢复原状。
  
   还是写程序把:

   Create Proc sp我去存款(@M Money , @iOperator Int)
   As
   Begin
    Declare @i int

    Begin Tran           --激活事务
     Exec @i=sp交钱 @m,@iOperator
     if @i<>0           --这里一般用系统错误号 @@Error。 我这里为了举例子没有用到。需要根据实际情况。
     begin
      Rollback Tran                   --回滚事务
      RaisError ('银行的窗口太少了,我懒得排队,不交了!:( ', 16, 1) with Log --记录日志
      Return -1                     --返回错误号
     end

     Exec @i=sp填单 @m,@iOperator
     if @i<>0
     begin
      Rollback Tran                   --回滚事务
      RaisError ('银行的哥们打印机出了点毛病,打印不出单子来,把钱退回来给我吧??', 16, 1) with Log
      Return -2                     
     end

     Exec @i=sp签字 @m
     if @i<>0
     begin
      Rollback Tran                   --回滚事务
      RaisError ('我 靠?什么烂银行,换了3支笔都写不出水来!!老子不存了!!不签!', 16, 1) with Log 
      Return -3                     
     end

     Exec @i=sp输入电脑 @m,@iOperator
     if @i<>0
     begin
      Rollback Tran                   --回滚事务
      RaisError ('什么意思?磁盘空间已满?好了好了,把钱给我,我到旁边的这家银行!', 16, 1) with Log 
      Return -4                     
     end
 
    Commit Tran        --提交事务
    Return 0
  End
 

       ----------------------------------------------------------------------
       以上是伪代码,模拟我去存款的过程。

posted @ 2009-05-02 22:28 redcoatjk 阅读(120) | 评论 (0)编辑 收藏
 

基本原理:

服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。

找一般的流程中插入个中间的action

多写一个actionnonoaction

nonoaction

this.saveToken(request); //设置指令牌

return 跳转到执行逻辑功能的action中如doaction

执行业务功能的action doaction

doaction

......

if(this.isTokenValid(request)) //如果指令牌相同

{.....

...实现功能的代码

this.resetToken(request);//取消指令牌

}else //执行else说明提交是重复提交

{

可以跳转回首页.并报错 如写

ActionMessages errors= new ActionMessagers();

errors.add(“token”,new ActionMessages(“token”)); //可以把错误信息写在资源文件中 然后显示

this.saveErrors(return.errors); //保持错误信息

跳转….

}

 

 

 

 

posted @ 2009-04-14 16:06 redcoatjk 阅读(129) | 评论 (0)编辑 收藏
 
代码见:mytoken
要防止重复提交
需要先设置指令牌
然后具体操作功能之前,验证指令牌.
------------
举例如下:
----------提交留言------------------
在执行留言的action前,设置一个指令牌(比如跳转到添加页面前,先执行一个action.在action中设置指令牌.或者拦截器中做也可以):
this.saveToken(request);
然后
执行添加留言的acion中,在执行功能操作前
 if(this.isTokenValid(request)); 验证指令牌.
为true则执行添加操作.最后 用
this.resetToken(request);
来取消指令牌.
如果之前的验证指令牌返回false,那就不用执行添加操作,直接跳转处理.

posted @ 2009-04-14 16:04 redcoatjk 阅读(191) | 评论 (0)编辑 收藏
 
     摘要: 摘自 http://www.blogjava.net/crazycy/archive/2008/10/19/74622.html#235256 < 示例1>  1 class  Base {  2      int  x  =   2 ;  3 ...  阅读全文
posted @ 2009-03-30 16:56 redcoatjk 阅读(135) | 评论 (0)编辑 收藏
 
载自http://www.cnblogs.com/itelite/archive/2008/01/11/1035587.html
<script language="javascript">
 //Author :东阁
 //Date:2008-1-11
 //目的: 练习数组的基本操作

 /*
 由于javascript是一种无类型语言,所以一个数组的元素可以具有任意的数据类型,同一个数组的不同元素
 可以具有不同的类型,数组的元素设置可以包含其他数组,这样就可以创建一个复杂的数组了.
 并且在这点上说javascript作为一种脚本语言不同于那种严格的面向对象的c++.c#,java了.具有更高的灵活性.
 */

 /*
 *在javascript1.1和其后的版本中,数组是用构造函数Array()和运算符new来创建,
 可用以下的三种方式来创建javascript 中的数组.
 */
 var a=new Array();
 var b=new Array(5,4,3,"first","test,string");
 var c=new Array(20);

 a[1.23]="test";
 document.write("a[1.23]="+a[1.23]);
 //相信每位从强类型的编程语言学习javascript时,绝对会以为上面这种操作感到惊讶,
 //float数据也作数组的下标了,事实上                       并非如您所想       
 //javascript在您是用负数,浮点数,(或布尔型,对象,其他值时),javascript会将它转换为一个字符串
 //用生成的字符串作为对象的属性名字,而不是定义了一个新的数组元素
 //上面的实例事实就是为a 创建了一个名为:"1.23"的属性.
 document.write("a.length="+a.length);
 document.write("b.length="+b.length);
 document.write("c.length="+c.length);

 a[3]="Test";
 document.write("<br />a[3]="+a[3]);
 document.write("<br/>a.length="+a.length);
 //以上测试也很明确我们用整数作为数组的下标是才会真正为数组添加一个元素,
 //这里用数组的长度来体现了javascript的数组中的奥妙。


 //通过设置数组的length属性能过截断数组的长度。
 a.length=3;
 if (a[3]==undefined)
 {
  document.write("<br />在a.length="+a.length+"后,a[3]="+a[3]);
 }
 else
 {
    document.write("<br />在a.length="+a.length+"后,a[3]="+a[3]);
 }

 //这里测试我们的多维数组元素
 /*
 *javascript中实际上是不支持多维数组
 *但是我们将一个一维数组的元素再赋给其一个一维数组,这样就看起来就实现了多维数组了,但
 实际上他还是个一维数组,这和我们理解c语言的数组时的那种想法一样,但他们的实现机制是不一样的。
 */
 var g=new Array(3);
 g[3]=a;
 g[3][2]="Test"
 document.write("<br />g[3][2]="+g[3][2]);
 
  //数组join()方法
  for (var i=0;i<20 ;i++ )
  {
 c[i]=i;
 document.write("<br />c[i]="+c[i]);
  }
  document.write("<br/>c的元素join()方法后是:"+c.join());
  //数组的reverse()方法
  c.reverse();
  document.write("<br />c的元素在reverse()方法再join()后的结果是:"+c.join("|"));

  //concat()方法的测试
  var h=new Array(1,2,3);
  h= h.concat([4,5]);
  //但是concat函数不会递归地展开一个元素为数组的数组。
  h=h.concat(6,7,[9,[10,20]]);
  document.write("<br />h.length="+h.length+"<br />"+h);
  document.write("h[8]="+h[8]);


  //slice()方法
  document.write("<br>h.slice(4,5)="+h.slice(4,5));
document.write("h.slice(5,9)="+h.slice(5,9))
//slice()方法:返回的数组包含有第一个参数指定的元素和那个元素开始到第二个参数指定的
//元素为止的元素但不包含第二个参数所指定的元素。


//splice()方法
//splice()方法是插入或删除数组元素通用的方法。
/*
splice函数第一个参数指定了要插入或删除的元素在数组中的位置。
第二个参数指定了要从数组中删除的元个数
在第二参数之后可以有任意多个参数,它们指定的是从第一个参数指定的位置处插入的元素。
第一个元素及后续元素,做出相应的移动。
*/

document.write("<br />h.splice(8,1)后的h为::"+h.splice(8,1));
//document.write("<br />h.splice(8,0,'a','b','Test')后的h为::"+h.splice(8,0,'a','b','Test'));
h.splice(7,0,'a','b','Test');
document.write("<br />h.splice(7,0,'a','b','Test')后的h为:"+h);


//javascript中的数组作为堆栈时和php类似
//这点有趣更有用。
//以下是作为堆栈是使用的小实例
/*
push方法是将一个或多个新元素附加到数组的尾部,然后返回数组的新长度。
pop将删除数组的最后一个元素,坚守数组的长度,返回他删除的值。
*/
var stack=new Array();
stack.push(1,2);
document.write("<br>stack的元素是:"+stack);
document.write("<br />stack.length="+stack.length);
document.write("<br>stack.pop()返回的结果是:"+stack.pop());
document.write("<br />stack.length="+stack.length);

//以下是作为队列使用的小实例
/*
unshift方法将一个或多个元素添加到数组元素的头部,然后把已有的元素移动到下标最大的位置已腾出空间
,它返回的是主族的新长度。
方法shift是删除并返回数组的第一个元素,然后将后面的所有元素都向前移动以填补第一个元素留下的空白。
*/
var list=[];
list.unshift(6,2);
document.write("<br >list的内容为:"+list);
document.write("<br>list的shift方法是:"+list.shift());

//此外就剩下,我们在java中熟悉的toString()方法 了
//It's a piece of cake!
document.write(c.toString());
//说白了,其实数组的toString()方法和无参数的join()的效果是完全相同
//OK,this's chapter for Array,that's all!

</script>

posted @ 2009-03-09 13:06 redcoatjk 阅读(659) | 评论 (0)编辑 收藏
 

网上搜到这个资料.

加以修改加工一下,发布.感谢原作者的付出:http://singlewolf.javaeye.com/blog/173877

Singleton类之所以是private型构造方法,就是为了防止其它类通过new来创建实例,即如此,那我们就必须用一个static的方法来创建一个实例(为什么要用static的方法?因为既然其它类不能通过new来创建实例,那么就无法获取其对象,那么只用有类的方法来获取了)

 1class Singleton {   
 2
 3     private static Singleton instance;  
 4
 5     private static String str="单例模式原版" ;
 6
 7 
 8
 9     private Singleton(){}   
10
11     public static Singleton getInstance(){   
12
13         if(instance==null){   
14
15             instance = new Singleton();   
16
17         }
   
18
19         return instance;   
20
21     }
   
22
23     public void say(){   
24
25         System.out.println(str);   
26
27     }
  
28
29     public void updatesay(String i){
30
31           this.str=i;
32
33           
34
35          
36
37     }
 
38
39}
   
40
41  
42
43public class danli{   
44
45    public static void main(String[] args) {   
46
47        Singleton s1 = Singleton.getInstance();   
48
49        //再次getInstance()的时候,instance已经被实例化了   
50
51        //所以不会再new,即s2指向刚初始化的实例   
52
53        Singleton s2 = Singleton.getInstance();   
54
55        System.out.println(s1==s2);   
56
57        s1.say();   
58
59        s2.say();   
60
61        //保证了Singleton的实例被引用的都是同一个,改变一个引用,则另外一个也会变.
62
63        //例如以下用s1修改一下say的内容
64
65        s1.updatesay("hey is me Senngr");   
66
67        s1.say();  
68
69        s2.say(); 
70
71        System.out.println(s1==s2); 
72
73    }
   
74
75}

76

 打印结果:
true

单例模式原版

单例模式原版

hey is me Senngr

hey is me Senngr

true

private static Singleton instance;
public static Singleton getInstance()
这2个是静态的 

1.定义变量的时候是私有,静态的:private static Singleton instance;
2.定义私有的构造方法,以防止其它类通过new来创建实例;
3.定义静态的方法public static Singleton getInstance()来获取对象.instance = new Singleton();
posted @ 2009-03-05 21:42 redcoatjk 阅读(143) | 评论 (0)编辑 收藏
 
     摘要: 代码参见dynamic-proxy-AOP2 基于配置文件的方式的好处在于所谓的分层.所以号称应该推荐使用这个方法 随便了.代码重新贴一次吧. 1.UserManager接口  1package com.zyl.proxy;  2  3public interface UserManager {  4&n...  阅读全文
posted @ 2009-02-22 21:10 redcoatjk 阅读(574) | 评论 (1)编辑 收藏
 
 前面一个文章里的代码很简单(只是让大家了解什么是代理),实现的是静态代理,做为电脑代理商的ComputerProxy,在电脑行业 为电脑生产商(三星,联想)和客户提供服务,提供各种方便。
        郁闷的是,如果我现在增加一个行业,比如下面要讲到的Cat汽车行业,那么,我们只能增加一个代理了,也就是说我们要再写一个CatProxy代码,我们现在假设我们有很多个行业,那么,无疑我们的工作量开始大了,有没有什么办法让我们的代理商实现跨行业代理呢?
        答案是:可以。这就是我们这里讲的动态代理产生存在的意义了。

请看代码

在原有代码的基础上我们做了这些宽展:

/*
*汽车批发商
*这样我们的代码中就有了电脑和汽车这两个批发商
*/

public interface Cat {
    
public void buyCat(String name);
}

/*
*劳斯莱斯汽车公司
*/

public class RollsRoyce implements Cat {

    
public void buyCat(String name) {
        
        System.out.println(name
+"  劳斯莱斯公司产品!");
    }


}

/*
*所有行业代理商
*有了它我们的客户可以通过他买个各种产品
*/

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.logging.Level;
import java.util.logging.Logger;

public class AllthingsProxy implements InvocationHandler {

    
private Logger logger=
        Logger.getLogger(
this.getClass().getName());
    
    
private Object allthings;
    
    
//实现对象绑定
    public Object bind(Object allthings){
        
        
this.allthings = allthings;
        
        
//这里传入newProxyInstance的参数分别是 目标object
        
//(Lianxiang,Sanxing),interface(Computer),AllthingsProxy
        return Proxy.newProxyInstance(allthings.getClass().getClassLoader(),
                                    allthings.getClass().getInterfaces(), 
this);
    }

    
    
public Object invoke(Object proxy, Method method, Object[] args)
            
throws Throwable {
        
        Object result 
= null;
        
        
try{
        log(
"method starts " + method);
        
        result
=method.invoke(allthings, args);

        logger.log(Level.INFO , 
"method ends " + method);
        
        }
catch(Exception e){
            log(e.toString());
        }

        
        
return result;
    }

    
    
private void log(String msg){
        logger.log(Level.INFO,msg);
    }


}


在测试类BuyAllThings中,我们通过bing方法绑定对象(所要买的东西),让代理商了解到,客户想买什么?
(这里重在了解模式,具体方法的实现如不了解请自行查询API文档)


/*
*三个客户两个买电脑一个买汽车
*他们找到同个代理商
*/

public class BuyAllThing {

    
public static void main(String[] args) {
        
        AllthingsProxy allthingsproxy 
= new AllthingsProxy();
        
        Computer SanxingProxy
=(Computer)allthingsproxy.bind(new Sanxing());
        
        SanxingProxy.buyComputer(
"我想买一台三星电脑");
        
        Computer lianxiangProxy
=(Computer)allthingsproxy.bind(new Lianxiang());
        
        lianxiangProxy.buyComputer(
"我想买一台联想电脑");
        
        Cat RollsRoyceProxy
=(Cat)allthingsproxy.bind(new RollsRoyce());
        
        RollsRoyceProxy.buyCat(
"我想买一辆劳斯莱斯汽车");

    }


}

执行结果

我想买一台三星电脑  三星电脑公司产品!
我想买一台联想电脑  联想电脑公司产品!
我想买一辆劳斯莱斯汽车  劳斯莱斯公司产品!
2007-8-9 13:08:41 com.lusm.spring.AllthingsProxy log
信息: method starts 
public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy invoke
信息: method ends 
public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy log
信息: method starts 
public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy invoke
信息: method ends 
public abstract void com.lusm.spring.Computer.buyComputer(java.lang.String)
2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy log
信息: method starts 
public abstract void com.lusm.spring.Cat.buyCat(java.lang.String)
2007-8-9 13:08:42 com.lusm.spring.AllthingsProxy invoke
信息: method ends 
public abstract void com.lusm.spring.Cat.buyCat(java.lang.String)

我们可以任意的增加代理商的业务,比如,叫他代理电器,食物......,我们看到我们不需要更改原有的代码。这是动态代理带来的好处!

那我们的AllthingsProxy是怎么作到动态代理的呢?

AllthingsProxy宽展了InvocationHandler并实现了里面的代理方法,返回一个Object对象,

    public Object invoke(Object proxy, Method method, Object[] args)
    
throws Throwable;

来实现对汽车,电脑这些批发商的动态代理(代理商同过它 代理所有行业)。

AllthingsProxy中的bind实现了客户和代理商间的通信(通过它代理商知道客户想要买什么)

这和我们 BuyAllThing 测试类main中

代理对象=(绑定对象)allthingsproxy.bind(绑定对象(客户想买的东西))

想对应。

         呵呵 ,讲完了!也许有的朋友看不懂这里在说什么? 不必着急,学习都需要过程,等你的学习到某个阶段的时候,回头想想,也许认识就会加深许多,本人觉得Java是比较高级的语言,自身的发展也只直遵循着软件设计优化(代码重用)方向发展,重视设计思想,而不是去改变语言的语法或接口api,这是许多语言所缺乏的,如一个在VC6中编写的代码,拿到Visual Studio2005,Visual Studio2008去运行很容易出现问题。

       也许你并不清楚我在说什么?但是这一切会在你的Spring学习中渐渐清楚起来!

       以后的代码可能需要必要的IDE才能使用,本人使用的是:
       MyEclipse6.0M1+Eclipse3.3 
       数据库用的是:
      Oralce10g或者Mysql6.0

      祝你好运气!!!
posted @ 2009-02-19 23:15 redcoatjk 阅读(173) | 评论 (0)编辑 收藏
 
     摘要: 这几天在看一些代理的东西.发现这个帖子写的很不错 冒昧转过来收藏之. 摘自 http://www.blogjava.net/lusm/archive/2007/08/08/135355.html ---------------------------------------------------------------- 在以后的日子里,我会用学习剩下的时间和大家一起学习Java设计...  阅读全文
posted @ 2009-02-19 23:05 redcoatjk 阅读(225) | 评论 (1)编辑 收藏
仅列出标题
共8页: 上一页 1 2 3 4 5 6 7 8 下一页 
CALENDER
<2025年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

常用链接

留言簿(3)

随笔分类(22)

随笔档案(76)

文章分类(12)

文章档案(17)

搜索

  •  

积分与排名

  • 积分 - 250317
  • 排名 - 227

最新评论

评论排行榜


Powered By: 博客园
模板提供沪江博客