XJ さんのプロフィール走开!我是精神病患者ブログリストつながり ツール ヘルプ

My Custom Part

コンテンツが追加されていません。

卢 XJ

職業
目前是个小Coder,努力成长为Developer,何时才能变SoftwareDesigner
1月9日

Nokia L'Amour Collection

      Nokia L'Amour 系列是我见过的外观最漂亮的手机,雍容华贵,精致典雅。把众多平面设计、服装设计上的元素应用到手机上来。整个系列包括7360(直板)、7370(旋屏)、7380(口红式)三款,整体感觉比较复古。

      整个系列最大的特别便是复古花纹、侧面的布质标签和皮革制的电池背盖,充分体现主人精致的品位。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

12月21日

Log4J && Common Logging

log4j使用示例
--by blues(zhaochaohua@sina.com)
PART 1 介绍
log4j的好处在于:
1.通过修改配置文件,就可以决定log信息输出到何处(console,文件,...),是否输出。
这样,在系统开发阶段可以打印详细的log信息以跟踪系统运行情况,而在系统稳定后可以关闭log输出,从而在能跟踪系统运行情况的同时,又减少了垃圾代码(System.out.println(...)等)。
2.使用log4j,需要整个系统有一个统一的log机制,有利于系统的规划。

log4j的使用本身很简单。但合理地规划一个系统的统一log机制需要周全的考虑。

其他关于log4j的信息参看log4j自带的文档。

PART II 配置文件详细解释
先看一个配置文件的例子:
1.配置文件的例子
log4j.rootLogger=DEBUG
#将DAO层log记录到DAOLog,allLog中
log4j.logger.DAO=DEBUG,A2,A4
#将逻辑层log记录到BusinessLog,allLog中
log4j.logger.Businesslog=DEBUG,A3,A4
#A1--打印到屏幕上
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-5p [%t] %37c %3x - %m%n
#A2--打印到文件DAOLog中--专门为DAO层服务
log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.file=DAOLog
log4j.appender.A2.DatePattern='.'yyyy-MM-dd
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

#A3--打印到文件BusinessLog中--专门记录逻辑处理层服务log信息
log4j.appender.A3=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A3.file=BusinessLog
log4j.appender.A3.DatePattern='.'yyyy-MM-dd
log4j.appender.A3.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

#A4--打印到文件alllog中--记录所有log信息
log4j.appender.A4=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A4.file=alllog
log4j.appender.A4.DatePattern='.'yyyy-MM-dd
log4j.appender.A4.layout=org.apache.log4j.PatternLayout
log4j.appender.A4.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n


2.Appender的使用
一个Appender代表log信息要写向的一个地方。log4j可使用的Appender有很多类型,这里只考虑3种:ConsoleAppender,FileAppender,DailyRollFileAppender
2.1 ConsoleAppender
如果使用ConsoleAppender,那么log信息将写到Console。就是直接把信息打印到System.out上了。
2.2 FileAppender
使用FileAppender,那么log信息将写到指定的文件中。这应该是比较经常使用到的情况。
相应地,在配置文件中应该指定log输出的文件名。如下配置指定了log文件名为demo.txt
log4j.appender.A2.File=demo.txt
注意将A2替换为具体配置中Appender的别名。
2.3 DailyRollingAppender
使用FileAppender可以将log信息输出到文件中,但是如果文件太大了读起来就不方便了。这时就可以使用DailyRollingAppender。DailyRollingAppender可以把Log信息输出到按照日期来区分的文件中。如下配置文件就会每天产生一个log文件,每个log文件只记录当天的log信息:

log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.file=demo
log4j.appender.A2.DatePattern='.'yyyy-MM-dd
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%m%n

3.Layout的配置
Layout指定了log信息输出的样式。
详细信息请查看PatternLayout的javadoc。
例子1:显示日期和log信息
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %m%n
打印的信息是:
2002-11-12 11:49:42,866 SELECT * FROM Role WHERE 1=1 order by createDate desc

例子2:显示日期,log发生地方和log信息
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %l "#" %m%n
2002-11-12 11:51:46,313 cn.net.unet.weboa.system.dao.RoleDAO.select(RoleDAO.java:409) "#" SELECT * FROM Role WHERE 1=1 order by createDate desc

例子3:显示log级别,时间,调用方法,log信息
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
log信息:
[DEBUG] 2002-11-12 12:00:57,376 method:cn.net.unet.weboa.system.dao.RoleDAO.select(RoleDAO.java:409)
SELECT * FROM Role WHERE 1=1 order by createDate desc

PART 3 log4j的使用
log4j使用步骤有3个:
3.1.根据配置文件初始化log4j
配置文件如PART 2所叙述。现在讲的是如何在程序中配置log4j。
log4j可以使用3中配置器来初始化:BasicConfigurator,DOMConfigurator,PropertyConfigurator
这里用的是PropertyConfigurator。使用PropertyConfigurator适用于所有的系统。
如下的语句
PropertyConfigurator.configure("log4j.properties");
就以log4j.properties为配置文件初始化好了log4j环境。
注意一点:这个语句只需要在系统启动的时候执行一次。例如:在unet webOA项目中可以这么用:
在ActionServlet的init()方法中调用一次。
public class ActionServlet extends HttpServlet{
...
/**
* Initialize global variables
*/
public void init() throws ServletException {
// 初始化Action资源
try{
initLog4j();
...
}catch(IOException e){
throw new ServletException("Load ActionRes is Error");
}
}
...
protected void initLog4j(){
PropertyConfigurator.configure("log4j.properties");
}
...
}//end class ActionServlet

3.2 在需要使用log4j的地方获取Logger实例
如下是RoleDAO类中的使用例子:
static Logger log = Logger.getLogger("DAO");
注意这里使用"DAO"标识符,那么对应的在配置文件中对应的配置信息如下:

#定义DAO Logger
log4j.logger.DAO=DEBUG,A2
#设置Appender A2的属性
log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.file=demo
log4j.appender.A2.DatePattern='.'yyyy-MM-dd
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%-5p %d{yyyy-MM-dd HH:mm:ss} %l%n%m%n

public class RoleDAO extends BaseDBObject
{
...
static Logger log = Logger.getLogger("DAO");
...
public BeanCollection selectAll() throws SQLException
{
StringBuffer sql = new StringBuffer(SQLBUF_LEN);
sql.append("SELECT * FROM " + tableName + " order by roldId");
//System.out.println(sql.toString());
log.debug(sql);
...
}
...
}

3.3 使用Logger对象的debug,info,fatal...方法
log.debug("it is the debug info");

附件1:log4j的一个bug
当这样使用时,DailyRollingFileAppender不能正确使用:
public Class RoleDAO(){

static Logger log = Logger.getLogger("DAO");

//在每一次new RoleDAO对象的时候都执行一次configure()操作
public RoleDAO(TransactionManager transMgr) throws SQLException
{
...
PropertyConfigurator.configure("log4j.properties");
...
}

public void select(){
...
//使用log4j进行log记录
log.debug("...");
...
}
}
怎么解决:
在系统启动时执行一次PropertyConfigurator.configure("log4j.properties");
之后就不再执行。

 
 
 
 
org.apache.commons.logging 介绍

 

    对多种日志APIs的简单封装包API

 

概述

    本包为服务器端程序的日志处理提供API以使用多种不同的日志系统。包括如下已经实现的:

    ·Log4J Apache Jakarta 项目。每个Log的实例都对应于一个Log4j Category类。

·JDK Logging API JDK1.4及后续版本中。每个Log的实例都是一个java.util.logging.Logger实例。

·LogKit Apache Jakarta 项目。每个Log的实例都对应于一个LogKit Logger类。

    ·NoOpLog 简单地接受将所有的Log实例的日志输出,。

    ·SimpleLog 将所有的Log实例的日志输出到 System.out中。

 

快速开始向导

 

别不耐烦,马上继续下去,下面的例子描述了对logger的典型声明和使用(用调用者的类名来命名):

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFacory;

public class Foo{

    Log log = LogFactory.getLog(this.calss);

    Public void Foo(){

       

        try{

            if(log.isDebugEnabled()){

                log.debug(“About to do something to object” + name);

            }

            name.bar();

        }catch(IllegalStateException e){

            log.error(“Something bad happened to “ + name,e);

        }

       

    }

}

 

除非你配置不同,否则所有的日志输出都将被抛弃。因此,你很想查看此页的剩余部分以理解怎样配置你的日志系统。

 

配置Commons Logging包

 

选择一个LogFactory实现

    从应用观点,首先需要的就是装载一个引用LogFactory实例的对象以便为这个应用创建一个Log实例。这通常通过调用静态的getFactory()方法完成。这个方法实现了如下的发现算法来选择LogFactory实现类的名字并在应用中使用它:

    ·检查org.apache.commons.logging.LogFactory的系统属性。

    ·使用JDK 1.3 JAR服务发现机制(参见

    http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html获得更多信息)来查找名为META-INF/services/org.apache.commons.logging.LogFactory的资源,其中第一行既包含了需要的类名。

  ·在应用程序的classpath中查找名为common-logging.properties的属性文件,其中的org.apache.commons.logging.LogFactory属性定义了期望的实现类的名字。

    ·回到到默认的实现中,这个接下来会介绍。

   

    如果找到commons-logging.properties文件,其中定义的所有属性将被用来配置LogFactory实例的属性。

 

    一旦选中一个实现类的类名,对应的类将从当前线程的类装载器(如果有)中被装载,或者从类装载器中装载LogFactory自己。这将允许在多个类装载器(如servlet容器)中共享一份commons-logging.jar的拷贝,但仍然允许每个web应用程序提供自己的LogFactory的实现,如果需要的话。该类的一个实例将被创建,并且

 

默认LogFactory实现

 

    日志包APIs中包含了一个默认的实现类

org.apache.commons.logging.impl.LogFactoryImpl),当没有发现其他实现类时将选择他。他的主要目的是通过调用getInstance()方法创建(如果需要)并返回一个Log实例。默认实现使用如下规则:

·至多只有一个同名的Log实例被创建。以后的使用相同名字或类参数的getInstance()方法都将调用同一个LogFactory实例,并将返回同一个Log实例。

    ·当一个Log实例确实被创建后,默认的LogFactory实现使用如下的发现机制:

·查找org.apache.commons.logging.Log系统属性(为了和先前的1.0版的API兼容,org.apache.commons.logging.log的系统属性也别将被考虑)。

·查找名为org.apache.commons.logging.Log的工厂配置属性。

·如果Log4J日志系统在应用程序的classpath中是有效的,则使用对应的类包(Log4JcategoryLog)。

·如果应用程序使用JDK1.4系统,则使用Jdk14Logger包。

·如果都没有,则回到默认的不输出日志包(NoOpLog)。

    ·从线程类装载器(任何)中装载这个指定的类,或者从类装载器中装载LogFacory。

·例示一个选定的Log实现类的实例,将此指定的名字作为唯一的参数传给它的构造方法。

 

如果你想让当前的日志输出到System.out上,但没有安装任何三种提供的日志包中的任何一个,一个名为SimpleLog的简单的Log实现将生效。基于上述规则你可以选用它,在命令行包含一个系统属性定义来启动你的应用程序:

    java\

        -D org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog\

MyApplication

参见SimpleLog的JavaDoc以获得此实现的详细的配置信息。

 

配置日志系统的优先级

 

    基本原理是用户完全为优先的日志系统负责。Common-logging不会改变存在的配置。

 

    每个单独的Log实现都可以提供他自己的配置属性。这在对应的实现类的类发布中说明。

 

    最后,一些Log实现(如Log4J)需要为整个日志系统提供一个外部的配置文件。这个文件需要在实际的日志使用中用一个特别的方法来准备。

   

使用日志包APIs

   

    按如下步骤在应用程序组件中使用日志APIs。

1.      通过调用工厂方法LogFactory.getInstance(String name)获取一个org.apache.commons.logging.Log实例的引用,你的应用程序可以包含多种日志系统的引用以应付各种目的。一个典型的方案是为服务程序的各个主要部件使用他们自己的Log实例。

2.      通过调用适当的方法(debug(),info(),warn(),error(),和fatal())等将信息记录起来(如果对应的级别是可用的)。

 

例如:你可以在你的程序部件中使用如下的技术来初始化和使用一个Log实例:

   

    import org.apache.commons.logging.Log;

    import org.apache.commons.logging.LogFactory;

 

    public class Mycomponent{

        protected Log log = LogFactory.getLog(“my.component”);

       

        //Called once at startup time

public void start(){

           

            log.info(“MyComponent started”);

           

        }

 

        //Called once at shudown time

        public void stop(){

           

            log.info(“MyComponent stopped”);

           

        }

        //Called repeatedly to process a particular argument value

        //which you want logged if debugging is enabled

        public void process(String value){

           

                //Do thie thring concatenation only jif logging is enabled

            if(log.isDebugEnable())

                log.debug(“MyComponent processing” + value);

           

        }

    }

12月19日

无题

     乍一看,有一个多月没有更新我的space了,时间过的真快,不知不觉夏去冬来,完全感觉不到有个秋天。屈指一算,我参加工作也快半年了。这半年成长许多,对软件的认识也加深了很多,改变了很多。
      按照软件工程的理论越是前面的工作带来的风险成本越大。就是说在需求阶段的一个小失误,等发展到维护阶段就会带来很大的成本。言下之意,要从需求阶段就开始做好,充分挖掘客户需求。跟着某个项目老大混了半个项目(说半个是因为我是客串成员,他那项目是副业),开始很认真的做需求。到了编码后半阶段,突然需求更改,原先只涉及风险部的项目引入了市场部,业务发生重大的变更,于是新的需求分析,大部分的代码被报废(还好不是我写的,不然非气死)。这时我的理念是需求大于一切。项目越拖越久,需求不停在变,很多时候需求就诞生于几个人的圆桌讨论,各人有各人的需求,没人拍板。于是抱怨中国软件环境太差,把一切责任都推到客户的不确定需求身上。
     近期看了些Java模式,并研读了Hibernate等优秀开源软件的代码(浅读:P),直至周末看了Spring带的一个PetClinic的代码才恍然大悟。我们选择Java,选择OO语言就是因为他的flexibility。需求是重要的,但是无论怎么优秀的人都不可能把需求挖掘彻底,这时我们就需要flexibility的程序结构。petClinic的Clinic Interface严格规定了整个系统的DAO操作,无论你用Hibenate还是用JDBC,只要实现了该Interface就能使程序完整的跑起来,表结构的改变只需少量修改DAO类就可以。虽然大系统实现起来比较困难,但只要我们把这种思想贯彻进去,终归能写出优秀的程序。
    最近我的软件开发观:快速开发、快速适应变化的需求、解脱繁杂的XML配置文件

Thinking In Thinking

     最近一直在关注Java相关的新技术(其实也不算很新,对于我个人来说却是很新:))
一、AJAX
     AJAX随着市场人员WEB2.0概念的提出显的越来越热门,XMLHTTP的无闪烁刷新确实能给用户带来更丰富的体验。我实际用过的是一个叫DWR(http://getahead.ltd.uk/dwr/)的东东,它是一个基于AJAX的高层表现,无须了解XMLHTTP就可以体验AJAX带来的好处。比如在注册新用户时,在输入用户名后触发onBlur()事件,通过DWR去后台查询是否存在该用户名,然后把结果返回界面。整个过程没有任何页面上的刷新,所以用户根本感觉不到查询过程就可以选择一个不存在的用户名进行注册。
 
二、RIA
      HTML的表现总是差强人意,JS做为一种弱语言,越来越多的应用难以得到实现,另外JS的非OO也给开发带来了很大的难度。虽然B/S,瘦客户胖服务的广泛流行,但已经很多人意识到要给服务端减减肥,把一些事情交给客户端来做。RIA(Rich Internet Applications)正是在这样的情况下提了出来。Flash技术的丰富交互性成了RIA概念的首选实践。作为Flash RIA的代表Flex,Laszlo被人们所关注,前者是Flash的开发者MacroMedia的产品,后者是在开源精神倡导下的开源产品。他们对WebService、RomoteObject、RPC等等的良好支持,给平台架构带来了丰富的组合。Flex2.0的一个FlexStore Sample很好的展示了RIA的好处,对产品数据进行一次下载后在客户端进行查询,对比,查看详细信息等等操作(当然前提是产品数据没有很庞大),然后封装订购信息提交给Server。而以往的B/S程序,查询,对比,查看详细信息,封装订购信息等超作都是靠服务器客户端交互完成的。另外JSP文件还要经过Server的一次编译才能输出IE能解析的HTML。
 
三、SOA && WebService && ESB
      Service的提出确实是一种新的思想,面向企业级(Enterprise)的应用,是对业务层的一种粗颗粒抽象。而WebService标准的提出,更是解决了企业应用整合的难题。SUN致力推广的ESB(Enterprise Service Bus)概念更是新新概念,未经过大量的具体实践,成败还是未知数。
 
四、O/R Mapping
     作为O/R Mapping技术的代表Hibernate,一直没机会在实际项目中实践。后来在一个小项目快收尾时项目老大发善心允许使用Hibernate,用了一天就被Hibernate繁杂的配置以及对SQL的不完全支持所打击,而O/R Mapping带来的最大好处OO在我们这种非OO设计的项目中完全体现不出优越性,最后还是全部换回JDBC。看来要想Hibernate的好处必须在数据库设计阶段就要完全的用OO思想来设计。
11月4日

Informix SQL函数整理

聚集函数:

avg,求平均值
count,统计记录的条数
max,求最大值
min,求最小值
range,计算所选行的最大值与最小值的差
stdev,计算所选行的标准偏差
sum,求和函数
variance,函数返回值样本的方差做为所有选择行的方差的无偏估计。 它的公式,(sum(xi**2)-sum(xi)**2)/N)/(N-1) 其中xi是列中的每个值,N是列中值的总和。

时间函数:
day,mdy,month,weekday,year 这些函数返回与用来调用函数的表达式或自身变量的值。Current返回当前的日期和时间值,可以用extend函数来调整date或datetime值的精度。
使用day和current 函数来将列值与当前日期进行比较。
Date函数将字符串函数转换为DATE值。例date(‘12/7/04’)
To_char函数将datetime和date值转化为字符值。
To_date函数将字符值转化为datetime类型的值。例to_date(“1978-10-07 10:00” ,”%Y-%m-%d %H:%M)

 

基数函数:
cardinality(仅适用IDS)函数对集合包含的元素数目计数。 智能大对象函数,(仅适用与IDS) filetoblob( ),将文件复制到BLOB列中
filetoclob( ),将文件复制到CLOB列中
locopy( ),将BLOB或CLOB类型的数据复制到另一个BLOB或CLOB列中
lotofile( ),将BLOB或CLOB复制到文件中

 

字符串处理函数:
lower,将字符串中每个大写字母转换为小写字母
upper,将字符串中每个小写字母转换为大写字母
initcap,将字符串中每个词的首写字母转换成大写
replace,将字符串中的某一组字符转换成其他字符,例replace(col,”each”,”eve”)
substr,返回字符串中的某一部分,例substr(col,1,2)
substring,返回字符串中的某一部分,例substring(col,from 1 to 4)
lpad,使用lpad函数已用重复次数达到必要次数的字符序列在左边填充或截断的字符串的副本,这取决于字符串中填充部分的指定长度。 举例:字段 col 为char(15)类型,select lpad(col,21,”_”) from tab_name则显示为在col前加上六个_。
Rpad,使用rpad函数已用重复次数达到必要次数的字符序列在右边填充或截断的字符串的副本,这取决于字符串中填充部分的指定长度。 举例:字段col为char(15)类型,select rpad(col,21,”_”) from tab_name则显示为在col后边加上六个_。

 

其他函数:
hex,返回表达式的十六进制数
round,返回表达式的四舍五入值
trunc,返回表达式的截断值
length,计算表达式的长度
user,返回执行查询的用户的用户名(登陆帐户名)
today,返回当前系统日期
dbservername,返回数据库服务器的名称,同sitename
dbinfo,返回数据库的相关信息
decode,函数来将一个具有一个值的表达式转换为另一个值
decode(test,a,a_value,b,b_value,c,c_value……),decode函数不支持TEXT和BYTE类型。
Nvl,来将求值为空的表达式转化为另一个想要指定的值。 另外还可以在select语句中使用存储过程,如select spl($test) from tab_name

10月19日

感受<神话>

  前些日子看完了传说中的《神话》,给我留下了深刻的印象,个人认为这是一部值得去影院和收DVD的片子,另外原声CD也是极其值得收藏的。可以说《神话》在各个方面都超越了《英雄》,《英雄》给我的印象是唯美的画面,然而《神话》在画面色彩构造等方面与《英雄》比豪不逊色。特别是刚开场出送、迎接公主的时候韩服的蔚蓝、中国武服的红和背景黄土、蓝天浑然一体,一幅极其"神话"的画面。另外在印度的黄土这种枯燥的颜色上居然让大量朝圣者穿上洁白的衣服又构造了一幅极其壮观美丽的画面。还有窈窕的印度少女身着轻纱,舞着婀娜的身姿都给我留下了极其深刻的印象。而最高潮我觉得应该是最后溶洞里“飞天”的场景了,虽然色彩上主题是暗淡的兵马俑,然后朱红的马车,还有金喜善的一身素衣,给人强烈的视觉冲击,配上主题曲《Endless Love》渲染了一个极其煽情的场景。特别感谢《神话》的美指黄锐民先生!
      号称永不死亡的成龙在《神话》里倒勉强可以算死了一次,死的还算轰轰烈烈。整部片子整体上还是带有成氏影片的影子,但总算摆脱了高潮-低谷-高潮-完美大结局的套路。
  虽然在某些情节细节处理上有些牵强,但瑕不掩玉,不能动摇《神话》是至今最优秀的国片之一的地位。
 
リスト項目が追加されていません。