美丽涵涵童装店--说我博客名字,给你们打折!
随笔 - 82  文章 - 266  trackbacks - 0
<2007年8月>
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678


点击这里给杨爱友发消息
美丽涵涵童装店
说我博客名字,给你们打折!

常用链接

留言簿(6)

随笔分类

随笔档案

文章档案

好友的BLOG

搜索

  •  

最新评论

阅读排行榜

评论排行榜

vim
1. 删除行命令
dd: 删除游标所在的一整行(常用)
ndd: n为数字。删除光标所在的向下n行,例如20dd则是删除光标所在的向下20行
d1G: 删除光标所在到第一行的所有数据
dG: 删除光标所在到最后一行的所有数据
d$: 删除光标所在处,到该行的最后一个字符
d0: 那个是数字0,删除光标所在到该行的最前面的一个字符
x,X: x向后删除一个字符(相当于[del]按键),X向前删除一个字符(相当于[backspace]即退格键) 
2. 插入命令
I 在当前行首插入
A 在当前行尾插入
o 在当前行之后插入一行
O 在当前行之前插入一行
3. 移动命令
w 向前移动一个单词(光标停在单词首部),如果已到行尾,则转至下一行行首。此命令快,可以代替l命令。

b 向后移动一个单词 2b 向后移动2个单词
到指定行,冒号+行号,回车,比如跳到240行就是 :240回车
Ctrl + e 向下滚动一行
Ctrl + y 向上滚动一行
Ctrl + f 向下滚动一屏
Ctrl + b 向上滚动一屏    
4. 拷贝和粘贴
yy 拷贝当前行
nyy 拷贝当前后开始的n行,比如2yy拷贝当前行及其下一行。
p  在当前光标后粘贴,如果之前使用了yy命令来复制一行,那么就在当前行的下一行粘贴。
shift+p 在当前行前粘贴
...
posted @ 2019-01-29 13:59 杨爱友 阅读(180) | 评论 (0)编辑 收藏
参考文章:
http://wenku.baidu.com/link?url=kq8VcGwEedCn5hHdSDbPsQrJCapBZje0DRRzyvEOkpqVOEP5XV--dtSL3RNC9a5Mf9K3mSJOGVwYt8VHjpUoBVTQ0L5z3WOSV-dTpSgs-My

用一张空的U盘,利用支持软件和ISO镜像文件制作安装盘,然后将USB3.0驱动程序放进U盘

在格式化步骤,格式化完之后要加载USB3的驱动程序,否则安装WIN7后无法使用鼠标和键盘
参考文章:http://bbs.feng.com/read-htm-tid-8203477.html

启动WIN7后,可能出现黑屏“无法验证签名文件”,把windows\system32\drivers 里面那个AppleSSD.sys干掉
参考文章:
http://bbs.feng.com/read-htm-tid-9791867.html

最后进入WIN7系统,此时之后一个盘符,需要再进行分盘,按照网上介绍,“压缩卷--新建简单分区“进行,发现竟然把原有MAC系统干掉了,这里千万注意!

然后就是到bootcamp/drivers下面找一些网络、显卡等的驱动进行点击安装。
posted @ 2015-09-25 16:48 杨爱友 阅读(279) | 评论 (0)编辑 收藏
     摘要: 先在客户端注册一个callback, 然后把callback的名字传给服务器。

此时,服务器先生成 json 数据。
然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.

最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)
美丽涵涵童装店
  阅读全文
posted @ 2014-10-29 14:57 杨爱友 阅读(9362) | 评论 (5)编辑 收藏
     摘要: Spring源代码解析(一):IOC容器:http://www.javaeye.com/topic/86339
Spring源代码解析(二):IoC容器在Web容器中的启动:http://www.javaeye.com/topic/86594
Spring源代码解析(三):Spring JDBC:http://www.javaeye.com/topic/87034
Spring源代码解析(四):Spring MVC:http://www.javaeye.com/topic/87692
Spring源代码解析(五):Spring AOP获取Proxy:http://www.javaeye.com/topic/88187
美丽涵涵童装店
  阅读全文
posted @ 2014-10-29 14:54 杨爱友 阅读(2708) | 评论 (0)编辑 收藏
     摘要: 提高淘宝店铺访问量办法  阅读全文
posted @ 2014-10-29 14:34 杨爱友 阅读(4694) | 评论 (0)编辑 收藏
     摘要: Spring源码学习-bean加载
一个applicationContext.xml配置文件,这个不可少
一个bean,这里我没用接口,直接用一个普通的类做为Spring的bean
一个Junit测试类  阅读全文
posted @ 2014-08-29 10:47 杨爱友 阅读(10849) | 评论 (3)编辑 收藏

学习源码是一件非常耗时费力的事情,需要有足够的时间和持久的耐心,下面是我阅读郝佳老师的《Spring源码深度解析》所做的记录,书中以Spring3.2讲解,使用jdk1.7。

准备工作

1. 安装github:现在spring源代码都在github管理,所以首先需要下载githup,下载地址http://windows.github.com;

2. 安装gradle构建工具:下载地址http://www.gradle.org/downloads,下载完后进行解压到任意盘符,然后增加环境变量GRADLE_HOME,并在环境变量bin中增加%GRADLE_HOME%/bin,打开DOS窗口,运行gradle -v,出现版本号等信息,表示安装成功;

3. 下载Spring源码:首先打开git shell,切换到你的工作目录,然后输入以下命令:git clone git://github.com/SpringSource/Spring-framework.git,后面一串是源码下载地址。大概半小时的样子,就可以下载完成,这时候在你的工作目录中就会出现Spring-framework的目录,里面有Spring各组件的源码包;

4. 构建导入:下载下来的代码不能直接导入Eclipse,要先转换成Eclipse能读取的形式。因为所有组件都会依赖spring-core,所有我们首先要转换Spring-core工程,在命令窗口切换到Spring-core工程,运行gradle cleanidea eclipse命令,我们会看到开始下载工程所依赖的jar包,几分钟后执行完毕,再来看Spring-core文件夹,多了.classpath、.project等文件,这是Eclipse工程所必须的,然后可以把他导入到eclipse。因为大部分Spring组件都会用到 spring-beans、spring-context、spring-aop,而他们又依赖spring-expression、spring-instrument,所以我们干脆先把这些工程都进行转换并导入eclipse。

我初次导入过程并不顺利,拿spring-core为例,其中以来的一个jar包是Spring-framework/spring-core/build/libs/spring-asm-repack-4.0.jar,但我工程里面并没有他,只好在网上下载了一个,并加入构建路径,其次我还发现少commons-pool-1.5.3.jar、spring-cglib-repack-3.0.jar,都一一下载,最后还是报错没有java.util.concurrent.ForkJoinPool类,发现这个版本必须使用jdk1.7以上,1.6没有这个包。折腾半天,终于几个工程没变异错误了,向前迈进了一步。




posted @ 2014-08-21 16:04 杨爱友 阅读(5933) | 评论 (2)编辑 收藏

场景1:aService里面有个savePerson方法,里面将调用bService中的保存方法进行保存;

    aService代码:
@Transactional(propagation=Propagation.REQUIRED)
public void savePerson() {
Person p1 = new Person();
p1.setName("yangay");
Person p2 = new Person();
p2.setName("lisan");
messageBean.saveTwo(p1, p2);
messageBean.savePerson(null);
}
     bService代码:
      @Transactional(propagation=Propagation.REQUIRED)
public void saveOne(Person p){
this.dao.save(p);
}
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void saveTwo(Person p1,Person p2){
this.dao.save(p1);
this.dao.save(p2);
}
    因为saveTwo的传播特性设置为requires_new,saveTwo方法单独起一个事务,所以当调用saveOne抛出异常之后,不会影响saveTwo事务提交,事实上,在saveTwo返回之前已经将事务提交,所以p1、p2对象能保存入库;
    如果将saveTwo方法的传播特性设置为required,这时候三个方法公用一个事务,当saveOne抛出异常后,整个事务回滚,数据不能入库;

场景2:
 aService代码:
@Transactional(propagation=Propagation.REQUIRED)
public void savePerson() {
try{
Person p1 = new Person();
p1.setName("yangay");
Person p2 = new Person();
p2.setName("lisan");
messageBean.saveTwo(p1, null);
}catch(Exception ex){
ex.printStackTrace();
}
}
 bService代码:
        @Transactional(propagation=Propagation.REQUIRED)
public void saveTwo(Person p1,Person p2){
this.dao.save(p1);
this.dao.save(p2);
}
     因为异常被catch了,所以事务不回滚,p1正常入库;
场景3:
 aService代码:
@Transactional(propagation=Propagation.REQUIRED)
public void savePerson() {
try{
Person p1 = new Person();
p1.setName("yangay");
Person p2 = new Person();
p2.setName("lisan");
messageBean.saveOne(p1);
messageBean.saveTwo(p2, null);
}catch(Exception ex){
ex.printStackTrace();
}
}
 bService代码:
        @Transactional(propagation=Propagation.REQUIRED)
public void saveOne(Person p){
this.dao.save(p);
}
@Transactional(propagation=Propagation.REQUIRED)
public void saveTwo(Person p1,Person p2){
this.dao.save(p1);
this.dao.save(p2);
}
        开始以为有了try catch,p1能保存进去,但经过测试,发现会报错。因为saveTwo时抛出异常,首先被spring框架个catch住,将事务标记为rollbackonly,然再往出抛异常,最后被savePerson方法catch住,所以事务能够提交,但当提交的时候,发现标志位已经被设置了,不应该去提交了,然后吭哧吭哧的回滚调,再提示你已经被设置成rollback-only了。
        但如果saveTwo的传播特性改为require_new,因为他单起一个事务,不会影响父事务的提交,所以p1能保存,p2失败;

场景4:
事务在多个对象之间才有传播特性
@Override
public void savePerson() {
Person p1 = new Person();
p1.setName("yangay");

Person p2 = new Person();
p2.setName("lisan");

saveTwo(p1,null);
}

@Transactional(propagation=Propagation.REQUIRED)
public void saveTwo(Person p1,Person p2){
messageBean.saveOne(p1);
messageBean.saveOne(p2);
}
    两个方法在一个类里面,saveTwo并没有事务,p1能提交;但如果把saveTwo放到另外一个类,则saveTwo就会有事务,p1不能提交;
    如果要同一个类里面的saveTwo执行事务,可在配置文件增加<aop:aspectj-autoproxy expose-proxy="true"/>,然后((Iservice)AopContext.currentProxy()).saveTwo(),这样执行的就是代理的方法,就会有事务(Iservice必须是你定义的接口)
posted @ 2014-08-08 15:43 杨爱友 阅读(2734) | 评论 (0)编辑 收藏
当我把jboss/client下的所有jar和ejb工程jar方到web工程下,编写main函数可以调用到EJB的bean,而将web工程发布出去后,就调用不到了,报错“javax.naming.NameNotFoundException: xxx not bound”,折腾了五六个小时,网上说了各种各样的原因,都没能解决,最后看这位兄弟的文章,问题才得以解决。
http://blog.163.com/zzk331@126/blog/static/142674599200957111441126/
如果你的问题解决了,请回复我!
posted @ 2014-05-28 16:56 杨爱友 阅读(6279) | 评论 (0)编辑 收藏
     摘要: 来到互联网公司,需要开发EJB程序,用两天的时间先学习了EJB的开发流程,我用的开发环境是myeclipse、jboss4.2、ejb3.0、struts1.3.8、jkd6、oracle、JPA,页面展现用到velocity。其实这不是一个春对ejb的学习文章,因为里面涉及了跟ejb无关的struts、velocity,如果单纯学习写ejb的helloword,数据库都不用连接,下面我描述下helloword程序的实现过程。
虽然技术含量不高,但写的很辛苦,需要占用首页一个位置。  阅读全文
posted @ 2014-05-28 15:28 杨爱友 阅读(5776) | 评论 (4)编辑 收藏
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="utf-8">
<style>

</style>
</head>

<body>
    <div>
        <div id="chartdiv1" style="width: 300px; height: 300px;float:left;border: 1px solid red;"></div>
        <div id="chartdiv2" style="width: 300px; height: 300px;float:right;border: 1px solid red;"></div>
        <div style="clear:left;"></div>

        <div id="chartdiv3" style="width: 300px; height: 300px;float:left;border: 1px solid blue;"></div>
        <div id="chartdiv4" style="width: 300px; height: 300px;float:right;border: 1px solid blue;"></div>
    </div>


</body>

</html>
posted @ 2013-10-09 16:25 杨爱友 阅读(1363) | 评论 (0)编辑 收藏
     摘要: 地心坐标系(geocentric cs、GEOCCS):以地球中心为原点,直接用X、Y、Z来进行位置的描述,无需模拟地球球面,常用在GPS中。
地理坐标系(geographic cs、GEOGCS):带Datum的椭球面坐标系,单位经度、纬度,高程用作第三维。参数:椭球体、基准面。
投影坐标系(projected cs、PROJCS):平面坐标系,单位米、英尺等,它用X(Easting)、Y(Northing)来描述地球上某个点的位置。它对应于某个地理坐标系,在UML中表示属于1对多的关系,1个地理坐标系经过不同的投影方式可产生多个投影坐标系。参数:地理坐标系、投影方式。  阅读全文
posted @ 2013-06-26 16:10 杨爱友 阅读(1361) | 评论 (0)编辑 收藏
1. 说出常用的GIS平台,arcgis的产品线?
2. 地理坐标系、投影坐标系和地心坐标系的概念?
3. 描述一下矢量数据和栅格数据,以及各自应用的领域?
posted @ 2013-06-26 15:53 杨爱友 阅读(191) | 评论 (0)编辑 收藏
【转自:http://www.blogjava.net/Alpha/archive/2009/06/27/284373.html
Flex中As调用Js的方法是:

     1、导入包 (import flash.external.ExternalInterface;)
     2、使用ExternalInterface.call("Js函数名称",参数)进行调用,其返回的值就是Js函数所返回的值
 
Js调用As的方法是:
     1、导入包 (import flash.external.ExternalInterface;)
     2、在initApp中使用ExternalInterface.addCallback("用于Js调用的函数名",As中的函数名)进行注册下
     3、js中 就可以用document.getElementById("Flas在Html中的ID").注册时设置的函数名(参数)进行调用
posted @ 2013-06-26 15:44 杨爱友 阅读(206) | 评论 (0)编辑 收藏
关于js中target与currentTarget的区别的关键在于他们所处在的事件流的阶段是不一样的,target处于事件流的目标阶段,currentTarget处理事件流的捕获、目标阶段和冒泡阶段。只有当他们同事处于目标阶段的时候他们的指向才是一样的,请看以下代码:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>js性能优化</title>
</head>
<body> 
    <div id="outer">
        outer
        <p>
            inner
        </p>
    </div>
</body>
<script type="text/javascript">
(
function(){
    
var a=document.getElementById('outer');
        a.addEventListener('click',
function(e){
        alert(e.target.innerHTML);
        alert(e.currentTarget.innerHTML);
        alert(e.currentTarget 
=== e.target);
    },
false);
})();
</script>
</html>
posted @ 2013-06-26 15:34 杨爱友 阅读(327) | 评论 (0)编辑 收藏

【转载自http://apps.hi.baidu.com/share/detail/33880627

  地质学范畴,是指平均海平面通过大陆延伸勾画出的一个封闭连续的封闭曲面。

  大地水准面是由静止海水面并向大陆延伸所形成的不规则的封闭曲面。它是重力等位面,即物体沿该面运动时,重力不做功(如水在这个面上是不会流动的)。大地水准面是描述地球形状的一个重要物理参考面,也是海拔高程系统的起算面。大地水准面的确定是通过确定它与参考椭球面的间距--大地水准面差距(对于似大地水准面而言,则称为高程异常)来实现的。大地水准面和海拔高程等参数和概念在客观世界中无处不在,在国民经济建设中起着重要的作用。

    其实,大地水准面也是一个很不规则的曲面,

  大地水准面包围的球体称为大地球体。大地球体的长半轴为6378.245公里,短半轴为6356.863公里。从大地水准面起算的陆地高度,称为绝对高度或海拔。

    用于尽可能与大地水准面密合的一个椭球曲面,是人为确定的。椭球体与大地基准面之间的关系是一对多的关系,也就是基准面是在椭球体基础上建立的,但椭球体不能代表基准面,同样的椭球体能定义不同的基准面,如前苏联的Pulkovo 1942、非洲索马里的Afgooye基准面都采用了Krassovsky椭球体,但它们的大地基准面显然是不同的。

    理解:椭球面和地球肯定不是完全贴合的,因而,即使用同一个椭球面,不同的地区由于关心的位置不同,需要最大限度的贴合自己的那一部分,因而大地基准面就会不同。

    地图坐标系由大地基准面和地图投影确定,大地基准面是利用特定椭球体对特定地区地球表面的逼近,因此每个国家或地区均有各自的大地基准面,我们通常称谓的北京54坐标系、西安80坐标系实际上指的是我国的两个大地基准面。我国参照前苏联从1953年起采用克拉索夫斯基(Krassovsky)椭球体建立了我国的北京54坐标系,1978年采用国际大地测量协会推荐的IAG 75地球椭球体建立了我国新的大地坐标系--西安80坐标系, 目前GPS定位所得出的结果都属于WGS84坐标系统,WGS84基准面采用WGS84椭球体,它是一地心坐标系,即以地心作为椭球体中心的坐标系。因此相对同一地理位置,不同的大地基准面,它们的经纬度坐标是有差异的。 

    一般我们所说的WGS84就是指那个基准面。

 

posted @ 2011-09-05 14:50 杨爱友 阅读(1443) | 评论 (0)编辑 收藏
     摘要: 新加行:这个帖子发帖8年来,已经为太多的朋友解决了问题,不用感谢我,请允许我在这里打个广告:美丽涵涵童装店,说我博客名字,给你们打折。
restlet入门、示例,赋有源码,下载可直接运行  阅读全文
posted @ 2011-07-22 16:39 杨爱友 阅读(8667) | 评论 (2)编辑 收藏
     摘要: JAVA体系结构包括四个独立但相关的部分:
java程序设计语言、Java class文件格式、Java应用编程接口API、Java虚拟机  阅读全文
posted @ 2011-06-01 22:57 杨爱友 阅读(353) | 评论 (0)编辑 收藏
     摘要: 今年10.18号,有幸参北京国际马拉松,这一兴奋的日子,终生难忘。
过程很累人,意义很重大,回忆很美好。明年我一定会再去。
  阅读全文
posted @ 2009-10-30 00:38 杨爱友 阅读(262) | 评论 (0)编辑 收藏
不知道各位用过ScriptX控件做过打印功能没有。我现在的情况是:
前段时间所有客户机打印都正常,最近几天,有部分客户陆续不能使用打印功能了,报脚本错误。
我这里现在是正常的,那么导致那些客户机不能打印的原因大概是什么呢?我机子是正常的。
posted @ 2009-08-14 15:11 杨爱友 阅读(2321) | 评论 (1)编辑 收藏
目前我的项目中系统生成了订单(JSP页面),这个订单要通过邮件发送给供应商,总不能粘一段html文字发给供应商吧。
于是考虑导出成excel,将excel文件发送出去,但客户觉得excel文件太容易更改,要求生成PDF或图片等不太容易改的文档。
现在的问题是:我如何生成这个PDF文档?
考虑过用iText,通过java创建PDF文档,但发现太繁琐了,在一天的时间内很难做出个像样的报表。
那么请问大侠们,我应该通过什么方式生成这个“不太容易改”的文档呢?
能否给点itext的一些资料或你们写过的代码。
posted @ 2009-06-19 01:40 杨爱友 阅读(2065) | 评论 (19)编辑 收藏
     摘要: 使用itext生成pdf  阅读全文
posted @ 2009-06-18 12:04 杨爱友 阅读(2777) | 评论 (0)编辑 收藏
     摘要: 使用itext生成pdf  阅读全文
posted @ 2009-06-15 23:34 杨爱友 阅读(1729) | 评论 (0)编辑 收藏
     摘要: struts1,webwork,struts2简介  阅读全文
posted @ 2009-06-09 17:15 杨爱友 阅读(318) | 评论 (0)编辑 收藏

开发模式为struts、hibernate、jstl等。
在一个项目中,涉及到很多字典型数据,如水库规模(大、中、小)、土壤类型(酸性、碱性、粘性)、工程类型(桥梁、水闸、公路)等。
那么在数据库中如何来存储这些字典型数据呢?若水库规模、土壤类型、工程类型等各建一张表,太繁琐了吧!若将他们都存到一张“字典”表中,那水库、土壤、工程表将不能设置外键,规模字段只能存储一个规模ID标志,在查询出水库列表后,在页面中只能获得各水库的规模ID,却无法获取规模的名称。
posted @ 2009-04-10 15:37 杨爱友 阅读(1464) | 评论 (2)编辑 收藏
开发模式为struts、hibernate、jstl等。
在一个项目中,涉及到很多字典型数据,如水库规模(大、中、小)、土壤类型(酸性、碱性、粘性)、工程类型(桥梁、水闸、公路)等。
那么在数据库中如何来存储这些字典型数据呢?若水库规模、土壤类型、工程类型等各建一张表,太繁琐了吧!若将他们都存到一张“字典”表中,那水库、土壤、工程表将不能设置外键,规模字段只能存储一个规模ID标志,在查询出水库列表后,在页面中只能获得各水库的规模ID,却无法获取规模的名称。
posted @ 2009-04-10 15:34 杨爱友 阅读(423) | 评论 (0)编辑 收藏


一、spring
1.ContextLoaderListener
   它作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。在ContextLoaderListener中关联了ContextLoader这个类,所以整个加载配置过程由ContextLoader来完成。ContextLoader创建的是 XmlWebApplicationContext这样一个类,它实现的接口是WebApplicationContext->ConfigurableWebApplicationContext->ApplicationContext->BeanFactory这样一来spring中的所有bean都由这个类来创建。如果在web.xml中不写任何参数配置信息,默认的路径是"/WEB-INF/applicationContext.xml,在WEB-INF目录下创建的xml文件的名称必须是applicationContext.xml。如果是要自定义文件名可以在web.xml里加入contextConfigLocation这个context参数:
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath*:spring/*.xml</param-value>
 </context-param>
2.default-autowire
      在spring容器内拼凑bean叫作装配。装配bean的时候,你是在告诉容器,需要哪些bean,以及容器如何使用依赖注入将它们配合在一起。而default-autowire设置了bean的默认装配方式。
我们常常使用<ref>标签为JavaBean注入它依赖的对象。但是对于一个大型的系统,这个操作将会耗费我们大量的资源,我们不得不花费大量的时间和精力用于创建和维护系统中的<ref>标签。我们可以通过指定autowire来让容器为受管JavaBean自动注入依赖对象。
byName:通过属性的名字的方式查找JavaBean依赖的对象并为其注入。比如说类UserAction有个属性userService,Spring IoC容器会在配置文件中查找id/name属性为userService的bean,然后使用Seter方法为其注入。
注意:在配置bean时,<bean>标签中Autowire属性的优先级比其上级标签<beans/>高,即是说,如果在上级标签中定义default-autowire属性为byName,而在<bean>中定义为byType时,Spring IoC容器会优先使用<bean>标签的配置。
3.default-lazy-init
  加载spring bean时,默认采用的延迟策略。
二、Hibernate
1.load和get
  a.如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个  ObjectNotFoundException。
  b.Load方法可返回实体的代理类实例,而get方法永远直接返回实体类。
  c.load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。
2.对象的三种状态
Hibernate的对象有3种状态,分别为:瞬时态(Transient)、 持久态(Persistent)、脱管态(Detached)。
  瞬时态:
由new命令开辟内存空间的java对象,
    如:Person person = new Person("xxx", "xx");
瞬时对象在内存孤立存在,不和数据库的数据有任何关联关系,在Hibernate中,可通过session的save()或saveOrUpdate()方法将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。

持久态:
     处于该状态的对象在数据库中具有对应的记录,并拥有一个持久化标识。如果是用hibernate的delete()方法,对应的持久对象就变成瞬时对象。

       当一个session执行close()或clear()、evict(po)之后,持久对象变成脱管对象,此时持久对象会变成脱管对象,此时该对象虽然具有数据库识别值,但它已不在HIbernate持久层的管理之下。

       持久对象具有如下特点:

       1. 和session实例关联;

       2. 在数据库中有与之关联的记录。

脱管态:
   当与某持久对象关联的session被关闭后,该持久对象转变为脱管对象。
       1. 本质上与瞬时对象相同,在没有任何变量引用它时,JVM会在适当的时候将它回收;

       2. 比瞬时对象多了一个数据库记录标识值。
2.名词解释
 a.persist把一个瞬态的实例持久化,但是并"不保证"标识符(identifier主键对应的属性)被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时候。
 b.clear完整的清除session缓存
 c.evcit(obj)把某个持久化对象从session的缓存中清空。
 d.persist只能持久化一个瞬时态的对象,
三、java
1.格式化日期
  SimpleDateFormat format = new SimpleDateFormat("yyyy年M月d日");
  format.format(date);
  用一个M、d则到月份日期为10一下时,只显示一位,避免出现01月02日的情况。
  年可以用四位也可以用二位。
2.JDBC操作
  a.连接数据库:
    Class.forName("net.sourceforge.jtds.jdbc.Driver").newInstance();
    Connection conn = DriverManager.getConnection(url, userName, password);
    Statement stmt = conn .getStatement();
    ResultSet rs = stmt.executeQuery(sql);
    while(rs.next()){
 System.out.println(rs.getInt("userId"));
 System.out.println(rs.getString("userName"));
    }

 


 

posted @ 2009-04-03 13:14 杨爱友 阅读(260) | 评论 (0)编辑 收藏
     摘要: 2008年就这样的走了, 时间过得太快了,太快了!  阅读全文
posted @ 2009-01-14 16:49 杨爱友 阅读(253) | 评论 (0)编辑 收藏
     摘要: 我向来宽宏大量,对人对社会一副很积极的心态,没有埋怨过谁,在同事中,你是第一个。
今天的事情,让我很郁闷,我不想以此来改变我对人、对事、对社会的态度,但这件事,我不会忘记,会作为一个警钟,时刻敲醒我昏沉沉的头脑。  阅读全文
posted @ 2009-01-08 00:09 杨爱友 阅读(287) | 评论 (0)编辑 收藏
     摘要: 新加行:这个帖子发帖8年来,已经为太多的朋友解决了问题,不用感谢我,请允许我在这里打个广告:美丽涵涵童装店,说我博客名字,给你们打折。
Spring,hibernate,struts的面试笔试题(含答案)  阅读全文
posted @ 2008-12-16 07:57 杨爱友 阅读(4134) | 评论 (0)编辑 收藏
     摘要: supermap QQ群:4578330,欢迎加入!   阅读全文
posted @ 2008-12-16 06:59 杨爱友 阅读(1554) | 评论 (2)编辑 收藏
     摘要: Java编程经验汇总

绝对好文,转载的!

一个计算机专业学生几年的编程经验汇总

绝对好文,该系列一共11篇,斑竹可以考虑置顶,各位坛友看完之后,java基础绝对有不小的提升!
  阅读全文
posted @ 2008-12-12 11:47 杨爱友 阅读(3704) | 评论 (4)编辑 收藏
     摘要: 根据刚刚学习的心理体会总结出的配置流程,里面介绍了Flex工程的建立,远程方法调用的配置等相关知识,附有的demo源文件,可以自行下载。其他要用到的一些包、开发工具,如果有需要,可QQ我。  阅读全文
posted @ 2008-12-02 07:23 杨爱友 阅读(3527) | 评论 (4)编辑 收藏
     摘要: 使用对象:初次接触Arcgis,没有安装配置过Arcgis、servlet的初学者。  阅读全文
posted @ 2008-11-28 11:30 杨爱友 阅读(2427) | 评论 (0)编辑 收藏
     摘要: 关于类加载的问题。为什么打印结果是1和0呢?  阅读全文
posted @ 2008-10-28 15:26 杨爱友 阅读(1373) | 评论 (9)编辑 收藏
     摘要: 最近项目要开发大量报表,要找一个合适的报表工具。要使用户能够在客户端,根据需要定制待打印报表的样式和要显示的字段内容。求各位朋友推荐一款免费的报表定制工具。  阅读全文
posted @ 2008-10-28 09:50 杨爱友 阅读(286) | 评论 (1)编辑 收藏
     摘要: 要娶媳妇儿啦  阅读全文
posted @ 2008-10-26 00:22 杨爱友 阅读(499) | 评论 (5)编辑 收藏
     摘要: 转载于【http://www.blogjava.net/JAVA-HE/archive/2008/10/17/235066.html】  阅读全文
posted @ 2008-10-22 11:58 杨爱友 阅读(255) | 评论 (0)编辑 收藏
     摘要: 怎么判断用户对当前页面只有查询权限,而不能做“修改、删除”等操作。  阅读全文
posted @ 2008-10-22 11:44 杨爱友 阅读(2073) | 评论 (12)编辑 收藏
     摘要: 转载于【http://java.chinaitlab.com/line/373702.html】
一个进程就是一个执行中的程序,而每一个进程都有自己独立的一块内存空间,一组系统资源.在进程概念中,每一个进程的内部数据和状态都是完全独立的。线程与进程相似,是一段完成某个特定功能的代码,是程序中单个顺序的流控制;但与进程不同的是,同类的多个线程是共享一块内存空间和一组系统资源。  阅读全文
posted @ 2008-10-21 00:35 杨爱友 阅读(1584) | 评论 (0)编辑 收藏
     摘要: Spring提供了一个发送电子邮件的高级抽象层,它向用户屏蔽了底层邮件系统的一些细节,同时负责低层次的代表客户端的资源处理。Spring邮件抽象层的主要包为org.springframework.mail。它包括了发送电子邮件的主要接口MailSender和 封装了简单邮件的属性如from, to,cc, subject, text的值对象叫做SimpleMailMessage。
首先:我们定义一个发送邮件的接口:IMailManager.java。
  阅读全文
posted @ 2008-10-20 00:12 杨爱友 阅读(1345) | 评论 (1)编辑 收藏
     摘要: 各种企业应用几乎都会碰到任务调度的需求,就拿论坛来说:每隔半个小时生成精华文章的RSS文件,每天凌晨统计论坛用户的积分排名,每隔30分钟执行锁定用户解锁任务。对于一个典型的MIS系统来说,在每月1号凌晨统计上个月各部门的业务数据生成月报表,每半个小时查询用户是否已经有快到期的待处理业务……,这样的例子俯拾皆是,不胜枚举。
Quartz 在开源任务调度框架中的翘首,它提供了强大任务调度机制,难能可贵的是它同时保持了使用的简单性。Spring进一步降低了使用Quartz的难度,能以更具Spring风格的方式使用Quartz。  阅读全文
posted @ 2008-10-18 22:58 杨爱友 阅读(25208) | 评论 (9)编辑 收藏
     摘要:
1.public、protected、private以及默认类型变量作用域考查;
2.String类型对象创建及内存分配知识;
3.set与list唯一性考查;
4.构造函数的调用顺序;
5.java参数传递;  阅读全文
posted @ 2008-10-17 23:24 杨爱友 阅读(397) | 评论 (0)编辑 收藏
     摘要:
1. this指针是一个动态变化的变量,它表明了当前运行该函数的对象;
2. 一个方法(集合元素)由谁调用,this指针就指向谁;
3. 对象名可以起到一个命名空间的作用。

  阅读全文
posted @ 2008-08-06 22:33 杨爱友 阅读(727) | 评论 (0)编辑 收藏

一种配置情况是:

<convert converter="bean" match="com.hengyu.bean.project.*" />

大家都知道,当hibernate里面配置上lazy="true"时,查询对象A时,不会去查询于A相关联的B、C、D等对象,只要取B、C、D中属性值时,才会去查询。但是hibernate配合DWR时,这个lazy属性好象不起作用,只要一查询,就会把于之相关联的属性全部加载,执行一个方法,竟然有上百条HQL语句,使效率极其低下。
另一种配置是:

<convert converter="hibernate3" match="com.hengyu.bean.project.*" />
这样的话效率很快,但是当我去于A相关联的B、C等表里的属性时,却取不到。配置了opensessioninview,其他表中的属性仍然取不到。郁闷了半月了,请高手指教。
posted @ 2007-12-10 22:20 杨爱友 阅读(1318) | 评论 (2)编辑 收藏
     摘要: 如果一个人爱你  阅读全文
posted @ 2007-11-26 21:32 杨爱友 阅读(495) | 评论 (4)编辑 收藏
     摘要: 思想不积极,发布一天就关了。  阅读全文
posted @ 2007-10-16 16:29 杨爱友 阅读(370) | 评论 (9)编辑 收藏
     摘要: 这两周没做啥事情,却很累,心很累,不是没事情做,有,却不知道怎么做,头很痛,心很累,书不看了,博客也不写了。  阅读全文
posted @ 2007-09-26 00:12 杨爱友 阅读(433) | 评论 (12)编辑 收藏
     摘要: 由前端控制器负责判断用户的请求要分派给哪一个控制对象,借此达到控制用户请求资源的目的。  阅读全文
posted @ 2007-09-09 23:17 杨爱友 阅读(550) | 评论 (1)编辑 收藏
     摘要: 小小一篇总结、计划  阅读全文
posted @ 2007-09-09 05:32 杨爱友 阅读(335) | 评论 (3)编辑 收藏
     摘要: Spring AOP中的一些概念及Before Advice实例解析  阅读全文
posted @ 2007-09-06 00:06 杨爱友 阅读(1451) | 评论 (4)编辑 收藏
     摘要: 代理模式:为其他对象提供一种代理以控制对这个对象的访问。这种功能只有在编译无法确定要实现哪个接口时才有必要使用。  阅读全文
posted @ 2007-09-04 01:15 杨爱友 阅读(778) | 评论 (0)编辑 收藏
     摘要: 有关spring 几个重要的概念理解和两个IoC实例解析  阅读全文
posted @ 2007-09-04 00:22 杨爱友 阅读(1384) | 评论 (6)编辑 收藏
     摘要: 系型数据库之所以强大,其中一个原因就是可以统一使用表来管理同类数据信息,并且可以在相关数据之间建立关系。作为支持关系型数据库的SQL语句来说,自然要对全面发挥这种强大功能提供支持,这个支持就是连接查询。同样作为一种关系型数据库的持久层框架,  阅读全文
posted @ 2007-08-31 21:46 杨爱友 阅读(616) | 评论 (0)编辑 收藏
简介:

  我看到很多项目中,开发者实现了自己的MVC框架,并不是因为他们想做同Struts根本不同的东西,而是因为他们并没有意识到如何扩展Struts。开发自己的MVC框架可以获得全部的控制权,但是这也意味着需要很多资源来实现它(人力物力),在紧张的日程安排下,有时候这是不可能的。

  Struts不仅仅是一个强大的框架,同时它也是可扩展的。你可以以三种方式来扩展Struts。

  1、PlugIn:如果你想在application startup或shutdown的时候做一些业务逻辑的话,那就创建你自己的PlugIn类。

  2、RequestProcessor:如果你想在请求被处理的过程中某个时刻做一些业务逻辑的话,那么创建你自己的RequestProcessor类。比如说,在每次请求执行之前,你可以扩展RequestProcessor来检查用户是否登陆了以及他是否有权限去执行某个特定的action。

  3、ActionServlet:如果你想在application startup和shutdown的时候以及请求被处理的时候做某些业务逻辑,你也可以扩张ActionServlet类。不过你应当在PlugIn和RequestProcessor都不能解决你的需求的时候来使用ActionServlet。

  在这篇文章中,我们将使用一个Struts应用的示例来示范如何使用这三种方式来扩展Struts。示例程序的代码可以从http://www.onjava.com/onjava/2004/11/10/examples/sample1.zip下载。两个扩展Struts成功的范例是Struts自身的Validation和Tiles框架。

  我们假设你已经比较熟悉Struts框架并且知道如何使用它创建一个简单的应用。如果你想知道更多关于Struts的内容,请参考官方主页。

  PlugIn
  
  PlugIn是一个接口,你可以创建一个实现该接口的类,当application startup或shutdown的时候做些事情。

  比方说,我创建了一个使用Hibernate作为持久层的web应用,我想当应用启动的时候就初始化Hibernate,这样子当我的web应用受到第一个请求的时候,Hibernate就已经是配置好的并且可用的。同时我们想当application关闭的时候关闭Hibernate。我们可以用一个Hibernate PlugIn来实现这个需求,通过如下的两步:

  1、创建一个类实现了PlugIn接口

  public class HibernatePlugIn implements PlugIn{
  private String configFile;
  // This method will be called at application shutdown time
  public void destroy() {
  System.out.println("Entering HibernatePlugIn.destroy()");
  //Put hibernate cleanup code here
  System.out.println("Exiting HibernatePlugIn.destroy()");
  }
  //This method will be called at application startup time
  public void init(ActionServlet actionServlet, ModuleConfig config)
  throws ServletException {
   System.out.println("Entering HibernatePlugIn.init()");
   System.out.println("value of init parameter " +
   getConfigFile());
   System.out.println("Exiting HibernatePlugIn.init()");
  }
  public String getConfigFile() {
  return name;
  }
  public void setConfigFile(String string) {
  configFile = string;
  }
  }

  实现PlugIn接口的类必须完成两个方法:init()和destroy()。当application startup的时候init()方法被调用,当shutdown的时候destroy()方法被调用。Struts还允许给你的PlugIn类传递初始化参数。为了传递参数,你必须在PlugIn类中为每一个参数创建JavaBean式的setter方法。在我们的HibernatePlugIn类中,我会把configFile的name作为参数传进去,而不是硬编码到程序中。

  2、在struts-config.xml中添加如下的代码来通告Struts有新的PlugIn:

  <struts-config>
  ...
  <!-- Message Resources -->
  <message-resources parameter= "sample1.resources.ApplicationResources"/>

  <!-- Declare your plugins -->
  <plug-in className="com.sample.util.HibernatePlugIn">
  <set-property property="configFile" value="/hibernate.cfg.xml"/>
  </plug-in>
  </struts-config>

  属性className是实现了PlugIn接口的类的全限定名。对于每一个初始化参数,可以使用<set-property>元素传递参数。在我们的例子中,我要把config文件的名字传进去,所以使用了一个带有配置文件路径的<set-property>。

  Struts的Tiles和Validator框架都使用PlugIn来读取配置文件进行初始化。另外两件PlugIn可以帮你做到的事情是:

  ·如果你的application依赖于某些配置文件,那么你可以在PlugIn类中检查它们是否可用,如果不可用的话抛出一个ServletException,这样就可以使ActionServlet变为不可用。

  ·PlugIn接口的init()方法是你可以改变ModuleConfig的最后机会,ModuleConfig是一组静态配置信息的集合,用来描述基于Struts模块。Struts将会在所有PlugIn处理完后释放ModuleConfig。
   Request是如何被处理的

  ActionServlet是Struts框架中唯一的Servlet,它负责处理所有request。无论何时接收到一个request,它都会先尝试为当前的request寻找一个sub-application。一旦一个sub-application被找到,ActionServlet就会为那个sub-application创建一个RequestProcessor对象,调用这个对象的process()方法并把HttpServletRequest和HttpServletResponse对象传入。

  RequestProcessor.process()就是大部分request被处理的地方。process()方法使用了Template Method模式实现,其中有很多独立的方法来执行请求处理的每一步骤,这些方法将会在process方法中依次被调用。比如,将会有一个独立的方法用来寻找当前request对应的ActionForm类,一个方法来检查当前用户是否有执行action mapping所必须的权限。这些给与我们极大的灵活性。在发布的Struts包中有一个RequestProcessor类提供了请求处理每一步骤的默认实现。这就意味着你可以仅仅重写你感兴趣的方法,其它的使用默认的实现。举例来说,默认地Struts调用request.isUserInRole()来检查用户是否有权限执行当前的ActionMapping;这时如果你想通过查询数据库来实现,你所要做的就是重写processRoles()方法,通过查询出的用户是否拥有必须的权限来返回true或false。

  首先我们将会看到缺省情况下,process()方法是如何实现的,然后我将会详细解释默认的RequestProcessor类中的每一个方法,这样你就可以决定哪一部分是你想要改变的。

  public void process(HttpServletRequest request,HttpServletResponse response)
  throws IOException, ServletException {
  // Wrap multipart requests with a special wrapper
  request = processMultipart(request);
  // Identify the path component we will
  // use to select a mapping
  String path = processPath(request, response);
  if (path == null) {
  return;
  }
  if (log.isDebugEnabled()) {
  log.debug("Processing a '" + request.getMethod() + "' for path '" + path + "'");
  }
  // Select a Locale for the current user if requested
  processLocale(request, response);
  // Set the content type and no-caching headers
  // if requested
  processContent(request, response);
  processNoCache(request, response);
  // General purpose preprocessing hook
  if (!processPreprocess(request, response)) {
  return;
  }
  // Identify the mapping for this request
  ActionMapping mapping =
  processMapping(request, response, path);
  if (mapping == null) {
  return;
  }
  // Check for any role required to perform this action
  if (!processRoles(request, response, mapping)) {
  return;
  }
  // Process any ActionForm bean related to this request
  ActionForm form = processActionForm(request, response, mapping);
  processPopulate(request, response, form, mapping);
  if (!processValidate(request, response, form, mapping)) {
  return;
  }
  // Process a forward or include specified by this mapping
  if (!processForward(request, response, mapping)) {
  return;
  }
  if (!processInclude(request, response, mapping)) {
  return;
  }
  // Create or acquire the Action instance to
  // process this request
  Action action =
  processActionCreate(request, response, mapping);
  if (action == null) {
  return;
  }
  // Call the Action instance itself
  ActionForward forward = processActionPerform(request, response,action, form, mapping);
  // Process the returned ActionForward instance
  processForwardConfig(request, response, forward);
  }

  1、processMutipart():在这个方法中,Struts将会读取request来检查request的contentType是否是multipart/form-data。如果是的话,将会解析request并且将之包装到HttpServletRequest中。当你创建了一个HTML FORM用来提交数据,那么request的contentType默认就是application/x-www-form-urlencoded。但是如果你的form使用了file类型的input控件允许用户上传文件的话,你就必须将contentType改为multipart/form-data。如果是这样的情况,你就不能再通过getParameter()来获取用户提交的数据;你必须将request作为一个InputStream来读取,并且自己解析它来获得参数值。

  2、processPath():在这个方法中,Struts将会读取request的URI,来确定路径元素,这个元素是用来获取ActionMappint元素。
  3、processLocale():在这个方法中,Struts将会为当前request取得Locale,如果配置过的话,还可以将这个对象作为HttpSession中org.apache.struts.action.LOCALE属性的值而保存。作为这个方法的副作用,HttpSession将会被创建,如果你不想创建的话,你可以在ControllerConfig中将locale属性设为false,在struts-config.xml中象如下这样:

  <controller>
  <set-property property="locale" value="false"/>
  </controller>

  4、processContent():通过调用response.setContentType()来为response设置contentType。这个方法首先会尝试从struts-config.xml配置中得到contentType。缺省情况下使用text/html。如果想覆盖它,可以象如下这样:

  <controller>
  <set-property property="contentType" value="text/plain"/>
  </controller>

  5、processNoCache():如果配置是no-cache,Struts将会为每个response设置下面三个headers:

  requested in struts config.xml
  response.setHeader("Pragma", "No-cache");
  response.setHeader("Cache-Control", "no-cache");
  response.setDateHeader("Expires", 1);

  如果你想设置no-cache header,在struts-config.xml中加入下面信息:

  <controller>
  <set-property property="noCache" value="true"/>
  </controller>

  6、processPreprocess():这个方法为预处理提供一个hook,可以在子类中覆盖它。它的缺省实现没有作任何事情,总是返回true。返回false的话将会终止当前请求的处理。

  7、processMapping():这个方法将会用路径信息得到一个ActionMapping对象。也就是struts-config.xml文件中的<action>元素:

  <action path="/newcontact" type="com.sample.NewContactAction" name="newContactForm" scope="request">
  <forward name="sucess" path="/sucessPage.do"/>
  <forward name="failure" path="/failurePage.do"/>
  </action>

  ActionMapping元素包含了Action类的名称和处理请求使用的ActionForm等等信息。它还包含当前ActionMapping配置的ActionForwards信息。

  8、processRoles():Struts web应用提供了一个授权方案。也就是说,一旦一个用户登入了容器,struts的processRoles()方法将会通过调用request.isUserInRole(),来检查他是否有必须的角色来运行一个给定的ActionMapping。

  <action path="/addUser" roles="administrator"/>

  假设你有一个AddUserAction并且你只想让administrator能够增加新的user。你所要做的就是给你的AddUserAction元素增加一个role属性,这个属性的值为administrator。这样,在运行AddUserAction之前,这个方法会确保用户拥有administraotr的角色。

  9、processActionForm():每一个ActionMapping都一个相应的ActionForm类。当Struts处理一个ActionMapping的时候,它将会从<action>元素的name属性中找出对应的ActionForm类的名称。

  <form-bean name="newContactForm" type="org.apache.struts.action.DynaActionForm">
  <form-property name="firstName" type="java.lang.String"/>
  <form-property name="lastName" type="java.lang.String"/>
  </form-bean>

  在我们的例子中,它会先在request scope中检查是否有一个org.apache.struts.action.DynaActionForm类的对象存在。如果有它将会使用这个对象,如果没有它将会创建一个新的对象并把它设置在request scope。

  10、processPopulate():在这个方法中,Struts将会用相匹配的request参数装配ActionForm的实例变量。

  11、processValidate():Struts将会调用你的ActionForm类的validate方法。如果你从validate()返回ActionErrors,它将会将user重定向到<action>元素的input属性指定的页面。

  12、processForward()和processInclude():在这些方法中,Struts将会检查<action>元素的forward或include属性,如果找到了,将会把forward或include请求放置到配置的页面中。

  <action forward="/Login.jsp" path="/loginInput"/>
  <action include="/Login.jsp" path="/loginInput"/>

  你可以从这些方法的名字上猜测它们的不同:processForward()最终调用RequestDispatcher.forward(),而processInclude()调用RequestDispatcher.include()。如果你同时配置了forward和include属性,它将会总是调用forward,因为forward先被处理。

  13、processActionCreate():这个方法从<action>元素的type属性中获取获得Action类的名字并且创建返回它的实例。在我们的例子中,它将会创建一个com.sample.NewContactAction类的实例。

  14、processActionPerform():这个方法调用你的Action类的excute()方法,你的业务逻辑也就是在excute方法中。

  15、processForwardConfig():你的Action类的excute()方法将会返回一个ActionForward对象,这个对象将指出哪个页面是显示给用户的页面。因此,Struts将会为那个页面创建一个RequestDispatcher,并且调用RequestDispatcher.forward()。

  上面的列表说明了默认的RequestProcessor实现在处理请求时每一步作的工作,以及执行的顺序。正如你所看到的,RequestProcessor是非常灵活的,允许你通过设置<controller>元素的属性来配置它。举例来说,如果你的应用准备生成XML内容来代替HTML,你就可以通过设置controller元素的属性来通知Struts这些情况。
  
  创建你自己的RequestProcessor

  通过上面,我们了解到了RequestProcessor的默认实现是如何工作的。现在我们要演示一个例子来说明如何定制你自己的RequestProcessor。为了展示创建用户定制的RequestProcessor,我们将会让我们的示例实现下面两个业务需求:

  ·我们想创建一个ContactImageAction类,它将生成图片而不是平常的HTML页面。

  ·在每个请求处理之前,我们都想通过检查session中的userName属性来确定用户是否已经登陆。如果那个属性没有找到,我们会把用户重定向到登陆页面。

  我们将分两步实现这些业务需求。

  1、创建你的CustomRequestProcessor类,它将继承自RequestProcessor类,如下:

  public class CustomRequestProcessor
  extends RequestProcessor {
  protected boolean processPreprocess (
  HttpServletRequest request,HttpServletResponse response) {
   HttpSession session = request.getSession(false);
   //If user is trying to access login page
   // then don't check
   if( request.getServletPath().equals("/loginInput.do")
  || request.getServletPath().equals("/login.do") )
    return true;
   //Check if userName attribute is there is session.
   //If so, it means user has allready logged in
   if( session != null && session.getAttribute("userName") != null)
    return true;
   else{
    try{
     //If no redirect user to login Page
     request.getRequestDispatcher("/Login.jsp").forward(request,response);
    }catch(Exception ex){
    }
   }
   return false;
  }

  protected void processContent(HttpServletRequest request,
  HttpServletResponse response) {
  //Check if user is requesting ContactImageAction
  // if yes then set image/gif as content type
  if( request.getServletPath().equals("/contactimage.do")){
   response.setContentType("image/gif");
   return;
  }
   super.processContent(request, response);
  } 
  }

  在CustomRequestProcessor类的processPreprocess方法中,我们检查session的userName属性,如果没有找到,就将用户重定向到登陆页面。

  对于生成图片作为输出的需求,我们必须覆盖processContent方法,首先检查请求是否是/contactimage路径。如果是的话,我们就会将contentType设置为image/gif;否则设置为text/html。

  2、在你的struts-config.xml文件的<action-mappint>元素之后加入下面的文字,告诉Struts CustomRequestProcessor应当被用作RequestProcessor类:

  <controller>
  <set-property property="processorClass"value="com.sample.util.CustomRequestProcessor"/>
  </controller>

  请注意,当你只有很少的action类需要生成非text/html类型的输出时,你覆写processContent()方法是OK的。如果不是这样子的话,你应该创建一个Struts的子应用来处理请求生成图片的Action,并为它们将contentType设置为image/gif。

  Struts的Tiles框架就是使用它自己的RequestProcessor来装饰Struts的输出。

  ActionServlet

  如果你查看你的Struts web应用的web.xml,你会看到这样的文字:

  <web-app >
  <servlet>
  <servlet-name>action=</servlet-name>
  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
  <!-- All your init-params go here-->
  </servlet>
  <servlet-mapping>
  <servlet-name>action</servlet-name>
  <url-pattern>*.do</url-pattern>
  </servlet-mapping>
  </web-app >

  这意味着ActionServlet负责处理你所有Struts的请求。你可以创建一个ActionServlet的子类,当应用启动,关闭,每个请求的时候做一些特定的事情。但是在继承ActionServlet类之前,你应该尽量创建一个PlugIn或RequestProcessor去解决你的问题。在Servlet1.1之前,Tiles框架是基于ActionServlet来修饰生成的响应。但是从1.1之后,它开始使用TilesRequestProcessor类。

  总结

  决定开发你自己的MVC框架是一个非常大的决定,你必须要考虑开发和维护框架代码所花费的时间和资源。Struts是一个非常强大和稳定的框架,你可以修改它来满足你绝大多数的业务需求。

  但另一方面,也不要草率地做出扩展Struts的决定。如果你在RequestProcessor中写了一些性能比较低的代码,它将会在每次请求时执行,因而降低你整个应用的效率。而且还是有一些情况,开发自己的MVC框架要比扩展Struts好。
posted @ 2007-08-31 12:42 杨爱友 阅读(1674) | 评论 (0)编辑 收藏
美丽涵涵童装店
亲,说我博客名字,给你们打折!