软件是对质量的不懈追求

#

HTTP Referer二三事

什么是HTTP Referer

简言之,HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器 籍此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。

Referer其实应该是英文单词Referrer,不过拼错的人太多了,所以编写标准的人也就将错就错了。

我的问题

我刚刚把feed阅读器改变为Gregarius,但他不像我以前用的liferea,访问新浪博客的时候,无法显示其中的图片,提示“此图片仅限于新浪博客用户交流与沟通”,我知道,这就是HTTP Referer导致的。

由于我上网客户端配置的特殊性,首先怀疑是squid的问题,但通过实验排除了,不过同时发现了一个Squid和Tor、Privoxy协同使用的隐私泄露问题,留待以后研究。

Gregarius能处理这个问题么?

答案是否定的,因为Gregarius只是负责输出html代码,而对图像的访问是有客户端浏览器向服务器请求的。

不过,安装个firefox扩展也许能解决问题,文中推荐的”Send Referrer”我没有找到,但发现另外一个可用的:”RefControl“,可以根据访问网站的不同,控制使用不同的Referer。

但是我不喜欢用Firefox扩展来解决问题,因为我觉得他效率太低,所以我用更好的方式——Privoxy。

Privoxy真棒

在Privoxy的default.action中添加两行:

{+hide-referrer{forge}}

.album.sina.com.cn

这样Gregarius中新浪博客的图片就出来了吧?+hide-referrer是Privoxy的一个过滤器,设置访问时对HTTP Referer的处理方式,后面的forge代表用访问地址当作Refere的,还可以换成block,代表取消Referer,或者直接把需要用的Referer网址写在这里。

用Privoxy比用Firefox简单的多,赶紧吧。

From https to http

我还发现,从一个https页面上的链接访问到一个非加密的http页面的时候,在http页面上是检查不到HTTP Referer的,比如当我点击自己的https页面下面的w3c xhtml验证图标(网址为http://validator.w3.org/check?uri=referer),从来都无法完成校验,提示:

No Referer header found!

原来,在http协议的rfc文档中有定义:

15.1.3 Encoding Sensitive Information in URI's



...



Clients SHOULD NOT include a Referer header field in a (non-secure)

HTTP request if the referring page was transferred with a secure

protocol.

这样是出于安全的考虑,访问非加密页时,如果来源是加密页,客户端不发送Referer,IE一直都是这样实现的Firefox浏览器也不例外。但这并不影响从加密页到加密页的访问。

Firefox中关于Referer的设置

都在里,有两个键值:

  • network.http.sendRefererHeader (default=2)
    设置Referer的发送方式,0为完全不发送,1为只在点击链接时发送,在访问页面中的图像什么的时候不发送,2为始终发送。参见Privacy Tip #3: Block Referer Headers in Firefox

  • network.http.sendSecureXSiteReferrer (default=true)
    设置从一个加密页访问到另外一个加密页的时候是否发送Referer,true为发送,false为不发送。

利用Referer防止图片盗链

虽然Referer并不可靠,但用来防止图片盗链还是足够的,毕竟不是每个人都会修改客户端的配置。实现一般都是通过apache的配置文件,首先设置允许访问的地址,标记下来:

# 只允许来自domain.com的访问,图片可能就放置在domain.com网站的页面上

SetEnvIfNoCase Referer "^http://www.domain.com/" local_ref

# 直接通过地址访问

SetEnvIf Referer "^$" local_ref

然后再规定被标记了的访问才被允许:

<FilesMatch ".(gif|jpg)">

Order Allow,Deny

Allow from env=local_ref

</FilesMatch>

或者

<Directory /web/images>

Order Deny,Allow

Deny from all

Allow from env=local_ref

</Directory>

这方面的文章网上很多,参考:

不要使用Rerferer的地方

不要把Rerferer用在身份验证或者其他非常重要的检查上,因为Rerferer非常容易在客户端被改变,不管是通过上面介绍的Firefox扩展,或者是Privoxy,甚至是libcurl的调用,所以Rerferer数据非常之不可信。

如果你想限制用户必须从某个入口页面访问的话,与其使用Referer,不如使用session,在入口页面写入session,然后在其他页面检查,如果用户没有访问过入口页面,那么对应的session就不存在,参见这里的讨论。不过和上面说的一样,也不要过于相信这种方式的“验证”结果。

个人感觉现在Rerferer除了用在防盗链,其他用途最多的就是访问统计,比如统计用户都是从哪里的链接访问过来的等等。

posted @ 2009-11-14 13:41 BlakeSu 阅读(405) | 评论 (0)编辑 收藏

StringTemplate语法

1 变量替换
public static void fun1() {
  StringTemplate st = new StringTemplate(
    "对象变量替换 姓名:$KeyList.Name$, 年龄:$KeyList.Age$ ");
  HashMap ht = new HashMap();
  ht.put("Name", "李四");
  ht.put("Age", "35");
  st.setAttribute("KeyList", ht);
  System.out.print(st.toString());
 }
2 自定义集合替换
public static void fun2() {
  StringTemplate st = new StringTemplate(
    "自定义集合替换 $List:{姓名:$it.Name$ 年龄:$it.Age$}$");
  st.setAttribute("List.{Name,Age}", "王二", "29");
  System.out.print(st.toString());

 }
3 对象变量替换
定义类
private static class User {
  String name;
  String age;

  public String getName() {
   return name;
  }

  public void setName(String name) {
   this.name = name;
  }

  public String getAge() {
   return age;
  }

  public void setAge(String age) {
   this.age = age;
  }
 }
public static void fun3() {
  User us = new User();
  us.name = "张三";
  us.age = "23";
  List<User> uss = new ArrayList<User>();
  uss.add(us);
  uss.add(us);
  uss.add(us);
  uss.add(us);
  uss.add(us);
  StringTemplate st = new StringTemplate(
    "<table>$Item:{<tr class=black><td>$it.name$</td></tr>},{<tr class=red><td>$it.age$</td></tr>};separator=\"\n\"$</table>");
  st.setAttribute("Item", uss);
  System.out.print(st.toString());
 }
   交叉替换
 public static void fun4() {
  User us = new User();
  us.name = "张三";
  us.age = "23";
  List<User> uss = new ArrayList<User>();
  uss.add(us);
  uss.add(us);
  uss.add(us);
  uss.add(us);
  uss.add(us);

  StringTemplateGroup sg = new StringTemplateGroup("GroupTest");
  sg.defineTemplate("RowRed",
    "<tr class=red><td>$it.Name$</td><td>$it.Age$</td></tr>\n");
  sg.defineTemplate("Rowblack",
    "<tr class=black><td>$it.Name$</td><td>$it.Age$</td></tr>\n");
  StringTemplate st = sg.defineTemplate("List",
    "<table>$Item:RowRed(),Rowblack()$</table>");
  st.setAttribute("Item", uss);
  System.out.print(st.toString());
 }
4 条件判断
public static void fun5() {
  StringTemplate st = new StringTemplate(
    "当前用户登陆状态: $if(IsAdmin)$ 用户登陆成功! $else$ 用户没有登陆! $endif$");
  st.setAttribute("IsAdmin", true);
  System.out.print(st.toString());
 }
5 sql语句实现
  theQuery.st内容
  SELECT $column; separator=","$ FROM $table$;
  public static void fun6() {
  // 一个sql语句的实现
  StringTemplateGroup group = new StringTemplateGroup("myGroup", "c:/");
  StringTemplate query = group.getInstanceOf("theQuery");
  query.setAttribute("column", "name");
  query.setAttribute("column", "email");
  query.setAttribute("table", "User");
  System.out.print(query.toString());
 }
6 使用AttributeRenderer
  private static class DateRenderer implements AttributeRenderer {
  public String toString(Object o) {
   SimpleDateFormat f = new SimpleDateFormat("yyyy.MM.dd");
   return f.format(((Calendar) o).getTime());
  }
 }
public static void fun7() {
  StringTemplate st = new StringTemplate("date: <created>",
    AngleBracketTemplateLexer.class);
  st.setAttribute("created", new GregorianCalendar(2005, 07 - 1, 05));
  st.registerRenderer(GregorianCalendar.class, new DateRenderer());

  String result = st.toString();

  System.out.print(result.toString());
 }

posted @ 2009-11-14 13:40 BlakeSu 阅读(1226) | 评论 (0)编辑 收藏

打开Windows命令行自动补齐功能

Linux上习惯了自动补全功能,在Windows上还真有些不习惯,好在微软也体谅我们大家,通过修改注册表可以实现此功能。HKEY_LOCAL_MACHINE-->Software-->Microsoft-->Command Prosessor-->PathCompletionChar的键值改为9(16进制)后,在Dos窗口中就可以使用自动补齐功能了。

posted @ 2009-11-14 13:39 BlakeSu 阅读(284) | 评论 (0)编辑 收藏

面向对象的特征

1.抽象:
抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。
2.继承:
继 承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继 承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增 加新的方法使之更适合特殊的需要。
3.封装:
封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
4.多态性:
多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。

posted @ 2009-11-14 13:38 BlakeSu 阅读(166) | 评论 (1)编辑 收藏

Oracle移动数据库文件

Oracle数据库由数据文件,控制文件和联机日志文件三种文件组成。
由于磁盘空间的变化,或者基于数据库磁盘I/O性能的调整等,我們可能会考虑移动数据库文件。(注:恢复数据库时非常有用,属于冷备份)
查询当前数据库中,相关文件路径
select * from v$datafile;
select * from v$controlfile;
select * from v$logfile;
根据以上路径,找到当前数据库相应文件路径。
一.移动数据文件:
可以用ALTER DATABASE,ALTER TABLESPACE两种方法移动数据文件。
1. ALTER DATABASE方法;
-- 用此方法,可以移动任何表空间的数据文件。
STEP 1. 停数据库:
  sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> SHUTDOWN;
SQL> EXIT;
STEP 2.用操作系统命令移动数据文件:
    将数据文件 'test.dbf' 从/ora/oracle/data1目录移动到/ora/oracle/data2目录下:
mv /ora/oracle/data1/test.dbf /ora/oracle/data2
STEP 3. Mount数据库,用ALTER DATABASE命令将数据文件改名:
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> STARTUP MOUNT;
SQL> ALTER DATABASE RENAME FILE '/ora/oracle/data1/test.dbf' TO '/ora/oracle/data2/test.dbf';
STEP 4. 打开数据库:.
SQL> ALTER DATABASE OPEN;
SQL>SELECT NAME,STATUS FROM V$DATAFILE;
2. ALTER TABLESPACE方法:
   用此方法,要求此数据文件既不属于SYSTEM表空间,也不属于含有ACTIVE回滚段或临时段的表空间。觉得麻烦,省略不用了。
二. 移动控制文件:
   控制文件 在 INIT.ORA文件中指定。移动控制文件相对比较简单,下数据库,
   编辑INIT.ORA,移动控制文件,重启动数据库。
STEP 1. 停数据库:
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> SHUTDOWN;
SQL> EXIT;
STEP 2.用操作系统命令 移动控制文件:
--将控制文件'ctl3orcl.ctl' 从/ora/oracle/data1目录移动到/ora/oracle/data2目录下:
mv /ora/oracle/data1/ctl3orcl.ctl /ora/oracle/data2
STEP 3. 编辑INIT.ORA文件:
INIT.ORA文件的在ORACLE_HOME/dbs目录下,
修改参数 "control_files",其中指定移动后的控制文件:
control_files = (/ora/oracle/data1/ctrlorcl1.ctl,/ora/oracle/data1/ctrlorcl2.ctl,/ora/oracle/data2/ctrlorcl3.ctl)
STEP 4. 重启动数据库:
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> STARTUP;
SQL>SELECT name FROM V$CONTROLFILE;
SQL> EXIT;

三. 移动联机日志文件:
STEP 1. 停数据库:
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> SHUTDOWN;
SQL> EXIT;
STEP 2. 用操作系统命令移动联机日志文件:
--将联机日志文件'redolog1.log' 从/ora/oracle/data1目录移动到/ora/oracle/data2目录下:
mv /ora/oracle/data1/redolog1.log /ora/oracle/data2
STEP 3. Mount数据库,用ALTER DATABASE 命令改联机日志文件名:.
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> STARTUP MOUNT ;
SQL> ALTER DATABASE RENAME FILE '/ora/oracle/data1/redolog1.log' TO '/ora/oracle/data2/redolog1.log';
STEP 4.重启动数据库: .
SQL> ALTER DATABASE OPEN;
SQL>SELECT MEMBER FROM V$LOGFILE;

posted @ 2009-11-14 13:37 BlakeSu 阅读(171) | 评论 (0)编辑 收藏

Apache Java项目全介绍

最近接触Jakarta-Common-BeanUtils这个东东比较 多,于是对Apache Jakarta Project产生了兴趣,上他们的官方网站上看了下感觉有用的东西好多,眼花缭乱的,又没有中文网站,又上各大论坛搜了下,也没有发现一个集中该项目的 资料,于是决定自己整理翻译一下,有助于各位网友更好的了解该项目。如果有什么描述不对不全面的地方,希望各位提出来给大家分享。

Jakarta项目是ASF(The Apache Software Foundation)的一部分。ASF是一个非赢利组织,她鼓励基于开放的软件许可下进行合作、注重实效的开发,并提供各个领域的高质量软件,她涉及到 Http服务器,编译工具,类库,开发架构,服务器端Java技术,J2EE容器,数据库工具,日志工具,XML解析等等诸多领域。ASF提供的java 项目有一部分在Jakarta中,还有一些成为独立的诸如Tomcat的项目,Jakarta项目则提供了多种多样开源的java解决通用方案。

先介绍一下ASF中和Jakarta项目并列的java项目:

Ant ——java构建工具,使用一个配置文件就可以完成java的项目的,编译、打包、测试、运行、部署、生成文档等诸多工作。
Avalon ——是一个包括核心框架、工具、组件和容器的面向组件编程(AOP)的完整开发平台。使用关键设计模式,如反向控制模式(IoC)和分离考虑模(SoC)。 Avalon提供各种基本组件和缺省的应用程序模块,帮助你快速的建立你自己的应用程序解决方案。
Excalibur ——集多个开源项目(Avalon Framework、LogKit和Cornerstone)于一身的轻量级可嵌入式反向控制容器。
Gump ——是Apache组织自己也使用的一个持续集成工具,全面支持Ant和Maven,当有新的改动提交到版本控制系统,它可以检查出潜在的冲突,并及时通知项目组的所有成员并自动生成改动的详细报告。
James ——是一套用java开发的邮件、新闻组、消息服务器,提供了比较完善的配置方案,尤其是关于邮件内容存储和用户信息存储。 支持 SMTP, POP3 , NNTP , IMAP 。
Logging ——可靠,快速的日志工具。
Lucene ——Java开发的高性能,全方位的文本搜索引擎。替文件的每一个字作索引,索引让搜寻的效率比传统的逐字比较大大提高, Lucen提供一组解读,过滤,分析文件,编排和使用索引的API,它的强大之处除了高效和简单外,是最重要的是使使用者可以随时应自已需要自订其功能。
Maven ——是一个潜在的基于java的apache ant的构建工具的替代者。提供了更强大的功能和易用性。
Portals ——提供了功能全面的、具有商业价值的企业门户。门户概念:门户对企业内的各种资源如信息管理系统进行整合并通过单一接口对外提供服务,雇员、合伙人及顾 客可以通过任何装置在任何地点通过门户入口享受到企业提供的服务,分析家们预计,门户将成为下一代的桌面环境。
Struts ——一个实现MVC model2的web应用程序开发框架。通过一个配置文件可以很好的对各种组件进行装配,结构清晰,应用的最广泛的额web开发框架。
Tapestry——类似 Struts,也是一个基于servlet的应用程序框架,支持MVC,出现的较晚,不如Struts普及,主要利用javabean和xml技术进行开发,
Tomcat ——Serlvet容器,同时具有传统的Web服务器的功能,如:处理Html页面。能够处理动静态网页。
Watchdog ——用来检查一个servlet或jsp容器在相应规范上的执行情况的兼容性。但是该项目已经静止了,只支持Servlet2.3、JSP1.2,相应的Serlvet容器如Tomcat也只支持Tomcat4.x。

下面介绍下Jakarta的各个子项目:

Alexandria——已经不再开发
BCEL ——The Byte Code Engineering Library (formerly known as JavaClass) 字节码引擎类库,它让用户方便的分析,创建,操作java的class文件成为可能。 它可以让您深入 JVM 汇编语言进行类操作的细节。
BSF ——bean脚本框架 在java应用内对脚本语言提供了支持,通过脚本语言可以访问java的对象和方法。
Cactus ——一个基于JUnit框架的简单测试框架,用来单元测试服务端Java代码。 Cactus单元测试服务端内容包括servlet,EJB, tag librarie, filter等
Commons ——提供很多日常开发中使用率很高的功能解决方案,已被很多著名的开源项目采用。具体的项目列表后面会有。
ECS ——使用Java语言和面向对象方法创建标记语言文档(HTML,XML)的开源项目。
HiveMind ——是一个服务和配置的微型内核, 一套通过简单的java对象和接口创建复杂应用的框架。
HttpComponents ——提供了java.net包所不能提供的更多强大的、方便的http协议处理功能。
JCS ——一个分布式的缓存系统,用来提高应用程序的性能,并且提供很多强大的额外功能。
JMeter ——纯java开发的一套桌面应用程序。用来进行功能测试和性能测试。它可以用来测试静止资料库或者活动资料库中的服务器的运行情况,可以用来模拟对服务 器或者网络系统加以重负荷以测试它的抵抗,或者用来分析不同负荷类型下的所有运行情况。它也提供了一个可替换的界面用来定制数据显示,测试同步及测试的创 建和执行。
ORO ——一套文本处理工具,能提供perl5.0兼容的正则表达式、 AWK-like正则表达式, glob 表达式。还提供替换,分割,文件名过虑等功能。
POI ——一套用来创建,读写基于OLE 2组件文档格式的文件。使用Java来读写MS Excel ,Word文件。
Regexp ——一套纯java的正则表达式相关的包。
Slide ——主要模块是一个可以做为内容管理框架底层的内容仓库.它可以把内容信息存取到专门的,异质的,分布式的数据库中.Slide还增加了security, locking, versioning等特性.
Taglibs ——一套在开发web应用时十分有用的,jsp 通用 tag包。
Turbine ——类似 Struts,也是一个基于servlet的应用程序框架,支持MVC。提供了大量可重用的组件。此框架包中包含了大量组件,但是这些组件是离散的。
Velocity ——是一个基于java的模板引擎(template engine)。它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象。 当Velocity应用于web开发时,界面设计人员可以和java程序开发人员同步开发一个遵循MVC架构的web站点,也就是说,页面设计人员可以只 关注页面的显示效果,而由java程序开发人员关注业务逻辑编码。 Velocity将 java代码从web页面中分离出来,这样为web站点的长期维护提供了便利, 同时也为我们在JSP和PHP之外又提供了一种可选的方案。 Velocity的能力远不止web站点开发这个领域,例如,它可以从模板(template)产生SQL和PostScript、XML,它也可以被当 作一个独立工具来产生源代码和报告,或者作为其他系统的集成组件使用。Velocity也可以为Turbine web开发架构提供模板服务(template service)。 Velocity+Turbine提供一个模板服务的方式允许一个web应用以一个真正的MVC模型进行开发。
Apache java项目全介绍2

下面介绍一下Jakarta下的Commons:一个csdn网友描述得很贴切,Commons就好比一个java百宝箱。
commons分为3部分Commons Proper、Commons Sandbox和Commons Dormant。
Commons Proper:提供了设计良好可重用的java组件,并都经过了广泛、严格的测试。
Commons Sandbox:处于实验、测试阶段的组件。
Commons Dormant:处于停滞状态,从Sandbox退出的,不活跃的组件,谨慎使用。

Commons Proper组件:

Attributes—— 支持源代码级的元数据。
BeanUtils——提供对 Java 反射和自省API的包装,处理javabean的工具。
Betwixt——将JavaBeans与XML相互转换。
Chain——对Chain of Responsibility(责任链)设计模式的实现。使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
CLI——处理命令行的命令的解析。
Codec——包含一些通用的编码解码算法。包括一些语音编码器, Hex, Base64, 以及URL encoder。
Collections——扩展和增加标准的 Java Collection框架。
Configuration——操作各种格式的配置文件。Properties文件 /XML文件 /JNDI /JDBC 数据源 /System properties /Applet parameters / Servlet parameters
Daemon——创建类似unix守护线程的java代码,可以安全地执行一些后台操作,线程不被某个应用程序控制,而是由操作系统控制类似windows的service,可以设置一个服务依赖于另一个服务,一个服务关闭前必须先执行另一个服务。
DBCP——一个数据库连接池
DbUtils——一个JDBC的工具类,比如可以将ResultSets生成javabean。
Digester——基于规则的XML文档解析,主要用于XML到Java对象的映射.
Discovery——提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。
EL——JSP 2.0引入的表达式
Email——处理e-mail
FileUpload——web应用中的文件上传组件
HttpClient——使用HTTP协议的客户端开发框架
IO——帮助进行IO功能开发
Jelly ——Jelly能够把XML转换成可执行代码,所以Jelly是一个基于XML与Java的脚本和处理引擎。 Jelly借鉴了JSP定指标签,Velocity, Cocoon和Xdoclet中的脚本引擎的许多优点。Jelly可以用在命令行,Ant或者Servlet之中。
Jexl——Jexl是一个表达式语言,通过借鉴来自于Velocity的经验扩展了JSTL定义的表达式语言。
JXPath——使用XPath语法操作javabean的工具。
Lang——提供对java.lang包的扩展。
Launcher——跨平台的java程序的启动
Logging ——提供的是一个日志(Log)接口(interface),同时兼顾轻量级和不依赖于具体的日志实现工具。它提供给中间件/日志工具开发者一个简单的日 志操作抽象,允许程序开发人员使用不同的具体日志实现工具。用户被假定已熟悉某种日志实现工具的更高级别的细节。JCL提供的接口,对其它一些日志工具, 包括Log4J, Avalon LogKit, and JDK 1.4等,进行了简单的包装,此接口更接近于Log4J和LogKit的实现.
Math——Math 是一个轻量的,自包含的数学和统计组件,解决了许多非常通用但没有及时出现在Java标准语言中的实践问题.
Modeler—— 支持兼容JMX规范的MBeans开发。
Net——集合了网络工具和协议工具的实现
Pool——Commons-Pool 提供了通用对象池接口,一个用于创建模块化对象池的工具包,以及通常的对象池实现。
Primitives——对java原始类型的支持。
SCXML——处理SCXML
Transaction——事务处理,实现了多层次锁、事务集合、事务文件的访问。
Validator——提供了一个简单的,可扩展的框架来在一个XML文件中定义校验器 (校验方法)和校验规则。支持校验规则的和错误消息的国际化。
VFS——访问各种文件系统,可以是本地文件、HTTP服务器上的文件、zip中的文件。
Commons Sandbox组件:

Compress——处理压缩文件如tar, zip 和 bzip2 格式。
CSV——处理CSV文件
Exec——安全地处理外部进程
Finder——实现类似UNIX find命令的功能
I18n——处理软件的I18n功能
Id——生成id号功能
Javaflow——捕捉程序运行状态
JCI——java编译接口
OpenPGP——处理加密方法OpenPGP.
Pipeline——处理类似工作队列的管道工具
Proxy——生成动态代理

posted @ 2009-11-14 13:36 BlakeSu 阅读(227) | 评论 (0)编辑 收藏

ibatis built-in type alias definitions

Alias           Type

Transaction manager aliases
JDBC     com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig
JTA      com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig
EXTERNAL com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig

Data types
string     java.lang.String
byte       java.lang.Byte
long       java.lang.Long
short      java.lang.Short
int        java.lang.Integer
integer    java.lang.Integer
double     java.lang.Double
float      java.lang.Float
boolean    java.lang.Boolean
date       java.util.Date
decimal    java.math.BigDecimal
object     java.lang.Object
map        java.util.Map
hashmap    java.util.HashMap
list       java.util.List
arraylist  java.util.ArrayList
collection java.util.Collection
iterator   java.util.Iterator

Data source factory types
SIMPLE com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory
DBCP   com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory
JNDI   com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory

Cache controller types
FIFO    com.ibatis.sqlmap.engine.cache.fifo.FifoCacheController
LRU     com.ibatis.sqlmap.engine.cache.lru.LruCacheController
MEMORY  com.ibatis.sqlmap.engine.cache.memory.MemoryCacheController
OSCACHE com.ibatis.sqlmap.engine.cache.oscache.OSCacheController

XML result types

Dom           com.ibatis.sqlmap.engine.type.DomTypeMarker
domCollection com.ibatis.sqlmap.engine.type.DomCollectionTypeMarker
Xml           com.ibatis.sqlmap.engine.type.XmlTypeMarker
XmlCollection com.ibatis.sqlmap.engine.type.XmlCollectionTypeMarker

posted @ 2009-11-14 13:35 BlakeSu 阅读(382) | 评论 (0)编辑 收藏

Oracle与SQL Server事务处理的比较

事务处理是所有大型数据库产品的一个关键问题,各数据库厂商都在这个方面花费了很大精力,不同的事务处理方式会导致数据库性能和功能上的巨大差异。
事务处理也是数据库管理员与数据库应用程序开发人员必须深刻理解的一个问题,对这个问题的疏忽可能会导致应用程序逻辑错误以及效率低下。
下 面我们针对Oracle及SQL Server这两种当前广泛使用的大型数据库产品,探讨一下它们在事务处理方面的一些差异。如没有特殊说明,本文内容适用的数据库产品版本为 Oracle9i及SQL Server 2000,其中的示例SQL语句,对于Oracle是在SQL*Plus中执行,而对于SQL Server 2000是在osql中执行。

1. 事务的概念

     事务可以看作是由对数据库的若干操作组成的一个单元,这些操作要么都完成,要么都取消,从而保证数据满足一致性的要求。事务的一个典型例子是银行中的转帐 操作,帐户A把一定数量的款项转到帐户B上,这个操作包括两个步骤,一个是从帐户A上把存款减去一定数量,二是在帐户B上把存款加上相同的数量。这两个步 骤显然要么都完成,要么都取消,否则银行就会受损失。显然,这个转帐操作中的两个步骤就构成一个事务.

     数据库中的事务还有如下ACID特征。
     ACID分别是四个英文单词的首写字母,这四个英文单词是Atomicity、Consistency、Isolation、Durability,分别翻译为原子性、一致性、隔离性、持久性。
    原子性:指事务中的操作,或者都完成,或者都取消。
    一致性:指事务中的操作保证数据库中的数据不会出现逻辑上不一致的情况,一致性一般会隐含的包括在其他属性之中。
    隔离性:指当前的事务与其他未完成的事务是隔离的。在不同的隔离级别下,事务的读取操作,可以得到的结果是不同的。
    持久性:指对事务发出COMMIT命令后,即使这时发生系统故障,事务的效果也被持久化了。与此相反的是,当在事务执行过程中,系统发生故障,则事务的操作都被回滚,即数据库回到事务开始之前的状态。
    对数据库中的数据修改都是在内存中完成的,这些修改的结果可能已经写到硬盘也可能没有写到硬盘,如果在操作过程中,发生断电或系统错误等故障,数据库可以 保证未结束的事务对数据库的数据修改结果即使已经写入磁盘,在下次数据库启动后也会被全部撤销;而对于结束的事务,即使其修改的结果还未写入磁盘,在数据 库下次启动后会通过事务日志中的记录进行“重做”,即把丢失的数据修改结果重新生成,并写入磁盘,从而保证结束事务对数据修改的永久化。这样也保证了事务 中的操作要么全部完成,要么全部撤销。

2. 事务设置及类型的区别

    在SQL Server中有三种事务类型,分别是:隐式事务、显式事务、自动提交事务,缺省为自动提交。
    自动提交,是指对于用户发出的每条SQL语句,SQL Server都会自动开始一个事务,并且在执行后自动进行提交操作来完成这个事务,也可以说在这种事务模式下,一个SQL语句就是一个事务。
    显式事务,是指在自动提交模式下以Begin Transaction开始一个事务,以Commit或Rollback结束一个事务,以Commit结束事务是把事务中的修改永久化,即使这时发生断电 这样的故障。例如下面是SQL Server中的一个显式事务的例子。

Begin Tran
Update emp Set ename=’Smith’ Where empno=7369
Insert Into dept Values(60,’HR’,’GZh’)
Commit

<!--[if !vml]--><!--[endif]-->

    隐式事务,是指在当前会话中用Set Implicit_Transactions On命令设置的事务类型,这时任何DML语句(Delete、Update、Insert)都会开始一个事务,而事务的结束也是用Commit或Rollback。
    在Oracle中没有SQL Server的这些事务类型,缺省情况下任何一个DML语句都会开始一个事务,直到用户发出Commit或Rollback操作,这个事务才会结束,这与SQL Server的隐式事务模式相似。

3. 事务隔离级别

    在SQL92标准中,事务隔离级别分为四种,分别为:Read Uncommitted、Read Committed、Read Repeatable、Serializable,其中Read Uncommitted与Read Committed为语句级别的,而Read Repeatable与Serializable是针对事务级别的。
    在Oracle和SQL Server中设置事务隔离级别的语句是相同的,都使用SQL92标准语法,即:
Set Transaction Isolation Level Read Committed
    上面示例中的Read Committed可以被替换为其他三种隔离级别中的任意一种。

1) SQL Server中的隔离级别及实现机制

    在SQL Server中提供了所有这四种隔离级别。
    下面我们讨论在SQL Server中,这几种隔离级别的含义及其实现方式。
    Read Uncommitted:一个会话可以读取其他事务未提交的更新结果,如果这个事务最后以回滚结束,这时的读取结果就可能是错误的,所以多数的数据库应用都不会使用这种隔离级别。
    Read Committed:这是SQL Server的缺省隔离级别,设置为这种隔离级别的事务只能读取其他事务已经提交的更新结果,否则,发生等待,但是其他会话可以修改这个事务中被读取的记 录,而不必等待事务结束,显然,在这种隔离级别下,一个事务中的两个相同的读取操作,其结果可能不同。
    Read Repeatable:在一个事务中,如果在两次相同条件的读取操作之间没有添加记录的操作,也没有其他更新操作导致在这个查询条件下记录数增多,则两次 读取结果相同。换句话说,就是在一个事务中第一次读取的记录保证不会在这个事务期间发生改变。SQL Server是通过在整个事务期间给读取的记录加锁实现这种隔离级别的,这样,在这个事务结束前,其他会话不能修改事务中读取的记录,而只能等待事务结 束,但是SQL Server不会阻碍其他会话向表中添加记录,也不阻碍其他会话修改其他记录。
    Serializable:在一个事务中,读取操作的结果是在这个事务开始之前其他事务就已经提交的记录,SQL Server通过在整个事务期间给表加锁实现这种隔离级别。在这种隔离级别下,对这个表的所有DML操作都是不允许的,即要等待事务结束,这样就保证了在 一个事务中的两次读取操作的结果肯定是相同的。

2) Oracle中的隔离级别及实现机制

    在Oracle中,没有Read Uncommitted及Repeatable Read隔离级别,这样在Oracle中不允许一个会话读取其他事务未提交的数据修改结果,从而避免了由于事务回滚发生的读取错误。Oracle中的 Read Committed和Serializable级别,其含义与SQL Server类似,但是实现方式却大不一样。
    在Oracle中,存在所谓的回滚段(Oracle9i之前版本)或撤销段(Oracle9i版本),Oracle在修改数据记录时,会把这些记录被修改 之前的结果存入回滚段或撤销段中,就是因为这种机制,Oracle对于事务隔离级别的实现与SQL Server截然不同。在Oracle中,读取操作不会阻碍更新操作,更新操作也不会阻碍读取操作,这样在Oracle中的各种隔离级别下,读取操作都不 会等待更新事务结束,更新操作也不会因为另一个事务中的读取操作而发生等待,这也是Oracle事务处理的一个优势所在。
    Oracle缺省的设置是Read Committed隔离级别(也称为语句级别的隔离),在这种隔离级别下,如果一个事务正在对某个表进行DML操作,而这时另外一个会话对这个表的记录进 行读取操作,则Oracle会去读取回滚段或撤销段中存放的更新之前的记录,而不会象SQL Server一样等待更新事务的结束。
    在Serializable隔离级别(也称为事务级别的隔离),事务中的读取操作只能读取这个事务开始之前已经提交的数据结果。

 如果在读取时,其他事务正 在对记录进行修改,则Oracle就会在回滚段或撤销段中去寻找对应的原来未经更改的记录(而且是在读取操作所在的事务开始之前存放于回滚段或撤销段的记 录),这时读取操作也不会因为相应记录被更新而等待。

4. DDL语句对事务的影响

1) Oracle中DDL语句对事务的影响

    在Oracle中,执行DDL语句(如Create Table、Create View等)时,会在执行之前自动发出一个Commit命令,并在随后发出一个Commit或者Rollback命令,也就是说,DDL会象如下伪码一样执行:

Commit;
DDL_Statement;
If (Error) then
Rollback;
Else
Commit;
End if;


我们通过分析下面例子来看Oracle中,DDL语句对事务的影响:

<!--[if !vml]--><!--[endif]-->Insert into some_table values(‘Before’);
<!--[if !vml]--><!--[endif]-->Creaate table T(x int);
<!--[if !vml]--><!--[endif]-->Insert into some_table values(‘After’);
<!--[if !vml]--><!--[endif]-->Rollback;

    由于在Oracle执行Create table语句之前进行了提交,而在Create table执行后也会自动发出Commit命令,所以只有插入After的行被回滚,而插入Before的行不会被回滚,Create table命令的结果也不会被回滚,即使Create table语句失败,所进行的Before插入也会被提交。如果最后发出Commit命令,因为插入Before及Create table的操作结果已经在之前提交,所以Commit命令影响的只有插入After的操作。

2) SQL Server中DDL语句对事务的影响

在SQL Server中,DDL语句对事务的影响与其他DML语句相同,也就是说,在DML语句发出之前或之后,都不会自动发出Commit命令。
在SQL Server 2000中,对于与上面Oracle同样的例子,最后发出Rollback后,数据库会回滚到插入Before之前的状态,即插入Before和After的行都会被回滚,数据表T也不会被创建。
如果最后发出Commit操作,则会把三个操作的结果全部提交。

5. 用户断开数据库连接对事务的影响

    另外,对应于Oracle的管理客户端工具SQL*Plus,在SQL Server 2000中是osql,两种管理工具都是命令行工具,使用方式及作用也类似,但是在SQL*Plus中,用户退出连接时,会自动先发出Commit命令, 然后再退出,而在osql中,如果用户退出连接,会自动发出Rollback命令,这对于SQL Server的自动提交模式没有什么影响,但如果处于隐式事务模式,其影响是显而易见的。对于两种数据库产品的其他客户端管理工具也有类似的不同之处。

posted @ 2009-11-14 13:34 BlakeSu 阅读(187) | 评论 (0)编辑 收藏

SAX与DOM之间的区别

SAX (Simple API for XML) DOM (Document Object Model) 是当前两个主要的XML API,几乎所有商用的xml 解析器都同时实现了这两个接口。因此如果你的程序使用了SAX或者DOM APIs,那么你的程序对xml解析器是透明。
 
1. DOM以一个分层的对象模型来映射xml文档。而SAX将文档中的元素转化为对象来处理。
 
2. DOM将文档载入到内存中处理,而SAX则相反,它可以检测一个即将到来的 XML流,由此并不需要所有的XML代码同时载入到内存中。
 
SAX 处理是如何工作的

   SAX 
在读取 XML 流的同时处理它们,这很像以前的自动收报机纸带(ticker tape)。请考虑下面的 XML 代码片断:
       <?xml version="1.0"?>
       <samples>
          <server>UNIX</server>
          <monitor>color</monitor>
       </samples>

   分析这个代码片断的 SAX 处理器一般情况下将产生以下事件: 
       Start document
       Start element (samples)
       Characters (white space)
       Start element (server)
       Characters (UNIX)
       End element (server)
       Characters (white space)
       Start element (monitor)
       Characters (color)
       End element (monitor)
       Characters (white space)
       End element (samples)
  
   SAX API 允许开发人员捕捉这些事件并对它们作出反应。
 
SAX 处理涉及以下步骤:

     1.
创建一个事件处理程序。 
     2.
创建 SAX 解析器。 
     3.
向解析器分配事件处理程序。 
     4.
解析文档,同时向事件处理程序发送每个事件。 

基于事件的处理的优点和缺点

     
这种处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,
   因此不需 要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时
   停止解析。一般来说,SAX 还比它的替代者 DOM 快许多。
   另一方面,由于应用程序没有以任何方式存储数据,使用 SAX 来更改数据或在数据流中往后移是不可能的。
 
DOM 和基于树的处理
     DOM 是处理 XML 数据的传统方法。使用 DOM 时,数据以树状结构的形式被加载到内存中。
     
例如,在“SAX 处理是如何工作的”中用作例子的相同文档在 DOM 中将表示为节点,DOM 使用父子关系。
基于树的处理的优点和缺点

    DOM 
以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。
       它还可以在任何时候在树中上下导航,而不是像 SAX 那样是一次性的处理。DOM 使用起来也要简单得多。
    另一方面,在内存中构造这样的树涉及大量的开销。大型文件完全占用系统内存容量的情况并不鲜见。此外,创建一棵 DOM 树可能是一个缓慢的过程。

如何在 SAX  DOM 之间选择

  
选择 DOM 还是选择 SAX,这取决于下面几个因素:

    1.
应用程序的目的:如果打算对数据作出更改并将它输出为 XML,那么在大多数情况下,DOM 是适当的选择。并不是说使用 SAX 就不能更改数据,
      但是该过程要复杂得多,因为您必须对数据的一份拷贝而不是对数据本身作出更改。 

    2.
数据容量: 对于大型文件,SAX 是更好的选择。 
      数据将如何使用:如果只有数据中的少量部分会被使用,那么使用 SAX 来将该部分数据提取到应用程序中可能更好。 另一方面,
      如果您知道自己以后会回头引用已处理过的大量信息,那么 SAX 也许不是恰当的选择。 

    3.
对速度的需要: SAX 实现通常要比 DOM 实现更快。 

   SAX 
 DOM 不是相互排斥的,记住这点很重要。您可以使用 DOM 来创建 SAX 事件流,也可以使用 SAX 来创建 DOM 树。事实上,用于创建 DOM 树的大多数解析器实际上都使用 SAX 来完成这个任务!

posted @ 2009-11-14 13:33 BlakeSu 阅读(427) | 评论 (0)编辑 收藏

Execute and Wait Interceptor 的使用(struts2)

1、增加拦截器
    
       <interceptor-ref name="execAndWait">
            <!--等待时间,执行时间没有超过此值,将不显示等待画面(毫秒)-->
            <param name="delay">1000</param>
            <!-- 间隔检查时间,检查后台进程有没有执行完毕,如果完成了它就立刻返回-->
            <param name="delaySleepInterval">50</param>
       </interceptor-ref>
  
      此拦截器必须放在所有拦截器的最后。    

2、增加result

       <result name="wait">wait.jsp</result>
 
       如果没有找到"wait"结果,struts2会自动生成一个wait结果(\org\apache\struts2\interceptor \wait.ftl).这个结果是用FreeMarker做的,所以需要Freemarker支持才能正常工作。如果你不想在程序中加入 FreeMarker,那就必须自己实现一个wait结果。这一般来说是有必要的,因为默认的wait页面很简单。

3、Action实现SessionAware接口

       因为这个action将会以单独的线程执行,所以你不能用ActionContext,因为它是ThreadLocal.这也就是说如果你要访问 session数据,你必须实现 SessionAware结构而不是调用ActionContext.getSesion() 。

       public interface SessionAware{
              public void setSession(Map map);
       }

       public abstract class AbsBasicAction extends ActionSupport implements SessionAware{
            
               /** 当前 Session */
              protected Map session ;

              public void setSession(Map session) {
                   this.session = session ;
              }
       }

4、实现 wait 结果 映射的 wait.jsp

       必须设置该页面的meta信息,每隔5秒,重新请求一次前面的action。
       <meta http-equiv="refresh" content="2;url=<s:url includeParams="all" />" />

posted @ 2009-11-14 13:31 BlakeSu 阅读(267) | 评论 (0)编辑 收藏

仅列出标题
共12页: First 上一页 4 5 6 7 8 9 10 11 12 下一页