落落空间

缘来是java
posts - 12, comments - 12, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2007年7月25日

前提:两个项目A和B,其中项目A登录之后拥有了自己的session,项目B想共用此session,通过项目A的servlet回调项目B的servlet,并给其传递sessionId,在项目B中通过sessionId调用远程接口获取session并赋值给自己的session,项目B再一次发起请求时自己创建的sessionId被改变,session丢失。
解决办法:
在项目B的servlet内加入:Response.AddHeader("P3P","CP=CAO PSA OUR");
原因:ie默认不接受没有标识为安全的第三方cookie,造成不能保存cookie及session。

posted @ 2009-11-05 17:10 落落 阅读(2685) | 评论 (0)编辑 收藏

有时候要限制用户可输入的内容限制为英文字母和数字,即希望关闭输入法

这时候只要简单的对要限制的控件加上一个ime-mode的css属性即可,如<input style="ime-mode:disabled">

ime-mode    CSS提议属性

语法:
ime-mode : auto | active | inactive | disabled
 
参数:
auto : 不影响IME的状态。与不指定ime-mode属性时相同
active : 指定所有使用IME输入的字符。即激活本地语言输入法。用户仍可以撤销激活IME
inactive : 指定所有不使用IME输入的字符。即激活非本地语言。用户仍可以撤销激活IME
disabled : 完全禁用IME。对于有焦点的控件(如输入框),用户不可以激活IME
 
说明:
设置或检索是否允许用户激活输入中文,韩文,日文等的输入法(IME)状态。
对应的脚本特性为imeMode。
 
示例:
<input type=text style='ime-mode: disabled; '>

posted @ 2007-07-31 17:09 落落 阅读(1360) | 评论 (1)编辑 收藏

基于模板的Web表示层技术 (摘自《Spring开发指南》)

传统的JSP技术为Web表现层技术提供了灵活、丰富的功能支持。然而,站在工程的角度
而言,过于凌乱的JSP Script也成为系统维护的头号大敌。
JSP 代码几乎等同于Java 代码,在提供了最丰富的特性支持的同时,也为系统的开发带
来一些隐患,程序员往往天马行空,不为羁束,在JSP 中将业务逻辑、数据逻辑、表现逻辑代
码相混杂,代码重用性、系统可维护性极低。特别是在参与开发人员众多,技术水平良莠不齐
的情况下,纵使技术经理一再强调设计规范的约束,但人本的约束总是难以控制,随着开发过
程进展和产品上线压力的增大,规范约束逐渐薄弱,于是难以避免的造成代码的混乱,可维护
性的下降。
面对这个问题,众多组织和厂商开始研发自己的表现层框架,试图通过一个隔离的表现层
框架,强行将表现层和逻辑层相剥离。时间似乎退回到了最初Web 端只支持Servlet 技术的
时代(那时候或多或少各个公司都有自己的模板实现)。不过,现在的模板技术经过长时间的
发展,已经将表现层的能力发挥得淋漓尽致,不失为JSP技术之外的一个明智选择。

模板技术相对传统JSP技术有以下三个主要优势:
1. 在技术层面,将表现逻辑与业务逻辑相分离。
2. 为人员之间的分工提供了一个良好的分界点。页面美工只需专著关心模板的设计,而程序员则专注于业务逻辑的实现。二者重合点明显减少。
3. 如果需要,模板引擎可脱离Web 容器单独运行,这为系统可能的移植需求提供了更多的弹性空间(这一特性在应用中也许并不会有太大的实际意义,只是提供了一种附加选择)。

目前Spring支持一下几种模板技术:
1. XSLT
XSLT是基于XML的表现层模板技术,伴随着XML的大量使用。XSLT也日渐成熟,并
迅速成为主流表现层技术之一。XSLT作为一个通用表现层框架,拥有最好的平台适应性,
几乎所有的主流程序设计语言都提供了XLST支持,现有的XLST模板可以简单的移植到不
同的语言平台
,如将J2EE应用中的XSLT移植到.net平台,这样的可移植性是其他专用
模板技术,如Velocity和Freemarker难以达到的。
笔者在2001年在一个原型项目中采用了XSLT作为表现层实现,由于当时XSLT尚不
成熟,XSLT解析器效率低下,因此在正式产品开发中使用其他技术作为替代。在2003年
中,经过技术探讨,决定再次在项目实施中引入XSLT 技术,相对两年前,此时的XSLT
技术已经相当成熟,解析器的效率也大大改善。经过半年时间的项目研发,产品上线,并
取得了令人满意的表现。不过,在之后的项目回顾过程中,笔者认为,目前在项目中大量
采用XSLT技术尚不可取,上述项目开发过程中,XSLT技术提供了极佳的扩展性和重用性,
也保证了业务逻辑和表示逻辑的清晰划分,然而,最大的问题是,XSLT缺乏强有力的编辑
器支持。虽然通过XML/XSLT 技术成全了设计上近乎完美的表现,但却为界面开发带来了
极大难度,以至后期复杂界面的修改都需要消耗极大的人力,得不偿失。

笔者在项目开发中所用的XSLT 编辑器为StylusStudio 和XmlSpy,目前这两款编
辑器可以算是XSLT开发的首选,提供了丰富的特性和可视化编辑功能。但即便如此,XLST
繁杂苛刻的语法和调试上的难度也为开发工作带来了极大的障碍。
此外,也许是最重要的一点,xslt在性能上的表现尚不尽如人意。经过多年的发展,
XSLT解析/合成器的性能相对最初已经大为改观,但依然与其他模板技术存在着较大差距。
据实地测试,FreeMarker和Velocity对于同等复杂度的表现层逻辑,平均处理速度是
XSLT 的10 倍以上,这是一个不得不正视的性能沟壑。
同时,XSLT 的内存占用也是
FreeMarker 和Velocity 的数倍有余(XSLT 中,每个节点都是一个Java 对象,大量
对象的存储对内存占用极大,同时大量对象的频繁创建和销毁也对JVM 垃圾收集产生了较
大负面影响)。
在上述项目中,由于硬件上的充分冗余(8G RAM, 4CPU),才使得这些
性能上的影响相对微弱。
因此,目前在项目中大量引入XSLT技术尚需仔细考量。
2. Velocity
Velocity是Apache Jakarta项目中的一个子项目,它提供了丰富强大的模板功能。
作为目前最为成熟的模板支持实现,Velocity 在诸多项目中得到了广泛应用,不仅
限于Web 开发,在众多代码生成系统中,我们也可以看到Velocity 的身影(如
Hibernate中的代码生成工具)。
3. FreeMarker
FreeMarker是Velocity之外的另一个模板组件。
与Velocity 相比,FreeMarker 对表现逻辑和业务逻辑的划分更为严格,
Freemarker在模板中不允许对Servlet API进行直接操作(而Velocity可以),
如FreeMarker 中禁止对HttpServletRequest 对象直接访问(但可以访问
HttpServletRequest对象中的Attribute)。通过更加严格的隔离机制,牵涉逻
辑处理的操作被强制转移到逻辑层。从而完全保证了层次之间的清晰性。
另外一个Velocity无法实现的特性,也是最具备实际意义的特性:FreeMarker对
JSP Tag提供了良好支持。
这一点可能存在一点争议,JSP技术的最大问题就是容易
在页面中混入逻辑代码。而FreeMarker 对JSP Tag 的支持似乎为这个问题又打开
了大门。这一点上,我们可以将FreeMarker看作是仅允许使用TAG的JSP页面(实
际上,FreeMarker的表达式语法与EL语法也非常类似)。
从开发角度而言,只允许使用TAG的JSP页面,已经在很大程度上保证了页面表现逻
辑与业务逻辑的分离。
程序员在JSP Script中混杂逻辑代码的原因,大部分是出于
慵懒,只要无法在页面模板中直接编写Java代码,相信程序员也不会去专门编写一个
JSP TAG来刻意违反层次划分原则。
对JSP TAG 的支持为FreeMarker 带来了极大的活力,目前开源社区中已经有了为
数众多的成熟Taglib,如DisplayTag、Struts Menu等,这些功能丰富,成熟可
靠的Taglib,将为产品开发提供极大的便利。另一方面,这也为代码重用提供了另一
个可选途径,避免了大部分模板实现在这一点上的不足。
就笔者的经验,对于Web开发而言,FreeMarker在生产效率和学习成本上更具优势,
而Velocity 的相对优势在于更多第三方工具的支持和更广泛的开发和用户团体(然
而对于一个轻量级模板类库而言,这样的优势并不是十分明显)。
如果没有Velocity的技术储备,而又需要通过技术上的限定解决视图/模型的划分问
题,这里推荐采用FreeMarker作为Spring MVC中的表现层实现。以获得最好的(学
习、开发)成本受益。

posted @ 2007-07-26 16:06 落落 阅读(1184) | 评论 (0)编辑 收藏

理解类的实现机制

  在JavaScript中可以使用function关键字来定义一个“类”,如何为类添加成员。在函数内通过this指针引用的变量或者方法都会成为类的成员,例如:
程序代码 程序代码

function class1(){
        var s="abc";
        this.p1=s;
        this.method1=function(){
                alert("this is a test method");
        }
}
var obj1=new class1();

  通过new class1()获得对象obj1,对象obj1便自动获得了属性p1和方法method1。

  在JavaScript中,function本身的定义就是类的构造函数,结合前面介绍过的对象的性质以及new操作符的用法,下面介绍使用new创建对象的过程。
  (1)当解释器遇到new操作符时便创建一个空对象;
  (2)开始运行class1这个函数,并将其中的this指针都指向这个新建的对象;
  (3)因为当给对象不存在的属性赋值时,解释器就会为对象创建该属性,例如在class1中,当执行到this.p1=s这条语句时,就会添加一个属性p1,并把变量s的值赋给它,这样函数执行就是初始化这个对象的过程,即实现构造函数的作用;
  (4)当函数执行完后,new操作符就返回初始化后的对象。

  通过这整个过程,JavaScript中就实现了面向对象的基本机制。由此可见,在JavaScript中,function的定义实际上就是实现一个对象的构造器,是通过函数来完成的。这种方式的缺点是:
  ·将所有的初始化语句、成员定义都放到一起,代码逻辑不够清晰,不易实现复杂的功能。
  ·每创建一个类的实例,都要执行一次构造函数。构造函数中定义的属性和方法总被重复的创建,例如:
程序代码 程序代码

this.method1=function(){
              alert("this is a test method");
       }

  这里的method1每创建一个class1的实例,都会被创建一次,造成了内存的浪费。下一节介绍另一种类定义的机制:prototype对象,可以解决构造函数中定义类成员带来的缺点。


使用prototype对象定义类成员
  现在介绍另一种为类添加成员的机制:prototype对象。当new一个function时,该对象的成员将自动赋给所创建的对象,例如:
程序代码 程序代码

<script language="JavaScript" type="text/javascript">
<!--
 //定义一个只有一个属性prop的类
 function class1(){
         this.prop=1;
 }
 //使用函数的prototype属性给类定义新成员
 class1.prototype.showProp=function(){
         alert(this.prop);
 }
 //创建class1的一个实例
 var obj1=new class1();
 //调用通过prototype原型对象定义的showProp方法
 obj1.showProp();
//-->
</script>

  prototype是一个JavaScript对象,可以为prototype对象添加、修改、删除方法和属性。从而为一个类添加成员定义。

  了解了函数的prototype对象,现在再来看new的执行过程。
  (1)创建一个新的对象,并让this指针指向它;
  (2)将函数的prototype对象的所有成员都赋给这个新对象;
  (3)执行函数体,对这个对象进行初始化操作;
  (4)返回(1)中创建的对象。

  和new的执行过程相比,多了用prototype来初始化对象的过程,这也和prototype的字面意思相符,它是所对应类的实例的原型。这个初始化过程发生在函数体(构造器)执行之前,所以可以在函数体内部调用prototype中定义的属性和方法,例如:
程序代码 程序代码

<script language="JavaScript" type="text/javascript">
<!--
//定义一个只有一个属性prop的类
function class1(){
        this.prop=1;
        this.showProp();
}
//使用函数的prototype属性给类定义新成员
class1.prototype.showProp=function(){
        alert(this.prop);
}
//创建class1的一个实例
var obj1=new class1();
//-->
</script>

  和上一段代码相比,这里在class1的内部调用了prototype中定义的方法showProp,从而在对象的构造过程中就弹出了对话框,显示prop属性的值为1。

  需要注意,原型对象的定义必须在创建类实例的语句之前,否则它将不会起作用,例如:
程序代码 程序代码

<script language="JavaScript" type="text/javascript">
<!--
//定义一个只有一个属性prop的类
function class1(){
        this.prop=1;
        this.showProp();
}
//创建class1的一个实例
var obj1=new class1();
//在创建实例的语句之后使用函数的prototype属性给类定义新成员,只会对后面创建的对象有效
class1.prototype.showProp=function(){
        alert(this.prop);
}
//-->
</script>

  这段代码将会产生运行时错误,显示对象没有showProp方法,就是因为该方法的定义是在实例化一个类的语句之后。

  由此可见,prototype对象专用于设计类的成员,它是和一个类紧密相关的,除此之外,prototype还有一个重要的属性:constructor,表示对该构造函数的引用,例如:
程序代码 程序代码

function class1(){
        alert(1);
}
class1.prototype.constructor(); //调用类的构造函数

  这段代码运行后将会出现对话框,在上面显示文字“1”,从而可以看出一个prototype是和一个类的定义紧密相关的。实际上:class1.prototype.constructor===class1。


一种JavaScript类的设计模式

  前面已经介绍了如何定义一个类,如何初始化一个类的实例,且类可以在function定义的函数体中添加成员,又可以用prototype定义类的成员,编程的代码显得混乱。如何以一种清晰的方式来定义类呢?下面给出了一种类的实现模式。

  在JavaScript中,由于对象灵活的性质,在构造函数中也可以为类添加成员,在增加灵活性的同时,也增加了代码的复杂度。为了提高代码的可读性和开发效率,可以采用这种定义成员的方式,而使用prototype对象来替代,这样function的定义就是类的构造函数,符合传统意义类的实现:类名和构造函数名是相同的。例如:
程序代码 程序代码

function class1(){
        //构造函数
}
//成员定义
class1.prototype.someProperty="sample";
class1.prototype.someMethod=function(){
        //方法实现代码
}  

  虽然上面的代码对于类的定义已经清晰了很多,但每定义一个属性或方法,都需要使用一次class1.prototype,不仅代码体积变大,而且易读性还不够。为了进一步改进,可以使用无类型对象的构造方法来指定prototype对象,从而实现类的成员定义:
程序代码 程序代码

//定义一个类class1
function class1(){
        //构造函数
}
//通过指定prototype对象来实现类的成员定义
class1.prototype={
        someProperty:"sample",   someMethod:function(){
             //方法代码
        },
        …//其他属性和方法.
}

  上面的代码用一种很清晰的方式定义了class1,构造函数直接用类名来实现,而成员使用无类型对象来定义,以列表的方式实现了所有属性和方法,并且可以在定义的同时初始化属性的值。这也更象传统意义面向对象语言中类的实现。只是构造函数和类的成员定义被分为了两个部分,这可看成JavaScript中定义类的一种固定模式,这样在使用时会更加容易理解。

  注意:在一个类的成员之间互相引用,必须通过this指针来进行,例如在上面例子中的someMethod方法中,如果要使用属性someProperty,必须通过this.someProperty的形式,因为在JavaScript中每个属性和方法都是独立的,它们通过this指针联系在一个对象上。

posted @ 2007-07-25 15:27 落落 阅读(227) | 评论 (0)编辑 收藏