牛仔裤的夏天

JAVA是蓝色的- online

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  30 随笔 :: 5 文章 :: 15 评论 :: 0 Trackbacks

2006年3月27日 #

    贝贝在宜城中心幼儿园的第一个“六一”国际儿童节终于来到了,这对于我们全家来说可是一个大日子。早上起来,贝贝却有点担心我们不陪他一起参加幼儿园的庆祝活动,从而流露出一丝焦虑。其实我们才不会错过这个难得的机会呢,更何况爸爸妈妈和贝贝一起准备的歌舞“小海军”,也将在今天的庆祝活动中一起亮相呢。

       早上九点,我们准时来到幼儿园。作为小朋友们的乐园,这里欢歌笑语,张灯结彩,处处洋溢着儿童节的欢快气氛,贝贝也很快就融入到节日的氛围之中了。

师和潘老师井然有序的安排下,小一班的庆祝活动开始了。小朋友们分组表演了儿歌和童谣。轮到贝贝这一组开始表演了,我们赶快准备拍照和摄像,一定要把这精彩的瞬间捕捉记录下来。“ 公鸡每天早早起,母鸡生蛋孵小鸡 …” ,小朋友们花朵般幼嫩的歌喉伴随着可爱的舞蹈动作吸引了在场的每一位家长。当我们还都沉浸在刚才精彩的幼儿歌舞表演时,家长们的趣味游戏“水果蹲”开始了,我和贝贝妈妈也积极参与了这个游戏。家长们的表现让小朋友们忍俊不止,“咯咯咯 咯咯咯”,一串串的笑声渲染了每一位大人和小朋友。

贝贝今天的表现很棒,当老师说请贝贝家庭表演歌舞“小海军”时,他很快就大大方方地跑到舞台中央,声音响亮,和爸爸一起唱起小海军这首儿歌,同时动作流畅,和妈妈一起跳着舞蹈,开开心心地完成了这个节目,赢得了大家的一片掌声。我们一直都很珍惜与贝贝一同参加集体活动的机会,因此心中尤为以这次在幼儿园里和贝贝一起同台表演而感到高兴。接下来,其他的家庭也都表演了各自精彩的节目,有讲故事、钢琴独奏、双簧,还有魔术,众彩纷呈的节目把这次活动的气氛推向高潮。以至于活动落下帷幕时,家长和小朋友们都还恋恋不舍呢。

回家后,贝贝蹦蹦跳跳,不时唱着儿歌,似乎还对今天的活动意犹未尽。“六一”儿童节,我们全家过得开心而有意义。通过这次活动增强了贝贝在集体活动中的自信心和责任感,同时也加强了我们和贝贝之间的互动体验。

posted @ 2006-06-12 14:05 luckyrobbie 阅读(250) | 评论 (0)编辑 收藏

1
早上,贝贝站在我的摩托车踏板上,我送他去幼儿园。开到roundabout的地方时,贝贝说:爸爸就开这个温度吧。 我问:什么? 贝贝说:是速度,不要再加速度了。

2
贝贝喜欢打电脑游戏,前几天特别喜欢玩一个哆啦A梦钓鱼的flash游戏,如果不小心会钓到鲨鱼,而且我们不让他多玩。一天贝贝睡觉做梦而大哭,叫醒后问他做到什么梦了,他说:爸爸不让我玩钓鱼,而且钓到了鲨鱼把小猫吃掉了。

3
晚上吃樱桃,贝贝吃的很开心,还挑出红的给我吃。我对贝贝说:挑1粒给妈妈吃吃,去拍拍她的马屁。于是贝贝选了一个红的樱桃,跑到妈妈边上说:妈妈,喏,吃个马屁。
posted @ 2006-04-23 11:02 luckyrobbie 阅读(252) | 评论 (0)编辑 收藏

1. 域模型也称为设计模型,由以下内容组成:
    具有状态和行为的域对象
    域对象之间的关系

2. 域对象(Domain Object) - 对真实世界的实体的软件抽象,也叫业务对象(Business Object),分为:
    实体域对象(实体EJB,POJO),为每个实体域对象分配OID(Object Identifier)
    过程域对象(Session Bean, Message Driven Bean, Java Bean)
    事件域对象(事件触发)
  三种域对象位于业务逻辑层

3. 域对象之间的关系
    关联(Association):one to one, one to many, many to many, 单向, 双向
    依赖(Dependency):类与类之间的访问关系,如果A访问B的属性或者方法,或者A负责实例化B,则A依赖B。过程域对象往往依赖实体域对象。
    聚集(Aggregation):整体与部分之间的关系,实体域对象之间常见。聚集关系和关联关系有相同的形式,区别是:对于聚集关系,部分类的对象不能单独存在,它的生命周期依赖于整体类的对象的生命周期;对于关联关系的2个类,可以分别单独存在。
    一般化(Generalization)

     
   

posted @ 2006-04-18 15:53 luckyrobbie 阅读(224) | 评论 (0)编辑 收藏

这2天用hsqldb做hibernate测试,做insert时,不论用hibernate的方法还是用jdbc的方法,显示的一切信息都是成功的,可是后来打开hsqldb的manager,发现table里面没有记录insert,郁闷之极,觉得应该是hsqldb的配置问题

于是打开那个script文件,最后找到这句配置:SET WRITE_DELAY 20
改为SET WRITE_DELAY 0后,一切正常了

posted @ 2006-04-06 22:32 luckyrobbie 阅读(333) | 评论 (0)编辑 收藏

http://msdn.microsoft.com/library/CHS/jscript7/html/jsreconIntroductionToRegularExpressions.asp?frame=true
posted @ 2006-03-30 11:05 luckyrobbie 阅读(316) | 评论 (0)编辑 收藏

我对decorate模式的理解:
1-首先要有一个Interface,提供一个通用的方法;
2-其次有n多个class来实现这个接口中的方法,这些实现方法在功能上应该是并列的,但不是必须的,从而可以根据需要decorate那个需要被修饰的初始对象。
3-最后这些class都有一个带有Interface作为参数的构造方法和一个Interface的属性,这样在构造的时候就可以取得那个需要修饰的对象的实例,然后在实现Interface的方法里面,首先实现修饰对象实例的修饰方法,然后再进行自己的decorate方法。

根据这个想法来画一张画:

package  test;

public   interface  Painting  {
    
public   void  paint();
}


class  SunPainting  implements  Painting  {
    Painting painting 
=   null ;

    
public  SunPainting()  {
    }


    
public  SunPainting(Painting painting)  {
        
this .painting  =  painting;
    }


    
public   void  paint()  {
        
if  (painting  !=   null {
            painting.paint();
        }

        System.out.println(
" 画了一个太阳 " );
    }

}


class  CloudPainting  implements  Painting  {
    Painting painting 
=   null ;

    
public  CloudPainting()  {
    }


    
public  CloudPainting(Painting painting)  {
        
this .painting  =  painting;
    }


    
public   void  paint()  {
        
if  (painting  !=   null {
            painting.paint();
        }

        System.out.println(
" 画了一朵白云 " );
    }

}


class  LawnPainting  implements  Painting  {
    Painting painting 
=   null ;

    
public  LawnPainting()  {
    }


    
public  LawnPainting(Painting painting)  {
        
this .painting  =  painting;
    }


    
public   void  paint()  {
        
if  (painting  !=   null {
            painting.paint();
        }

        System.out.println(
" 画了一片草地 " );
    }

}

再写段测试画画的代码:

package  test;

public   class  TestPainting  {
    
public   static   void  main(String[] args) {
        
new  SunPainting( new  CloudPainting( new  LawnPainting())).paint();
    }

}

测试结果:

画了一片草地
画了一朵白云
画了一个太阳


 最后有个问题:为什么不直接定义一个画画的类,然后把这些该怎么画的事情分别通过方法来实现呢? 那么什么情况下使用decorate模式更为合适呢?

posted @ 2006-03-27 16:56 luckyrobbie 阅读(555) | 评论 (0)编辑 收藏

你觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗?

        1 OutputStreamWriter out = ...
  2 java.sql.Connection conn = ...
  3 try { // ⑸
  4 Statement stat = conn.createStatement();
  5 ResultSet rs = stat.executeQuery(
  6 "select uid, name from user");
  7 while (rs.next())
  8 {
  9 out.println("ID:" + rs.getString("uid") // ⑹
  10 ",姓名:" + rs.getString("name"));
  11 }
  12 conn.close(); // ⑶
  13 out.close();
  14 }
  15 catch(Exception ex) // ⑵
  16 {
  17 ex.printStackTrace(); // ⑴,⑷
  18 }

作为一个Java程序员,你至少应该能够找出两个问题。但是,如果你不能找出全部六个问题,请继续阅读本文。

本文讨论的不是Java异常处理的一般性原则,因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为“反例”(anti-pattern)的违背优秀编码规范的常见坏习惯,帮助读者熟悉这些典型的反面例子,从而能够在实际工作中敏锐地察觉和避免这些问题。

反例之一:丢弃异常

代码:15行-18行。

这段代码捕获了异常却不作任何处理,可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看,它也许可以和C/C++程序的一个恶名远播的问题相提并论??不检查缓冲区是否已满。

如果你看到了这种丢弃(而不是抛出)异常的情况,可以百分之九十九地肯定代码存在问题(在极少数情况下,这段代码有存在的理由,但最好加上完整的注释,以免引起别人误解)。

这段代码的错误在于,异常(几乎)总是意味着某些事情不对劲了,或者说至少发生了某些不寻常的事情,我们不应该对程序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace算不上“处理异常”。

不错,调用printStackTrace对调试程序有帮助,但程序调试阶段结束之后,printStackTrace就不应再在异常处理模块中担负主要责任了。

丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档,可以看到下面这段说明:“特别地,虽然出现ThreadDeath是一种‘正常的情形’,但ThreadDeath类是Error而不是Exception的子类,因为许多应用会捕获所有的Exception然后丢弃它不再理睬。

”这段话的意思是,虽然ThreadDeath代表的是一种普通的问题,但鉴于许多应用会试图捕获所有异常然后不予以适当的处理,所以JDK把ThreadDeath定义成了Error的子类,因为Error类代表的是一般的应用不应该去捕获的严重问题。可见,丢弃异常这一坏习惯是如此常见,它甚至已经影响到了Java本身的设计。

那么,应该怎样改正呢?主要有四个选择:

1、处理异常。针对该异常采取一些行动,例如修正问题、提醒某个人或进行其他一些处理,要根据具体的情形确定应该采取的动作。再次说明,调用printStackTrace算不上已经“处理好了异常”。

2、重新抛出异常。处理异常的代码在分析异常之后,认为自己不能处理它,重新抛出异常也不失为一种选择。

3、把该异常转换成另一种异常。大多数情况下,这是指把一个低级的异常转换成应用级的异常(其含义更容易被用户了解的异常)。

4、不要捕获异常。

结论一:既然捕获了异常,就要对它进行适当的处理。不要捕获异常之后又把它丢弃,不予理睬。

反例之二:不指定具体的异常

代码:15行。

许多时候人们会被这样一种“美妙的”想法吸引:用一个catch语句捕获所有的异常。最常见的情形就是使用catch(Exception

ex)语句。但实际上,在绝大多数情况下,这种做法不值得提倡。为什么呢?

要理解其原因,我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常,而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常。

由于绝大多数异常都直接或间接从java.lang.Exception派生,catch(Exception ex)就相当于说我们想要处理几乎所有的异常。

再来看看前面的代码例子。我们真正想要捕获的异常是什么呢?最明显的一个是SQLException,这是JDBC操作中常见的异常。另一个可能的异常是IOException,因为它要操作OutputStreamWriter。

显然,在同一个catch块中处理这两种截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说,catch语句应当尽量指定具体的异常类型,而不应该指定涵盖范围太广的Exception类。

另一方面,除了这两个特定的异常,还有其他许多异常也可能出现。例如,如果由于某种原因,executeQuery返回了null,该怎么办?答案是让它们继续抛出,即不必捕获也不必处理。实际上,我们不能也不应该去捕获可能出现的所有异常,程序的其他地方还有捕获异常的机会直至最后由JVM处理。

结论二:在catch语句中尽可能指定具体的异常类型,必要时使用多个catch。不要试图处理所有可能出现的异常。

反例之三:占用资源不释放

代码:3行-14行。

异常改变了程序正常的执行流程。这个道理虽然简单,却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源,即使遇到了异常,也要正确释放占用的资源。为此,Java提供了一个简化这类操作的关键词finally。

finally是样好东西:不管是否出现了异常,Finally保证在try/catch/finally块结束之前,执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally。

当然,编写finally块应当多加小心,特别是要注意在finally块之内抛出的异常??这是执行清理任务的最后机会,尽量不要再有难以处理的错误。

结论三:保证所有资源都被正确释放。充分运用finally关键词。

反例之四:不说明异常的详细信息

代码:3行-18行。

仔细观察这段代码:如果循环内部出现了异常,会发生什么事情?我们可以得到足够的信息判断循环内部出错的原因吗?不能。我们只能知道当前正在处理的类发生了某种错误,但却不能获得任何信息判断导致当前错误的原因。

printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程,但只提供了一些最基本的信息,未能说明实际导致错误的原因,同时也不易解读。

因此,在出现异常时,最好能够提供一些文字信息,例如当前正在执行的类、方法和其他状态信息,包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。

结论四:在异常处理模块中提供适量的错误原因信息,组织错误信息使其易于理解和阅读。

反例之五:过于庞大的try块

代码:3行-14行。

经常可以看到有人把大量的代码放入单个try块,实际上这不是好习惯。这种现象之所以常见,原因就在于有些人图省事,不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子,虽然东西是带上了,但要找出来可不容易。

一些新手常常把大量的代码放入单个try块,然后再在catch语句中声明Exception,而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难,因为一大段代码中有太多的地方可能抛出Exception。

结论五:尽量减小try块的体积。

反例之六:输出数据不完整

代码:7行-11行。

不完整的数据是Java程序的隐形杀手。仔细观察这段代码,考虑一下如果循环的中间抛出了异常,会发生什么事情。循环的执行当然是要被打断的,其次,catch块会执行??就这些,再也没有其他动作了。

已经输出的数据怎么办?使用这些数据的人或设备将收到一份不完整的(因而也是错误的)数据,却得不到任何有关这份数据是否完整的提示。对于有些系统来说,数据不完整可能比系统停止运行带来更大的损失。

较为理想的处置办法是向输出设备写一些信息,声明数据的不完整性;另一种可能有效的办法是,先缓冲要输出的数据,准备好全部数据之后再一次性输出。

结论六:全面考虑可能出现的异常以及这些异常对执行流程的影响。

改写后的代码

根据上面的讨论,下面给出改写后的代码。也许有人会说它稍微有点?嗦,但是它有了比较完备的异常处理机制。


OutputStreamWriter out = ...
  java.sql.Connection conn = ...
  try {
   Statement stat = conn.createStatement();
   ResultSet rs = stat.executeQuery("select uid, name from user");
   while (rs.next()){
    out.println("ID:" + rs.getString("uid") + ",姓名: "+ rs.getString("name"));
   }
  }
  catch(SQLException sqlex)
  {
   out.println("警告:数据不完整");
   throw new ApplicationException("读取数据时出现SQL错误", sqlex);
  }
  catch(IOException ioex)
  {
   throw new ApplicationException("写入数据时出现IO错误", ioex);
  }
  finally
  {
   if (conn != null) {
    try {
     conn.close();
    }
    catch(SQLException sqlex2)
    {
     System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接:" + sqlex2.toString());
    }
   }
   if (out != null){
    try {
     out.close();
    }
    catch(IOException ioex2)
    {
     System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString());
    }
   }
  }




本文的结论不是放之四海皆准的教条,有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心,务必加上详细、全面的注释。

一方面,不要笑话这些错误,不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途,原因很简单,因为它们确确实实带来了“方便”。所有这些反例都可以看作Java编程世界的恶魔,它们美丽动人,无孔不入,时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事,不足挂齿,但请记住:勿以恶小而为之,勿以善小而不为。
posted @ 2006-03-27 10:17 luckyrobbie 阅读(266) | 评论 (0)编辑 收藏

JSP彩色验证码

xiaohanne 发表于2004-06-01 作者:xiaohanne 评价:13/6 评论数:5 点击数:5229 [ 收藏 ]
摘要:



本文Matrix永久镜像:
http://www.matrix.org.cn/resource/article/0/910.html
说明:本文可能由Matrix原创,也可能由Matrix的会员整理,或者由
Matrix的Crawler在全球知名Java或者其他技术相关站点抓取并永久
保留镜像,Matrix会保留所有原来的出处URL,并在显著地方作出说明,
如果你发觉出处URL有误,请联系Matrix改正.
生成有4个随机数字和杂乱背景的图片,数字和背景颜色会改变,服务器端刷新(用history.go(-1)也会变)
原型参考ALIBABA  
http://china.alibaba.com/member/showimage

------------产生验证码图片的文件-----image.jsp-------------------------------------------

<%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>
<%!
Color getRandColor(int fc,int bc){//给定范围获得随机颜色
        Random random = new Random();
        if(fc>255) fc=255;
        if(bc>255) bc=255;
        int r=fc+random.nextInt(bc-fc);
        int g=fc+random.nextInt(bc-fc);
        int b=fc+random.nextInt(bc-fc);
        return new Color(r,g,b);
        }
%>
<%
//设置页面不缓存
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);

// 在内存中创建图象
int width=60, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

// 获取图形上下文
Graphics g = image.getGraphics();

//生成随机类
Random random = new Random();

// 设定背景色
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);

//设定字体
g.setFont(new Font("Times New Roman",Font.PLAIN,18));

//画边框
//g.setColor(new Color());
//g.drawRect(0,0,width-1,height-1);


// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(12);
        int yl = random.nextInt(12);
        g.drawLine(x,y,x+xl,y+yl);
}

// 取随机产生的认证码(4位数字)
String sRand="";
for (int i=0;i<4;i++){
    String rand=String.valueOf(random.nextInt(10));
    sRand+=rand;
    // 将认证码显示到图象中
    g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));//调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
    g.drawString(rand,13*i+6,16);
}

// 将认证码存入SESSION
session.setAttribute("rand",sRand);


// 图象生效
g.dispose();

// 输出图象到页面
ImageIO.write(image, "JPEG", response.getOutputStream());


%>

---------------使用验证码图片的文件---------a.jsp------------------------------------

<%@ page contentType="text/html;charset=gb2312" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>认证码输入页面</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</head>
<body>
<form method=post action="check.jsp">
<table>
<tr>
<td align=left>系统产生的认证码:</td>
<td><img border=0 src="image.jsp"></td>
</tr>
<tr>
<td align=left>输入上面的认证码:</td>
<td><input type=text name=rand maxlength=4 value=""></td>
</tr>
<tr>
<td colspan=2 align=center><input type=submit value="提交检测"></td>
</tr>
</form>
</body>
</html>

-----------------验证的页面----------check.jsp

<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %>
<html>
<head>
<title>认证码验证页面</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</head>

<body>
<%
String rand = (String)session.getAttribute("rand");
String input = request.getParameter("rand");
%>
系统产生的认证码为: <%= rand %><br>
您输入的认证码为: <%= input %><br>
<br>
<%
  if (rand.equals(input)) {
%>
<font color=green>输入相同,认证成功!</font>
<%
  } else {
%>
<font color=red>输入不同,认证失败!</font>
<%
  }
%>
</body>
</html>
posted @ 2006-03-27 10:13 luckyrobbie 阅读(263) | 评论 (0)编辑 收藏

自己的build.xml 
<?xml version="1.0" encoding="gb2312"?>
<project name="app" default="build" basedir=".">
 <property name="app.name" value="hello-ant"/>
     <property name="app.jar" value="${app.name}.jar"/>
     <property name="app.copyright" value=" Copyright (c) 2005 The Robbie's Software Foundation.  All rights reserved."/>

 <property name="src.dir" location="src"/>
 <property name="build.dir" location="build"/>
 <property name="build.docs" value="${build.dir}/docs"/>
 <property name="build.docs.api" value="${build.docs}/api"/>
 <property name="dist.dir" location="dist"/>
 <property name="lib.dir" location="lib"/>
 <property environment="env"/> <!--取系统环境变量-->
 
 <path id="myclasspath">
  <fileset dir="${lib.dir}">
   <include name="**/*.jar"/>
  </fileset>
  <fileset dir="${env.STRUTS_HOME}">
   <include name="lib/*.jar"/>
  </fileset>
<!--
pathelement只能添加单个的jar文件, 没有fileset方便
  <pathelement path="${env.STRUTS_HOME}/lib/struts.jar"/>
-->  
 </path>
 
 <target name="init" depends="clean">
  <echo message="初始化..."/>
  <mkdir dir="${build.dir}"/>
 </target>
 
 <target name="build" depends="init">
  <echo message="编译中..."/>
  <javac srcdir="${src.dir}" destdir="${build.dir}" verbose="true">
   <classpath refid="myclasspath"/>
 
  <compilerarg value="-Xlint:all"/> <!--网上找了半天才找到的, 用于添加javac的编译参数-->
  </javac>
 </target>
 
 <target name="clean">
  <echo message="清理中..."/>
  <delete dir="${build.dir}"/>
  <delete dir="${dist.dir}"/>
 </target>
 
 <target name="dist" depends="build">
  <echo message="制作jar..."/>
  <tstamp/>
  <mkdir dir="${dist.dir}"/>
  <jar destfile="${dist.dir}/app-${DSTAMP}${TSTAMP}.jar" basedir="${build.dir}"/>  
 </target>
 
 <target name="javadocs" depends="dist">
  <echo message="制作api手册..."/>
  <mkdir dir="${build.docs.api}"/>
         <javadoc packagenames="tax.*"
                   sourcepath="${src.dir}"
                   defaultexcludes="yes"
                   destdir="${build.docs.api}"
                   author="true"
                   version="true"
                   use="true"
                   windowtitle="Docs API">
               <doctitle><![CDATA[<h1>tax struts ant API Docs</h1>]]></doctitle>
               <bottom><![CDATA[<i>${app.copyright}</i>]]></bottom>
        </javadoc>
     </target>
</project>

 
 
 
 
 
 
 
 
 
 

 别人的build.xml
 
<?xml version="1.0"  encoding="GB2312" ?>
<!--
    =======================================================================
      hello-ant 项目 ,学习ant工具的第2个build file.
      参照ant的jakarta-ant-1.6alpha的build.xml
      Copyright (c) 2002 The Neusoft Software Foundation.  All rights
      reserved.
    =======================================================================
-->
<project default="dist" basedir=".">
<!--
    ===================================================================
      定义属性(property tasks)
      最好把用到的路径呀,名称呀都在这里定义成全局变量
      例:定义
          <property name="a" value="hello"/>
      以后就可以这样用它:
          <property name="b" value="${a}/b"/>
      现在:b=="hello/b"
    ===================================================================
-->
    <!--主要的系统环境属性-->
    <property environment="env"/><!--取window,unix...的环境变量-->
    <property name="java.home" value="${env.JAVA_HOME}"/>
    <property name="ant.home"  value="${env.ANT_HOME}"/>
    <!--主要的app环境属性-->
    <property name="app.name"      value="hello-ant"/>
    <property name="app.jar"       value="${app.name}.jar"/>
    <property name="app.copyright" value=" Copyright (c) 2002 The Neusoft Software Foundation.  All rights reserved."/>

    <!--app中src的属性-->
    <property name="src.dir"    value="src" />
    <property name="src.main"   value="${src.dir}/main"/>
    <property name="src.script" value="${src.dir}/script"/>
    <!--app用到的lib-->
    <property name="lib.dir" value="lib"/>
    <!--app的build目录中-->
    <property name="build.dir"      value="build" />
    <property name="build.classes"  value="${build.dir}/classes"/>
    <property name="build.docs"     value="${build.dir}/docs"/>
    <property name="build.docs.api" value="${build.docs}/api"/>
    <property name="build.lib"      value="${build.dir}/lib"/>
    <!--app的dist (distribution) 目录中-->
    <property name="dist.dir"      value="dist"/>
    <property name="dist.bin"      value="${dist.dir}/bin"/>
    <property name="dist.docs"     value="${dist.dir}/docs"/>
    <property name="dist.lib"      value="${dist.dir}/lib"/>
    <!--app的docs目录中-->
    <property name="docs.dir"      value="docs"/>
    <!--
    定义一组路径以后可以通过id重用这组路径 ,例:
    <javac srcdir="src/main" destdir="build/classes">
            <classpath refid="classpath"/>
    </javac>
    -->
    <path id="classpath">
        <!--本项目只有一个java,用不上classpath,这里只是做个例子-->
        <pathelement location="${build.classes}"/>
        <pathelement path="${java.home}/lib/tools.jar"/>
    </path>
<!--
    ===================================================================
      init 准备目录(File Tasks)
      主要的目录结构通常是不会变的,一起生成他们
    ===================================================================
-->
    <target name="init">
        <!--清除以前目录-->
        <delete dir="${build.dir}" failonerror="false" />
        <delete dir="${dist.dir}"  failonerror="false"/>
        <!--准备目录-->
        <mkdir dir="${build.dir}"/>
        <mkdir dir="${build.classes}"/>
        <mkdir dir="${build.docs}"/>
        <mkdir dir="${build.docs.api}"/>
        <mkdir dir="${build.lib}"/>
        <mkdir dir="${dist.dir}"/>
        <mkdir dir="${dist.bin}"/>
        <mkdir dir="${dist.lib}"/>
    </target>
<!--
    ===================================================================
      Build the code (Compile Tasks,File Tasks)
    ===================================================================
-->
    <target name="build" depends="init">
        <!--编译-->
        <javac srcdir="${src.main}" destdir="${build.classes}">
            <classpath refid="classpath"/>
        </javac>
    </target>
<!--
    ===================================================================
      打包文档(Archive Tasks)
      Create the project jars: xxx1.jar and xxx2.jar
    ===================================================================
-->
   <target name="jars" depends="build">
        <jar basedir="${build.classes}" jarfile="${build.lib}/${app.jar}"/>
    </target>
<!--
     ===================================================================
       Creates the API documentation
     ===================================================================
-->
    <target name="javadocs"
            depends="jars"
            description="--> creates the API documentation">
        <!--copy docs 手册... -->
        <copy todir="${build.docs}">
            <fileset dir="${docs.dir}"/>
        </copy>
        <javadoc packagenames="hello.ant.*"
                 sourcepath="${src.main}"
                 defaultexcludes="yes"
                 destdir="${build.docs.api}"
                 author="true"
                 version="true"
                 use="true"
                 windowtitle="Docs API">
             <doctitle><![CDATA[<h1>hello ant Docs API</h1>]]></doctitle>
             <bottom><![CDATA[<i>${app.copyright}</i>]]></bottom>
             <tag name="todo" scope="all" description="To do:" />
         </javadoc>
    </target>
<!--
     ===================================================================
       Create the distribution that can run (Archive Tasks)
       主要是从各目录中把该copy的copy上
     ===================================================================
-->
   <target name="dist" depends="javadocs">
        <!--copy bin 执行文件 -->
        <copy todir="${dist.bin}">
            <fileset dir="${src.script}/"/>
        </copy>
        <copy todir="${dist.docs}">
            <fileset dir="${build.docs}/"/>
        </copy>
        <!-- copy lib 文件 -->
        <copy todir="${dist.lib}">
            <fileset dir="${build.lib}/"/>
        </copy>
    </target>
<!--
     ===================================================================
      Cleans everything(File Tasks)
      例如可以删除build中的文件,留给你发挥吧
     ===================================================================
-->
</project>
posted @ 2006-03-27 10:07 luckyrobbie 阅读(447) | 评论 (0)编辑 收藏

Action中的代码:
ActionMessages actionMessages=new ActionMessages();
actionMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("......"));
saveMessages(request, actionMessages);
 
对应的jsp中:
<html:messages id="message" message="true">
      <bean:write name="message"/>
</html:messages>
  • name : 指定ActionMessages存放在request或者session内的属性key.
  • message: 指定消息的来源, 如果为true, 对应于key=Globals.MESSAGE_KEY的ActionMessages对象, 此时name属性无效;如果为false, 则根据name属性检索ActionMessages对象, 如果没有设置name, 默认为Globals.ERROR_KEY. message属性的默认值为false.
posted @ 2006-03-27 10:02 luckyrobbie 阅读(2126) | 评论 (4)编辑 收藏

     摘要: from: http://bobcat.webappcabaret.net/javachina/faq/ant_01.htm FAQ on ANT Building Process by Roseanne Zhang scjp, advanced, job tips, xml, ant, c/c++, ...  阅读全文
posted @ 2006-03-27 10:00 luckyrobbie 阅读(185) | 评论 (0)编辑 收藏

aix的系统备份命令是mksysb, make system backup ,有点类似 ghost.

aix5.3支持微分区技术,所谓微分区就是1台机器上装多个OS(操作系统),把这台机器上的cpu资源进行划分,然后分配给每一个os使用,最小粒度是0.1个cpu.有点类似vmware软件.让一个机器跑多个操作系统.这项技术早在ibm的大机上就已经实现了.只不过最近才在小机和pc机器上发布.

TIVOLI是系统管理软件.

关闭aix的命令:shutdown ->正常关机,关闭所有服务. halt -> 相当于直接关闭电源.
重启aix:shutdown -Fr

查看出错信息:errpt errpt -a | more -> 分页显示 errpt -a > /tmp/err01 输出到文件.
清除错误信息:errclear 0

smit 用鼠标操作 smitty 用键盘来操作,一般用smitty为好.

ping -f 全速ping ,利用所有的服务器资源来ping,如果是多个服务器ping一个ip,可以把机器ping死.

几个关于磁盘的名词:
lv: logical volume 逻辑卷
pv: physical volume 物理卷
vg: volume group 卷组
pp: physical partition 物理分区
lp: logical partition 逻辑分区

pv对应的是物理硬盘或者是磁盘阵列上划分的lun,一个vg最多可以有1016个pp.
pv的上面是vg,一个vg可以包含多个pv.
vg的上面是lv,lv如果不作任何处理就是裸设备,也可以作成文件系统.
lv被分为多个lp,默认情况下,lp与pp是一一对应的,也可以做成一对多的.这样就相当于用多个pp来作raid0备份.

lsdev -C | grep disk 可以查看物理磁盘的硬件信息
lspv 查看pv的信息 -p hdisk0 查看具体数据存放的位置:例如,数据在第m到n个pp上面.
lsvg 查看vg的信息 -l vg的列表 -c 被使用的vg -l rootvg 查看rootvg的详情.
lslv -m lv1 查看lv1 的lp与pp的映射.
getlvcv -AT lv1 看到lv1的控制信息.
fsck -y /dev/newlv 检查lv.

smit vg 可以管理vg
smit lv 管理lv

varryonvg rootvg 激活rootvg卷组,varryoffvg newvg 使newvg卷组脱机.

nbpi:number of bytes per inode 每个i节点拥有的字节数,这个参数越小,文件系统的可用的inode越多.如果inode用完,即使有剩余空间,系统也会报空间不够.此时要调小nbpi的值.一般是4k
df -k 中iused 指的是i节点的使用情况.

设置从cd启动,bootlist -m normal cd0

启动时按ESC+1或者F1,可以进入启动菜单.选择启动方式.

用smitty crfs 创建完文件系统以后还要mount.
/etc/filesystems 文件记录文件系统的信息.如想把某个lv映射到不同的文件系统路径上面,可以直接修改这个文件.

用logform /dev/testloglv 将lv格式化成jfs的log的格式.

file 文件名 可以看某个文件的信息,包括文件类型,可执行文件,文本文件,等等.

uname -a 可以看到os的信息.

fsck 检查文件系统的信息,在umount的时候是准确的, 相当于windows的磁盘扫描.

碎片整理 smitty jfs

lsfs /root 显示文件系统的属性

各个组件的关系:

lsps -a 查看page space的使用情况

vgda:vg description area 每个vg的头部存放vg的描述信息,
如果包含2个pv,那么第一个pv会在头部和另一个位置存放2个vgda,第2个pv也会存放一个.
如果包含3个pv,那么每个pv上都有1个vgda.
vg的信息在odm中也会存储,但必须和vgda中的信息一致,否则无法varryonvg,有下面4个命令来管理odm中的vg信息.
importvg:从vgda中读取信息到odm中
exportvg:从odm中删除vg信息
varryonvg:激活(online)vg
varryoffvg:卸载(offline)vg

修改vg的factor,这样可以将vg的max pp 从默认的1016 增大1倍,到2032,但由于vgda的总大小不变,这些信息都是记录到里面的.所以vg的最大文件数要减小1倍,实际上是个等式:max pp * max file = 固定的一个值,factor增大,实际上是max pp * factor,max file / factor.具体做法:chvg -t 2 rootvg 修改factor为2.vgda

用cfgmgr,来刷新,来认出新assign的hdisk.
cfgmgr -v 检查新设备,新硬件.
-i /dev/cd0 从光盘自动安装新硬件驱动.

当作双机时,2个服务器server1 和 server2 来连接同一个盘阵,server1对磁盘分配一个pvid,当第一次切换到server2时,要用ckdev命令来读出server1配置的pvid.系统是通过pvid来识别pv的.
ckdev -l hdisk1 -a pv = clear 清除pvid
ckdev -l hdisk1 -a pv = yes 新置pvid

lsdev 查看物理设备
lsdev -C 显示所有设备状态
rmdev -l cd0 逻辑删除 cd0
mkdev -l cd0 安装cd0
rmdev -d -l cd0 删除cd0设备驱动

查看cpu的信息
lsattr -El proc0
lsdev -C | grep proc
查看内存的信息
lsattr -El mem0
查看光驱的信息
lsattr -El cd0
查看硬盘的信息
lsattr -El hdisk0

lscfg -vp | more 分页看全部硬件信息
prtconf | more 列出硬件信息

查看谁在使用cdrom fuser /cdrom -k 直接杀掉用户进程

telnet的登陆信息存放在/etc/motd文件中.
想查看最近有谁登陆,用last命令.
查看登录失败的信息: /etc/security/failedlogin
存放用户密码的文件:/etc/security/passwd

用户登录需要运行的脚本:
1 /etc/profile
2 /etc/environment 在这个文件中设置中文环境,LANG=zh_CN
3 用户profile ,分2种情况:
如果是命令行登录,则运行/home/user/.profile
如果是图形登录,则运行 /home/user/.dtprofile 需要将次文件中,#DTSOURCEPROFILE=TRUE 的# 去掉,否则还是使用.profile.

在/dev下面有2种设备,一种是block设备,一种是char(字符)设备.这取决于不同的应用.

vmstat的某些行的解释:
vmstat->faults->cs: user calls 用户调用的次数
cpu->wa: >40 说明io繁忙
kthr: kernel thread
kthr->r 在运行队列中等待执行的进程
b 正在等待io的进程
memory->avm:active vitual memory 物理内存+使用的虚拟内存,以4k为单位.
page->re:是pin 和 pout 的总和.
sr:search的内存块数.
fr:释放的内存块数.
每次作page out时,系统要搜索物理内存以找到可以释放的块,sr和fr分别代表搜索的和通过搜索找到的可以释放的块 数.如果2者很接近,说明内存中有很多用于file cache,内存的数量是够用的.如果fr/sr的值很小,说明内存不够.

tty:代表终端

iostat:
%tm_act 实际transaction的百分比
tps 每秒发生的次数
kbps 每秒的速率
名词:thrasing: 应用程序频繁交换,导致paging过多.

/usr/samples/kernel/vmtune -f 120 -F 128
-f 120 代表minfree mem < 120 时要进行page out
-F 128 代表maxfree mem > 128 时要进行page in
-p -P 也跟page out 有关,具体不清楚,还需明确.

sar->avque:平均的请求数

对文件系统作监视:filemon
filemon -o /tmp/a.txt -O all -v
运行之后系统会一直监视文件系统的使用情况并记录日志,-T 64000 是使用的buffer cache,在大型系统上,这个值可以调大.
运行一段时间后,要停掉filemon,使用trcstop 或者 kill -9 进程.
从a.txt中可以看到使用最频繁的文件等信息,有些类似statspack的报告.

对于后缀是Z的文件用uncompress来解压缩. uncompress a.tar.Z

用strings 命令来看2进制文件

如何调大page space,直接设置对应lv的大小.如果对应lv的vg空间不够的话,可以向vg中加硬盘.

dd的用法:dd if=/dev/rnewfs of=/dev/rcopyfs bs=1024 count=10240
bs: block size 块大小,1024字节
count: block count 块的数量
if是input file ,of 是output file

将任务切换到后台执行: ctrl+z ,然后 bg+回车
查看后台执行的程序:jobs
把后台执行的程序切换到前台执行:fg %n n是后台的job 编号

ip抓包工具:iptrace 和 tcpdump
iptrace -a a.out
停止iptrace:kill -9
tcpdump -i en1 -w a.out a.out 是输出文件

把进程与cpu绑定:bindprocessor -U 进程号 cpuid
bindprocessor -U 12345 0

odm库:
env | grep obj
ODMDIR=/etc/objrepos 这是odm库的存储路径

在disk0上生成引导区
bosboot -a -d /dev/hdisk0

用kdb 查看os 的 dump

ethernet channel 把2个网卡绑定到1个ip,可以作网络负载均衡.

crontab 设置定时任务
crontab -l list the crontab
crontab -e edit the crontab
crontab的格式:分钟 小时 月中的天数 月份 星期 命令
minute:
0 到 59
hour:
0 到 23
day_of_month:
1 到 31
month:
1 到 12
weekday:
星期日到星期六的 0 到 6 时
要在每星期日上午 2 时运行 fwlogmgmt 命令,请将下列各行添加至 crontab 文件底部:
0 2 * * 0 /usr/bin/fwlogmgmt -1

发送邮件,aix和redhad linux 都默认安装了smtp邮件服务,可以直接给internet发邮件.
mail -s "test mail"
haochunpeng@ninetowns.com < $ORACLE_BASE/admin/$ORACLE_SID/bdump/alert$ORACLE_SID.log
mail -s "test mail"
haochunpeng@ninetowns.com <<EOF
******** MAIL CONTENT *******
FJLADSFJLAKHFGAL
FJALDSKFJA
FASLJFLASF
*****************************
EOF
有了crontab和mail,就可以定时监控数据库,然后把报告发送邮件到管理员的信箱.

kill -9 9 是kill命令传送的一个信号,一共15个信号可以发送.

/etc/ftpusers 限制登录ftp的用户,谁在这个文件里面,谁就登不进去.

网络服务 /etc/inetd.conf 刷新 refresh src -d

lslpp -l | grep http 查看安装的软件

检查瓶颈:
利用vmstat iostat 查看总体情况,ps aux 可以看到具体进程占用资源的情况.
如果是io瓶颈,可以利用filemon -o /tmp/a.txt -O all; sleep 10;trcstop 来查看io资源的使用情况.

辨别僵尸进程:ps -ef pid 那列是 defunc的为僵尸进程.

几个不错的aix网站:
http://www.douzhe.com
http://www.xfocus.net/articles/200208/433.html

posted @ 2006-03-27 09:57 luckyrobbie 阅读(2006) | 评论 (0)编辑 收藏