随笔-153  评论-235  文章-19  trackbacks-0
  2007年8月21日
如鼠标移到 class 为 box 的 div 标签中背景变色

.vbox div:hover{background: #ddd;}

据说 IE6.0、Firefox2.0、Opera 9.23都不支持

posted @ 2010-02-24 22:10 流浪汗 阅读(1949) | 评论 (0)编辑 收藏
想改 a  的默认方式,比如:链接不要下划线,鼠标移到上面时有划线。

css 如
a:hover {text-decoration: underline;}
a:link 
{text-decoration: none;}
a:visited 
{text-decoration: none;}

是没有达到鼠标称到上面有划线。

必须改为:
a:link {text-decoration: none;}
a:visited 
{text-decoration: none;}
a:hover 
{text-decoration: underline;}

a:hover 放到最后。
posted @ 2010-02-24 22:04 流浪汗 阅读(973) | 评论 (3)编辑 收藏
一、介绍Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”, 是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器.
二、Location语法语法:location [=|~|~*|^~] /uri/ { … }
注:
1、~   为区分大小写匹配
2、~* 为不区分大小写匹配
3、!~和!~*分别为区分大小写不匹配及不区分大小写
不匹配
示例一:
location  / {
}
匹配任何查询,因为所有请求都以 / 开头。但是正则表达式规则将被优先和查询匹配。
示例二:
location =/ {}
仅仅匹配/

示例三:
location ~* \.(gif|jpg|jpeg)$ {
rewrite \.(gif|jpg)$ /logo.png;

注:不区分大小写匹配任何以gif,jpg,jpeg结尾的文件

三、ReWrite语法
last - 基本上都用这个Flag。
break - 中止Rewirte,不在继续匹配
redirect - 返回临时重定向的HTTP状态302
permanent - 返回永久重定向的HTTP状态301

1、下面是可以用来判断的表达式:
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
2、下面是可以用作判断的全局变量
例:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:
http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php

四、Redirect语法
    server {
    listen 80;
    server_name start.igrow.cn;
    index index.html index.php;
    root html;
    if ($http_host !~ "^star\.igrow\.cn$&quot {
         rewrite ^(.*)
http://star.igrow.cn$1 redirect;
    }
    }

五、防盗链location ~* \.(gif|jpg|swf)$ {
  valid_referers none blocked start.igrow.cn sta.igrow.cn;
  if ($invalid_referer) {
  rewrite ^/
http://$host/logo.png;
  }
}

六、根据文件类型设置过期时间
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {
if (-f $request_filename) {
   expires    1h;
   break;
}
}

七、禁止访问某个目录
location ~* \.(txt|doc)${
   
  root /data/www/wwwroot/linuxtone/test;
   
deny all;
}

转:http://www.phpchina.com/html/70/t-162870.html,http://idev.yo2.cn/go/19761.html
posted @ 2010-02-03 10:25 流浪汗 阅读(11996) | 评论 (0)编辑 收藏
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。下面详细介绍它的使用方法。

   
 top - 01:06:48 up  1:22,  1 user,  load average: 0.06, 0.60, 0.48
Tasks:  29 total,   1 running,  28 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.3% us,  1.0% sy,  0.0% ni, 98.7% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:    191272k total,   173656k used,    17616k free,    22052k buffers
Swap:   192772k total,        0k used,   192772k free,   123988k cached

   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  1379 root      16   0  7976 2456 1980 S  0.7  1.3   0:11.03 sshd
14704 root      16   0  2128  980  796 R  0.7  0.5   0:02.72 top
     1 root      16   0  1992  632  544 S  0.0  0.3   0:00.90 init
     2 root      34  19     0    0    0 S  0.0  0.0   0:00.00 ksoftirqd/0
     3 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 watchdog/0

    统计信息区
    前五行是系统整体的统计信息。第一行是任务队列信息,同 uptime 命令的执行结果。其内容如下:

    01:06:48 当前时间
    up 1:22 系统运行时间,格式为时:分
    1 user 当前登录用户数
    load average: 0.06, 0.60, 0.48 系统负载,即任务队列的平均长度。
    三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。

    第二、三行为进程和CPU的信息。当有多个CPU时,这些内容可能会超过两行。内容如下:

    Tasks: 29 total 进程总数
    1 running 正在运行的进程数
    28 sleeping 睡眠的进程数
    0 stopped 停止的进程数
    0 zombie 僵尸进程数
    Cpu(s): 0.3% us 用户空间占用CPU百分比
    1.0% sy 内核空间占用CPU百分比
    0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比
    98.7% id 空闲CPU百分比
    0.0% wa 等待输入输出的CPU时间百分比
    0.0% hi
    0.0% si

    最后两行为内存信息。内容如下:

    Mem: 191272k total 物理内存总量
    173656k used 使用的物理内存总量
    17616k free 空闲内存总量
    22052k buffers 用作内核缓存的内存量
    Swap: 192772k total 交换区总量
    0k used 使用的交换区总量
    192772k free 空闲交换区总量
    123988k cached 缓冲的交换区总量。
    内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,
    该数值即为这些内容已存在于内存中的交换区的大小。
    相应的内存再次被换出时可不必再对交换区写入。

进程信息区
    统计信息区域的下方显示了各个进程的详细信息。首先来认识一下各列的含义。

    序号 列名 含义
    a PID 进程id
    b PPID 父进程id
    c RUSER Real user name
    d UID 进程所有者的用户id
    e USER 进程所有者的用户名
    f GROUP 进程所有者的组名
    g TTY 启动进程的终端名。不是从终端启动的进程则显示为 ?
    h PR 优先级
    i NI nice值。负值表示高优先级,正值表示低优先级
    j P 最后使用的CPU,仅在多CPU环境下有意义
    k %CPU 上次更新到现在的CPU时间占用百分比
    l TIME 进程使用的CPU时间总计,单位秒
    m TIME+ 进程使用的CPU时间总计,单位1/100秒
    n %MEM 进程使用的物理内存百分比
    o VIRT 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
    p SWAP 进程使用的虚拟内存中,被换出的大小,单位kb。
    q RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
    r CODE 可执行代码占用的物理内存大小,单位kb
    s DATA 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
    t SHR 共享内存大小,单位kb
    u nFLT 页面错误次数
    v nDRT 最后一次写入到现在,被修改过的页面数。
    w S 进程状态。
    D=不可中断的睡眠状态
    R=运行
    S=睡眠
    T=跟踪/停止
    Z=僵尸进程
    x COMMAND 命令名/命令行
    y WCHAN 若该进程在睡眠,则显示睡眠中的系统函数名
    z Flags 任务标志,参考 sched.h

    默认情况下仅显示比较重要的 PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND 列。可以通过下面的快捷键来更改显示内容。

    更改显示内容
    通过 f 键可以选择显示的内容。按 f 键之后会显示列的列表,按 a-z 即可显示或隐藏对应的列,最后按回车键确定。

    按 o 键可以改变列的显示顺序。按小写的 a-z 可以将相应的列向右移动,而大写的 A-Z 可以将相应的列向左移动。最后按回车键确定。

    按大写的 F 或 O 键,然后按 a-z 可以将进程按照相应的列进行排序。而大写的 R 键可以将当前的排序倒转。

 命令使用

    1. 工具(命令)名称
    top
    2.工具(命令)作用
    显示系统当前的进程和其他状况; top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止. 比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最“敏感”的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定.
    3.环境设置
    在Linux下使用。
    4.使用方法
    4.1使用格式
    top [-] [d] [p] [q] [c] [C] [S] [s]  [n]
    4.2参数说明
     d 指定每两次屏幕信息刷新之间的时间间隔。当然用户可以使用s交互命令来改变之。
     p 通过指定监控进程ID来仅仅监控某个进程的状态。
     q该选项将使top没有任何延迟的进行刷新。如果调用程序有超级用户权限,那么top将以尽可能高的优先级运行。
     S 指定累计模式
     s 使top命令在安全模式中运行。这将去除交互命令所带来的潜在危险。
     i  使top不显示任何闲置或者僵死进程。
     c  显示整个命令行而不只是显示命令名
    4.3其他
       下面介绍在top命令执行过程中可以使用的一些交互命令。从使用角度来看,熟练的掌握这些命令比掌握选项还重要一些。这些命令都是单字母的,如果在命令行选项中使用了s选项,则可能其中一些命令会被屏蔽掉。
      Ctrl+L 擦除并且重写屏幕。
      h或者? 显示帮助画面,给出一些简短的命令总结说明。
      k 终止一个进程。系统将提示用户输入需要终止的进程PID,以及需要发送给该进程什么样的信号。一般的终止进程可以使用15信号;如果不能正常结束那就使用信号9强制结束该进程。默认值是信号15。在安全模式中此命令被屏蔽。
      i 忽略闲置和僵死进程。这是一个开关式命令。
      q 退出程序。
      r 重新安排一个进程的优先级别。系统提示用户输入需要改变的进程PID以及需要设置的进程优先级值。输入一个正值将使优先级降低,反之则可以使该进程拥有更高的优先权。默认值是10。
      S 切换到累计模式。
      s 改变两次刷新之间的延迟时间。系统将提示用户输入新的时间,单位为s。如果有小数,就换算成m s。输入0值则系统将不断刷新,默认值是5 s。需要注意的是如果设置太小的时间,很可能会引起不断刷新,从而根本来不及看清显示的情况,而且系统负载也会大大增加。
      f或者F 从当前显示中添加或者删除项目。
      o或者O 改变显示项目的顺序。
      l 切换显示平均负载和启动时间信息。
      m 切换显示内存信息。
      t 切换显示进程和CPU状态信息。
      c 切换显示命令名称和完整命令行。
      M 根据驻留内存大小进行排序。
      P 根据CPU使用百分比大小进行排序。
      T 根据时间/累计时间进行排序。
        W 将当前设置写入~/.toprc文件中。这是写top配置文件的推荐方法。

posted @ 2010-01-08 11:08 流浪汗 阅读(731) | 评论 (0)编辑 收藏

想发布新版的 mmseg4j 到现在已经有二个多月了。主要是因为这段时间忙其它事情了。现 Lucene 2.9 发布了,solr 1.4 也应该会比较快就要发布了。对 mmseg4j 兼容新版的 lucene/solr 也是个任务。

现 mmseg4j 发布新版 1.8,可以下载:mmseg4j-1.8.zip 包括了源码与词库,还有创建文件。下面说下此版的主要变更:

new:

1、有检测词典变更的接口,外部程序可以使用 wordsFileIsChange() 和 reload() 来完成检测与加载的工作. (内部不实现自动检测与加载,留给外部程序去做。)

2、添加 MMseg4jHandler 类,可以在solr中用url的方式来控制加载检测词库。

3、增加 CutLetterDigitFilter过虑器,切分“字母和数”混在一起的过虑器。比如:mb991ch 切为 "mb 991 ch"。

changes:

1、默认在 classpath 中加载 data 目录(词库目录),找不到再找 user.dir/data 目录。但是优先 mmseg.dic.path 系统属性指定的。

2、新词库,去除 sogou 高频无词性的词,合并 rmmseg 提供的词(是 mmseg4j 1.0 使用的词库),共计(14W 多词)。

3、数字或英文开头的数字或英文不独立分出。如 MB991CH/A 分为 mb991ch a,cq40-519tx 分为 CQ40 519TX

4、内置支持小写,不需要 LowerCaseFilter 了。MMSegAnalyzer 去除了小写过虑。

5、支持 solr 1.3/1.4、lucene 2.3/2.4/2.9

6、尝试加载 jar 里的 words.dic,并构建含有 words.dic 的 jar(mmseg4j-*-with-dic.jar)。

bugs:

1、Dictionary 添加 finalize 方法。修正 tomcat reload 时 OOM 的 bug: http://code.google.com/p/mmseg4j/issues/detail?id=4

2、MMSegTokenizer 在 lucene 2.4 编译的 在 lucene 2.9 中会报 java.lang.NoSuchFieldError: input。bug: http://code.google.com/p/mmseg4j/issues/detail?id=5

详情:http://blog.chenlb.com/2009/10/chinese-segment-mmseg4j-1_8-release.html

posted @ 2009-10-19 09:28 流浪汗 阅读(3426) | 评论 (1)编辑 收藏
中文分词 mmseg4j 1.7.2 版发布,其实两天前就发布了,只是没有写博客而已。与引版本发布的还有 1.6.2,两者基本一样,只是词库的数据结构不同,1.7的是键树,1.6的是数组与二分查找。 mmseg4j 1.7.2 版的主要更新:
  • 修复由 1.7-beta 升级到 1.7 版的 bug:添加 lowerCaseFilter 后的一个 bug: NullPointerException。
  • 核发程序与 lucene 和 solr 扩展分开打包, 同时给出低版本的 lucene 扩展(lucene 1.9 到 2.2; lucene 2.3)
如何从源码编译:下载源码:mmseg4j-1.7.2-srcmmseg4j-1.6.2-src。解压到如:e:/mmseg4j-1.7.2-src。然后到这个目录,运行:

 




上面编译是在 solr 1.3 和 lucene 2.4 环境下的。如果您要在 低版本的 lucene 中使用,到 e:/mmseg4j-1.7.2-src/contrib/lucene_1_9 或 e:/mmseg4j-1.7.2-src/contrib/lucene_2_3 运行:

 

说明:到 contrib 下的子项目中编译的话,先要编译 mmseg4j,contrib/lucene_1_9 可以支持到 2.2。

如果有任何疑问、建议,欢迎到论坛 http://groups.google.com/group/mmseg4j/topics?hl=zh_CN 讨论。或与我联系 chenlb2008#gmail.com。

还要感谢网友“苦涩可乐”提示 NullPointerException 的bug。

官方博客:mmseg4j,项目:google code mmseg4j
posted @ 2009-04-27 20:00 流浪汗 阅读(2892) | 评论 (0)编辑 收藏
很久没有在此博客写东西了。但一个多月了,原因是我已经有自己的博客空间了,此博客很少更新,不过如果写得好文就转载到此博客。

posted @ 2008-10-25 11:54 流浪汗 阅读(656) | 评论 (0)编辑 收藏
一直找代码高亮显示,在wp上可以有coolcode但,觉得美中不足的是服务器解析,每请求一次做一次。今天偶然看到 Unmi的博客,他的代码好漂亮,看源码,知道shCore,把他的拿过来试用下。 java 代码

java 代码

groovy 代码

 

posted @ 2008-09-05 00:26 流浪汗 阅读(1308) | 评论 (2)编辑 收藏
.tgz 解压:
tar zxvf myfile.tgz
posted @ 2008-09-03 13:33 流浪汗 阅读(46177) | 评论 (3)编辑 收藏
solr分发问题。
用rsync同步目录里出现:rsync:link_stat "snapshot.20080820124136/." (in solr) failed: No such file or directory (2)

上一编配置得没什么问题:http://www.blogjava.net/chenlb/archive/2008/07/04/212398.html 。现竟然出错,郁闷。

网上找了下, 说明路径有空格。http://bbs.chinaunix.net/viewthread.php?tid=1003058

二楼的回复:

带空格的文件/目录名不知道害死了多少人。

`rsync -av --progress $dir1 $dir2`;

`rsync -av --progress "$dir1" "$dir2"`;
代替。

其实 `` 虽然用着方便,
但不适合内插变量。
有变量作为参数的情况下,建议用 system。

此是解决那楼主的问题,可以本来就没有空格的问题,没解决到我的问题。仔细思索。

机子里有几个rsync服务,我部署的时候是复制相关的配置,rsync服务端口没改,子机同步这个服务的时候(子机同步端口与rsync一致,是错的,重复的),然后做同步的时候出现上面的问题。改了其它端口后就可以。

总的来讲,还是自己对linux了解不多。
posted @ 2008-09-02 16:14 流浪汗 阅读(6484) | 评论 (0)编辑 收藏
用unzip

unzip myfile.zip
posted @ 2008-09-02 16:03 流浪汗 阅读(809) | 评论 (0)编辑 收藏
上一篇记录了本机模式我虚拟分布模式。http://www.blogjava.net/chenlb/archive/2008/08/11/221311.html

现我在虚拟机里开三台机子,分别命名为:master(172.16.249.210),slave-1(172.16.249.211),slave-2(172.16.249.212)。

master可以无密码登录到slave机。
每台机子都匹配ip对应名。
127.0.0.1       localhost       localhost

172.16.249.210  master
172.16.249.211  slave-1
172.16.249.212  slave-2

修改conf/masters文件和conf/slaves文件。
conf/masters文件:
master

conf/slaves文件:
slave-1
slave-
2

格式化后可以启动了:
[chenlb@master hadoop-0.17.1]$ bin/start-all.sh 


参考资料:
http://hadoop.apache.org/core/docs/r0.17.1/quickstart.html
http://hadoop.apache.org/core/docs/r0.17.1/cluster_setup.html
posted @ 2008-08-11 15:45 流浪汗 阅读(792) | 评论 (0)编辑 收藏

 

Required Software

  1. JavaTM 1.5.x
  2. ssh与sshd

如果没有安装请自行安装。我以CentOS 4.6为例。

下载hadoop,http://apache.mirror.phpchina.com/hadoop/core/ 我下载的是0.17.1版本。

解压hadoop-0.17.1.tar.gz,然后conf/hadoop-env.sh 设置JAVA_HOME ,我是可JAVA_HOME 去注释,值自己的路径。如:

export JAVA_HOME=/usr/java/jdk1.6.0_06

如果不设置启动后用不了。

先从简单开始。

1、Local (Standalone) Mode ,叫单机模式。

[chenlb@master hadoop-0.17.1]$ bin/hadoop jar hadoop-0.17.1-examples.jar grep conf output 'dfs[a-z.]+'

 

[chenlb@master hadoop-0.17.1]$ cat output/*


如果,正常可以看到内容。像这样。

3       dfs.
3       dfs.class
2       dfs.period
2       dfs.replication
...    ...

2、Pseudo-Distributed Mode,虚拟分布模式。
vi conf/hadoop-site.xml
<configuration>
<property>
        
<name>fs.default.name</name>
        
<value>hdfs://master:9000/</value>
</property>
<property>
        
<name>mapred.job.tracker</name>
        
<value>hdfs://master:9001/</value>
</property>
<property>
        
<name>dfs.replication</name>
        
<value>1</value>
</property>
<property>
        
<name>hadoop.tmp.dir</name>
        
<value>/home/chenlb/hadoop-0.17.1/tmp/</value>
</property>
</configuration>

在/etc/hosts里添加本机ip对应master,例如我的:172.16.249.210    master
保证可以无密码登录。请看那一篇文章:http://www.blogjava.net/chenlb/archive/2008/07/03/212293.html

用ssh localhost试一下是否免密码登录。

格式化分布式文件系统:
[chenlb@master hadoop-0.17.1]$ bin/hadoop namenode -format

启动Hadoop:
[chenlb@master hadoop-0.17.1]$ bin/start-all.sh 

默认可以在${HADOOP_HOME}/logs里看到日志。

可以用web看浏览NameNode和JobTracker
  • NameNode - http://localhost:50070/
  • JobTracker - http://localhost:50030/


    把文件放到分布式文件系统里:

    [chenlb@master hadoop-0.17.1]$ bin/hadoop dfs -put conf input

    此时已经在分布文件系统里建立了input文件夹。而conf是本地的文件夹。

    执行示例:
    [chenlb@master hadoop-0.17.1]$ bin/hadoop jar hadoop-*-examples.jar grep input output 'dfs[a-z.]+'

    这里input和output都是分布式文件系统的的文件夹,而且output在分布式文件系统里不存在,否则报错(也可以先删除它bin/badoop dfs -rmr output)。

    耐心等待。结束后可以查看。
    [chenlb@master hadoop-0.17.1]$ bin/hadoop dfs -get output output 
    [chenlb
    @master hadoop-0.17.1]$ cat output/* 

    也可以直接在分布式文件系统里查:
    [chenlb@master hadoop-0.17.1]$ bin/hadoop dfs -cat output/*

    成功运行后可以关闭它了:
    [chenlb@master hadoop-0.17.1]$ bin/stop-all.sh

    我在第2阶段,出了些问题:output已经存在,要先删除它(第二次运行前,可以不用output)。

    下一篇讲:Fully-Distributed Mode http://www.blogjava.net/chenlb/archive/2008/08/11/221314.html
  • posted @ 2008-08-11 15:28 流浪汗 阅读(4944) | 评论 (2)编辑 收藏
    在linux下改了ip地址后,不能立即生效。以前是重启机器,我觉得这样很傻,后来知道网卡可以重启。

    /etc/init.d/network restart
    posted @ 2008-08-11 09:34 流浪汗 阅读(6056) | 评论 (1)编辑 收藏
    一直想了解分布搜索与索引。Lucene有MultiSearcher,solr1.2的只能有单个索引,现在1.3可以有Distributed Searching这玩意。可以从多个索引里搜索出并合并结果返回给你。这些索引不是replication的,是分割的。可以先%num方式索引在num台机器上,然后用solr的shards参数。

    如:
    shards=localhost:8080/use-solr1.3,localhost:9080/use-solr1.3&q=chenlb

    测试后可以返回结果,但合并的时候发了点时间,我的机子上40-60ms,单个搜索基本是0ms

    测试数据是14W结果,分开索引到两个tomcat里。看了后台,一个搜索有两次请求,其中合并的那机子是三次请求。时间可能花在请求里,还有就是合并可能缓存不到。

    官方建议:如果单个solr足够快的话没有必要搞Distributed Searching,如果再高点要求可以index repliction。

    当索引很大的时候可能Distributed Searching用的上场, 个人之见。

    参考:http://wiki.apache.org/solr/DistributedSearch
    posted @ 2008-08-07 18:31 流浪汗 阅读(1009) | 评论 (0)编辑 收藏
    html 与 xml的转义符不同, xml就只有5个:

    < &lt;
    > &gt;
    & &amp;
    " &quot;
    ' &apos;


    xml没有&nbsp;
    posted @ 2008-08-06 12:40 流浪汗 阅读(15374) | 评论 (2)编辑 收藏
    我比较喜欢免安装版(非安装版)的mysql,

    下载如: mysql-noinstall-5.0.45-win32.zip

    把它解压到如: E:/mysql-5.0.45, 当然可以任意位置。

    然后改my-medium.ini文件为my.ini,当然也可以不改名,但要改内容

    basedir="E:/mysql-5.0.45/"

    datadir
    ="E:/mysql-5.0.45/Data/"

    如果上面,最好加个字符集,在[mysqld]和[mysql]下面加
    default-character-set=utf8

    当然可能是其它字符集, 如:gbk

    写个mysql-startup.bat
    "E:\mysql-5.0.45\bin\mysqld" --defaults-file="E:\mysql-5.0.45\my.ini"

    双击mysql-startup.bat即可启动。

    用mysqladmin关闭mysql服务:
    E:/mysql-5.0.45/bin/mysqladmin -u root shutdown


    ^_^
    posted @ 2008-08-03 16:22 流浪汗 阅读(3081) | 评论 (1)编辑 收藏
        想让Tomcat支持ssi,一般是shtml文件。配置比较简单。

    默认tomcat不支持ssi。

    现以tomcat5.5.x为例。

    改conf/web.xml配置。

    有两种方式:一是servlet,二是filter。

    servlet方式的:
    <!--
        <servlet>
            <servlet-name>ssi</servlet-name>
            <servlet-class>
              org.apache.catalina.ssi.SSIServlet
            </servlet-class>
            <init-param>
              <param-name>buffered</param-name>
              <param-value>1</param-value>
            </init-param>
            <init-param>
              <param-name>debug</param-name>
              <param-value>0</param-value>
            </init-param>
            <init-param>
              <param-name>expires</param-name>
              <param-value>666</param-value>
            </init-param>
            <init-param>
              <param-name>isVirtualWebappRelative</param-name>
              <param-value>0</param-value>
            </init-param>
            <load-on-startup>4</load-on-startup>
        </servlet>
    -->

    <!--
        <servlet-mapping>
            <servlet-name>ssi</servlet-name>
            <url-pattern>*.shtml</url-pattern>
        </servlet-mapping>
    -->

    找到上面的内容,去掉注释。

    filter方式:
    <!--
        <filter>
            <filter-name>ssi</filter-name>
            <filter-class>
              org.apache.catalina.ssi.SSIFilter
            </filter-class>
            <init-param>
              <param-name>contentType</param-name>
              <param-value>text/x-server-parsed-html(;.*)?</param-value>
            </init-param>
            <init-param>
              <param-name>debug</param-name>
              <param-value>0</param-value>
            </init-param>
            <init-param>
              <param-name>expires</param-name>
              <param-value>666</param-value>
            </init-param>
            <init-param>
              <param-name>isVirtualWebappRelative</param-name>
              <param-value>0</param-value>
            </init-param>
        </filter>
    -->

    <!--
        <filter-mapping>
            <filter-name>ssi</filter-name>
            <url-pattern>*.shtml</url-pattern>
        </filter-mapping>
    -->

    同样是去掉上面的注释。但是filter方式的还要加mime-mapping=text/x-server-parsed-html
    <!--
        <mime-mapping>
            <extension>shtml</extension>
            <mime-type>text/x-server-parsed-html</mime-type>
        </mime-mapping>
    -->

    去掉mime-mapping的shtml注释。

    在test的web试下:
    index.shtml
    <!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 http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>ssi 示例</title>
    </head>

    <body>
    ssi area 
    <!--#include virtual="ssi.html" -->
    <p>

            footer 
    <!--#include virtual="footer.html" --><p>
            
            
    <p>
                
    <!--#config timefmt="%D" -->
            Me last modified 
    <!--#echo var="LAST_MODIFIED" -->

    </body>
    </html>

    footer.html
    <ul>
        
    <li>index</li>
        
    <li>about</li>
    </ul>

    ssi.html
    <p>this is ssi.html file</p><p>
    <p>中文</p>
    ssi.html file end
    <p/>


    现在可以,http://localhost:8080/test/index.shtml 有结果了。
    posted @ 2008-07-27 21:55 流浪汗 阅读(1370) | 评论 (0)编辑 收藏
        有一个项目的代码提交是用https协议的。一提交的时候出现如下错误:

    svn: PROPFIND request failed on '/svn/trunk/xxx'
    svn: PROPFIND of '/svn/trunk/xxx': Could not create SSL connection through proxy server (https://.

        这下郁闷,看了下eclipse设置,又没有设代理。google一下,看到一个邮件列表,有一个字眼“TSVN”。哦,快去看看TortoiseSVN。任意一个目录右击->TortoiseSVN->设置->网络,有学校时用的代理。去掉一试,好了没错了。

        前端时间用Subclipse时,一定要安装TortoiseSVN才可保存密码,现在又TortoiseSVN的设置Subclipse又有效。带着探索心去看eclipse的设置。Team->svn那里有一个选项:

    SVN接口:
    1.JavaHL(JNI)
    2.SVNkit(纯Java)

    原来选的是JavaHL(JNI),现在明白了。改用SVNkit试一下,现在的subclipse不会理TortoiseSVN了。

    posted @ 2008-07-26 13:34 流浪汗 阅读(3707) | 评论 (0)编辑 收藏
    有些windows操作系统被人"强奸"过的, 导致语言栏变灰色,无法显示,在任务栏里不显示.

    一般是ctfmon.exe问题. 看下C:\windows\system32\ctfmon.exe文件. 没有就下载

    http://www.blogjava.net/Files/chenlb/ctfmon_xp.rar

    安装它,

    然后在: 控制面板->区域和语言选项->语言->详细信息->高级->去掉"关闭高级文字服务"

    即可.

    那一种(百度知道): http://zhidao.baidu.com/question/31477300.html

    看你是使用2003 还是XP系统

    要是XP系统的话了就设置两个地方
    1.开始,运行,msconfig,勾选ctfmon.exe

    控制面板--区域和语言选项--语言--详细信息--高级--不要选“关闭高级文字服务”
    2.开始--控制面板--日期、时间、语言和区域设置--区域和语言选择--语言--详细信息--语言栏(选择在桌面显示语言栏 还有 选择:在任务栏中显示其他语言栏图标)

    参考: http://www.nvyouwm.cn/html/jishuwendang/huanjingpeizhi/20080602/266_2.html
    posted @ 2008-07-12 13:26 流浪汗 阅读(7552) | 评论 (9)编辑 收藏
    setTimeout(script,millisecond); 是从现在算起多少微秒后运行该代码(只运行一次)

    setInterval(script,millisecond);  是每隔多少微秒运行一次代码

    示例:
    1.执行一次
    <span id="time"></span> 秒
    <script type="text/javascript">
    var i = 1;
    var txt = document.getElementById("time");
    function addT(i) {
    txt.innerHTML
    =i;
    }
    setTimeout("addT(i++)",1000);
    </script>


    2.复制执行
    <span id="time">3</span> 秒
    <script type="text/javascript">
    var i = 1;
    var txt = document.getElementById("time");
    function addT(i) {
    txt.innerHTML
    =i;
    }
    setInterval(
    "addT(i++)",1000); 
    </script>

    setTimeout也可以做成重复执行
    <span id="time"></span> 秒
    <script type="text/javascript">
    var i = 1;
    var txt = document.getElementById("time");
    function addT(i) {
    txt.innerHTML
    =i;
    setTimeout(
    "addT(i++)",1000);
    }
    addT(i);
    </script>
    posted @ 2008-07-10 21:36 流浪汗 阅读(1070) | 评论 (0)编辑 收藏

    linux下的很软件都是 tar.gz后缀的,解压久了不用就忙了,写备忘。现我知的直接解压方法有两种

    1.gunzip与tar

    gunzip < *.tar.gz | tar -xvf -

    2.只用tar
    tar -zxvf *.tar.gz

    说明:
    z表示:通过gzip指令处理备份文件
    x表示:解压
    v表示:输出解压过程信息
    f表示:指定备份文件
    posted @ 2008-07-08 11:14 流浪汗 阅读(2510) | 评论 (0)编辑 收藏
    solr 1.3 还没有正式发布,在这里记录下从solr 1.2的主要改动:
    1. solrj     solr的java客户端,可以嵌入搜索(不是http/xml交互)
    2. multi-core     多核心——1个web应用可以用多种的搜索服务,即可以多个schema.xml
    3. search components    搜索组件。
    4. distributed search    分布式搜索。

    api的变动:

    1. org.apache.util 包下的大部分类移到org.apache.common.util包下面。
    2. org.apache.solr.request包下面的很多类移到org.apache.solr.common.params包下面。
    3. org.apache.solr.request.StandardRequestHandler 类改为 org.apache.solr.handler.StandardRequestHandler,同时它改为org.apache.solr.handler.SearchHandler的子类
    4. org.apache.solr.request.DisMaxRequestHandler 类改为 org.apache.solr.handler.DisMaxRequestHandler,同时不推荐在 StandardRequestHandler 的初始参数用'defType=dismax' 。
    posted @ 2008-07-08 10:20 流浪汗 阅读(440) | 评论 (0)编辑 收藏
        solr 分布式其实是分发,这概念像Mysql的复制。所有的索引的改变都在主服务器里,所有的查询都在从服务里。从服务器不断地(定时)从主服务器拉内容,以保持数据一致。

    先描述下我的环境:
    solr-master(192.168.1.181), solr-slave(192.168.1.155), jdke1.6.0_06, tomcat-5.5.26, solr-1.2 
    tomcat_home在 /home/chenlb/tomcat-5.5.26
    solr_home在 /home/chenlb/solr-home
    solr解压后的目录 /home/chenlb/solr-1.2.0
    最好两机可以ssh无密码交互,ssh无密码登录请看:http://www.blogjava.net/chenlb/archive/2008/07/03/212293.html

        solr的分发是用rsync的。
        快照与分发过程:

    1.snapshooter 命令在主服务器产生快照。一般在commit和optimize之后被solr调用。

    2.snappuller 命令在从服务器运行,所做的事是从主服务器拉最新的快照。 用rsync的daemon模式来运行可以获得更好的性能与更底的CPU利用率。

    3.snapinstaller 命令在从服务器运行,当从服务器从主服务器拉完快照后才执行。它会通知本地Solr服务器打开一个新的index reader,然后预热这个新index reader的缓存,此时有请求,原来的index reader继续为这此请求服务。一但预热完成,Solr 启用新的index reader,旧的被消亡。

        Solr 的Distribution(分发) 在Scripts文件里记录。在solr_home/conf/scripts.conf文件里。

    我现在这样配置:
    user=chenlb
    solr_hostname
    =localhost
    solr_port
    =8080
    rsyncd_port
    =18080
    data_dir
    =/home/chenlb/solr-home/data
    webapp_name
    =solr
    master_host
    =192.168.1.181
    master_data_dir
    =/home/chenlb/solr-home/data
    master_status_dir
    =/home/chenlb/solr-home/logs

    上面的配置两机都一样。

    1.安装好solr后启动它们,怎样在tomcat安装solr请看:http://www.blogjava.net/chenlb/archive/2008/03/25/188459.html
    [chenlb@solr-master ~]$ ./tomcat-5.5.26/bin/startup.sh

    启用且启动rsync
    [chenlb@solr-master ~]$ ./solr-home/bin/rsyncd-enable -u chenlb -v
    [chenlb@solr-master ~]$ ./solr-home/bin/rsyncd-start -u chenlb -v


    [chenlb@solr-slave ~]$ ./tomcat-5.5.26/bin/startup.sh

    2.solr-master
    先修改post.sh
    [chenlb@solr-master ~]$ cd solr-1.2.0/example/exampledocs/
    [chenlb@solr
    -master exampledocs]$ vi post.sh
    [chenlb@solr
    -master exampledocs]$
    #把http://localhost:8389/solr/update改下面的
    http://localhost:8080/solr/update

    提交数据
    [chenlb@solr-master exampledocs]$ ./post.sh *.xml

    产生快照
    [chenlb@solr-master ~]$ ./solr-home/bin/snapshooter -u chenlb -v

    说明:由于<listener event="postCommit" class="solr.RunExecutableListener">...</listener>没有设置成功(出现java.io.IOException: Cannot run program "snapshooter" (in directory "solr/bin"): java.io.IOException: error=2, No such file or directory,现在还没解决),可以只能手动生成快照(当然也可以cron)

    3.solr-slave
    启用快照下拉
    [chenlb@solr-slave ~]$ ./solr-home/bin/snappuller-enable -u chenlb -v

    拉快照
    [chenlb@solr-slave ~]$ ./solr-home/bin/snappuller -u chenlb -v

    安装
    [chenlb@solr-slave ~]$ ./solr-home/bin/snapinstaller -u chenlb -v


    现在可以在solr-slave里看结果了:
    http://192.168.1.155:8080/solr/select?q=solr
    http://192.168.1.181:8080/solr/select?q=solr

    看结果是否一样。
    posted @ 2008-07-04 16:49 流浪汗 阅读(3151) | 评论 (0)编辑 收藏

        由于svn服务器的调整,很多项目里的链接还是旧的服务器,又由于项目里有些东西还没有提交,所不能删除svn的元数据,怎样才能适应svn的迁移呢?

        我的项目全在Eclipse下面,用subclipse客户端,在subclipse找了好久没找到此功能,最后在TortoiseSVN找,找到了右击本地与svn相连的目录-->"TortoiseSVN"-->"Reloate..."在to URL那改就行了。^_^
     
        subclipse远不如TortoiseSVN强大,且它还依赖TortoiseSVN——如果没有TortoiseSVN,subclipse不能保存密码。

    posted @ 2008-07-04 11:06 流浪汗 阅读(1516) | 评论 (1)编辑 收藏
    ssh 无密码登录要使用公钥与私钥。linux下可以用用ssh-keygen生成公钥/私钥对,下面我以CentOS为例。

    有机器A(192.168.1.155),B(192.168.1.181)。现想A通过ssh免密码登录到B。

    1.在A机下生成公钥/私钥对。
    [chenlb@A ~]$ ssh-keygen -t rsa -''

    -P表示密码,-P '' 就表示空密码,也可以不用-P参数,这样就要三车回车,用-P就一次回车。
    它在/home/chenlb下生成.ssh目录,.ssh下有id_rsa和id_rsa.pub。

    2.把A机下的id_rsa.pub复制到B机下,在B机的.ssh/authorized_keys文件里,我用scp复制。
    [chenlb@A ~]$ scp .ssh/id_rsa.pub chenlb@192.168.1.181:/home/chenlb/id_rsa.pub 
    chenlb@
    192.168.1.181's password:
    id_rsa.pub                                    100%  223     0.2KB/s   00:00

    由于还没有免密码登录的,所以要输入密码。

    3.B机把从A机复制的id_rsa.pub添加到.ssh/authorzied_keys (打错了,使用下面的代码块)文件里。
    [chenlb@B ~]$ cat id_rsa.pub >> .ssh/authorized_keys
    [chenlb@B 
    ~]$ chmod 600 .ssh/authorized_keys

    authorized_keys的权限要是600

    4.A机登录B机。
    [chenlb@A ~]$ ssh 192.168.1.181
    The authenticity of host 
    '192.168.1.181 (192.168.1.181)' can't be established.
    RSA key fingerprint is 00:a6:a8:87:eb:c7:40:10:39:cc:a0:eb:50:d9:6a:5b.
    Are you sure you want to 
    continue connecting (yes/no)? yes
    Warning: Permanently added 
    '192.168.1.181' (RSA) to the list of known hosts.
    Last login: Thu Jul  
    3 09:53:18 2008 from chenlb
    [chenlb@B 
    ~]$

    第一次登录是时要你输入yes。

    现在A机可以无密码登录B机了。

    小结:登录的机子可有私钥,被登录的机子要有登录机子的公钥。这个公钥/私钥对一般在私钥宿主机产生。上面是用rsa算法的公钥/私钥对,当然也可以用dsa(对应的文件是id_dsa,id_dsa.pub)

    想让A,B机无密码互登录,那B机以上面同样的方式配置即可。

    参考:SSH-KeyGen 的用法 http://blog.163.com/chen98_2006@126/blog/static/158584272007101862513886/
    posted @ 2008-07-03 12:19 流浪汗 阅读(13712) | 评论 (3)编辑 收藏
    我用CentOS为例。

    简介:
        cron来源于希腊单词chronos(意为“时间”),是linux系统下一个自动执行指定任务的程序。例如,你想在每晚睡觉期间创建某些文件或文件夹的备份,就可以用cron来自动执行。

    CentOS的cron默认是开机启动的,如果没有开机启动可以用chkconfig
    [root@chenlb-pc ~]# chkconfig crond on

    查看crond是否开机启动
    [root@chenlb-pc ~]# chkconfig --list crond
    crond           0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭

    说明已经是开机启动。

    cron是执行crontab里的任务,所以要把任务加到crontab里。

    1.查看当前用户的任务。
    [chenlb@chenlb-pc ~]$ crontab -l
    no crontab 
    for chenlb

    现在还没有任务,可以用crontab -e来编辑任务(可以直接输入crontab是新建,然后回车,Ctrl+D保存,注意这样会覆盖以前的,不建议直接用crontab),然后再新的文件里输入以下内容。

    2.编辑任务
    [chenlb@chenlb-pc ~]$ crontab -e

    */1 * * * * echo `date` >> /home/chenlb/cron-log.txt

    上面的意思是指每一分钟打印时间放到/home/chenlb/cron-log.txt文件里,过一分钟后看是否有效,如下命令。
    [chenlb@chenlb-pc ~]$ tail /home/chenlb/cron-log.txt
    Wed Jul 
    2 15:43:01 CST 2008

    3.删除任务
    [chenlb@chenlb-pc ~]$ crontab -r


    说明:如果是root除了有以上的功能,还有-u参数为用户查看、编辑、删除任务,如用chenlb编辑任务。
    [root@chenlb-pc ~]# crontab -u chenlb -e

    解说下任务的语法:
        min hour day month week user command

    忽略用“*”,每多少的用“/多少”,多个的用“,”,到关系的用“-”

    ---------------------------------来自htmlor's blog的示例----------------------------------------------

    以下是cron语句中的字段与字段说明:

    字段 说明
    1 分钟(0-59)
    2 小时(2-24)
    3 日期(1-31)
    4 月份(1-12;或英文缩写Jan、Feb等)
    5 周几(0-6,0为周日;或单词缩写Sun、Mon等)
    6 用户名(执行命令时以此用户的身份)
    7 要执行的命令(路径)

    现在来看第一行:

    12 3 * * * root tar czf /usr/local/backups/daily/etc.tar.gz /etc >> /dev/null 2>&1

    这条语句将在每天的凌晨3点12分(03:12)运行 tar czf /usr/local/backups/daily/etc.tar.gz /etc 命令。>> /dev/null 2>&1 表示把所有标准输出发送到 /dev/null(linux的回收站),把标准错误输出(2)发送到和标准输出(1)同样的地方(即 /dev/null)。运行这行命令将不会产生任何输出。

    这条语句可以变得稍微复杂一点:

    30 15 13 6 1 * root tar czf /usr/local/backups/daily/etc.tar.gz /etc >> /dev/null 2>&1

    它将在6月13日周一的15:30运行 tar czf /usr/local/backups/daily/etc.tar.gz /etc 命令。

    以下语句可以达到同样的效果:

    30 15 13 Jun Mon * root tar czf /usr/local/backups/daily/etc.tar.gz /etc >> /dev/null 2>&1

    如果你想以用户joey的身份每小时的第15分钟运行某个程序,可以使用:

    15 * * * * joey /usr/bin/somecommand >> /dev/null 2>&1

    其中的星号(*)是通配符,表示cron将忽略这个字段。

    如果你想每两小时就运行某个程序,可以在小时字段里使用 */2。它将会在2点,4点,6点……22点,24点运行。具体语句如下:

    0 */2 * * * joey /usr/bin/somecommand >> /dev/null 2>&1

    cron语句中还可以使用逗号(,)来指定多个时间。例如你想在每小时的15分和30分运行某个程序,可以在分钟字段使用 15,30

    15,30 * * * * joey /usr/bin/somecommand >> /dev/null 2>&1

    如果你想在每月的第一周(即1号到7号)每天的指定时间运行某个程序,可以在日期字段使用 1-7

    15,30 */2 1-7 * * joey /usr/bin/somecommand >> /dev/null 2>&1

    这条语句将在每月的第1-7日每两小时的15分和30分(02:15,02:30……22: 15,22:30等)运行 /usr/bin/somecommand 命令。

    如果你想在每天的16:18执行一个脚本集合,可以把所有要执行的脚本放到一个目录中(如 /home/username/cron),可以使用:

    18 16 * * * root run-parts /home/username/cron >> /dev/null 2>&1

    如果你想保存某个程序的输出结果, 可以把 >> /dev/null 2>&1 替换为 >> /home/user/somecommand.log 2>&1



    参考:http://blog.htmlor.com/2006/07/25/cron_guide/
    posted @ 2008-07-02 16:23 流浪汗 阅读(5367) | 评论 (0)编辑 收藏
     Solr 涉及的术语,简单介绍下:
    • Auto-warming(自动预热) 当打开一个新的缓存时,它把在旧缓存里命中较高的键/值添加到新的缓存里。
    • Constraint(限制) 限制对象集的方法。
    • Facet(层面) 对象集的一个方面或特定的一部分,这可以用来资源分类。
    • Filter(过虑器) 它由上下方决定,可能是:
      1. Constraint(限制)的那称呼。
      2. 限制查询结果的"fq"参数。
      3. 涉及特定的Lucene的"Filter"类。
    • Solr Home Dir(Solr主目录) 又叫Solr Home Directory或Solr Home,它是Solr查找配置文件、数据、插件的主要目录,默认是./solr目录,可以JNDI配置solr/home属性,也可配置系统的solr.solr.home属性。
    • Static warming(静态预热) 当newSearcher 和 firstSearcher 的事件监听器强逼预热事件时,Solr会根据solrconfig.xml配置里的"static"查询来填充缓存。

    来源:http://wiki.apache.org/solr/SolrTerminology

     

    说的不对的地方,希望指出,一起学习。

    posted @ 2008-06-27 13:29 流浪汗 阅读(466) | 评论 (0)编辑 收藏

        两字符串相似度计算方法有好多,现对基于编距的算法的相似度计算自己总结下。

     

        简单介绍下Levenshtein Distance(LD):LD 可能衡量两字符串的相似性。它们的距离就是一个字符串转换成那一个字符串过程中的添加、删除、修改数值。

        举例:

    • 如果str1="test",str2="test",那么LD(str1,str2) = 0。没有经过转换。
    • 如果str1="test",str2="tent",那么LD(str1,str2) = 1。str1的"s"转换"n",转换了一个字符,所以是1。

    如果它们的距离越大,说明它们越是不同。

     

         Levenshtein distance最先是由俄国科学家Vladimir Levenshtein在1965年发明,用他的名字命名。不会拼读,可以叫它edit distance(编辑距离)。

     

        Levenshtein distance可以用来:

    • Spell checking(拼写检查)
    • Speech recognition(语句识别)
    • DNA analysis(DNA分析)
    • Plagiarism detection(抄袭检测)

    LD用m*n的矩阵存储距离值。算法大概过程:

    1. str1或str2的长度为0返回另一个字符串的长度。
    2. 初始化(n+1)*(m+1)的矩阵d,并让第一行和列的值从0开始增长。
    3. 扫描两字符串(n*m级的),如果:str1[i] == str2[j],用temp记录它,为0。否则temp记为1。然后在矩阵d[i][j]赋于d[i-1][j]+1 、d[i][j-1]+1、d[i-1][j-1]+temp三者的最小值。
    4. 扫描完后,返回矩阵的最后一个值即d[n][m]

    最后返回的是它们的距离。怎么根据这个距离求出相似度呢?因为它们的最大距离就是两字符串长度的最大值。对字符串不是很敏感。现我把相似度计算公式定为1-它们的距离/字符串长度最大值。

     

        源码:

    package com.chenlb.algorithm;

    /**
     * 编辑距离的两字符串相似度
     * 
     * 
    @author chenlb 2008-6-24 下午06:41:55
     
    */
    public class Similarity {

        
    private int min(int one, int two, int three) {
            
    int min = one;
            
    if(two < min) {
                min 
    = two;
            }
            
    if(three < min) {
                min 
    = three;
            }
            
    return min;
        }
        
        
    public int ld(String str1, String str2) {
            
    int d[][];    //矩阵
            int n = str1.length();
            
    int m = str2.length();
            
    int i;    //遍历str1的
            int j;    //遍历str2的
            char ch1;    //str1的
            char ch2;    //str2的
            int temp;    //记录相同字符,在某个矩阵位置值的增量,不是0就是1
            if(n == 0) {
                
    return m;
            }
            
    if(m == 0) {
                
    return n;
            }
            d 
    = new int[n+1][m+1];
            
    for(i=0; i<=n; i++) {    //初始化第一列
                d[i][0= i;
            }
            
    for(j=0; j<=m; j++) {    //初始化第一行
                d[0][j] = j;
            }
            
    for(i=1; i<=n; i++) {    //遍历str1
                ch1 = str1.charAt(i-1);
                
    //去匹配str2
                for(j=1; j<=m; j++) {
                    ch2 
    = str2.charAt(j-1);
                    
    if(ch1 == ch2) {
                        temp 
    = 0;
                    } 
    else {
                        temp 
    = 1;
                    }
                    
    //左边+1,上边+1, 左上角+temp取最小
                    d[i][j] = min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+temp);
                }
            }
            
    return d[n][m];
        }
        
        
    public double sim(String str1, String str2) {
            
    int ld = ld(str1, str2);
            
    return 1 - (double) ld / Math.max(str1.length(), str2.length()); 
        }
        
        
    public static void main(String[] args) {
            Similarity s 
    = new Similarity();
            String str1 
    = "chenlb.blogjava.net";
            String str2 
    = "chenlb.javaeye.com";
            System.out.println(
    "ld="+s.ld(str1, str2));
            System.out.println(
    "sim="+s.sim(str1, str2));
        }
    }

    不知sim方法中的公式是合理,个人认为差强人意思,^_^

     

    参考: http://www.merriampark.com/ld.htm

    posted @ 2008-06-25 10:08 流浪汗 阅读(3822) | 评论 (2)编辑 收藏
        发现中国科学技术大学有快速的CentOS的镜像。具体设置如下:
    1.以root用户进入CentOS系统。
    [root@chenlb ~]# cd /etc/yum.repos.d

    2.备份repo
    [root@chenlb yum.repos.d]# mv CentOS-Base.repo  CentOS-Base.repo.save

    3.从USTC下载新的repo
    [root@chenlb yum.repos.d]# wget http://centos.ustc.edu.cn/CentOS-Base.repo

    现在可以yum了。^_^

    链接:http://centos.ustc.edu.cn/
    posted @ 2008-06-24 23:45 流浪汗 阅读(1499) | 评论 (2)编辑 收藏
        用String.substring方法,不小心会有越界异常。现实现一个没抛出越界异常,越界就返回null,不过直接返回的再用其它方法,可能有Null异常。现还实现可以负index的,可能逆向的。
    package com.chenlb.util;   
      
    public class StringUtil {   
           
        
    /**  
         * start与end均可负数<br/>  
         * start < end正向取, start > end逆向取<br/>  
         * 示例:str="I am chenlb"<br/>  
         * StringUtil.substring(str, 0, 12) -> null<br/>  
         * StringUtil.substring(str, 12, 12) -> null<br/>  
         * StringUtil.substring(str, 12, 13) -> null<br/>  
         * StringUtil.substring(str, 4, 4) -> ""<br/>  
         * StringUtil.substring(str, 0, 4) -> "I am"<br/>  
         * StringUtil.substring(str, -4, -1) -> "enl"<br/>  
         * StringUtil.substring(str, -2, 4) -> "lbI am"<br/>  
         * StringUtil.substring(str, 4, 0) -> "ma I"<br/>  
         * StringUtil.substring(str, -1, -4) -> "lne"<br/>  
         * StringUtil.substring(str, 1, -4) -> "Iblne"<br/>  
         * StringUtil.substring(str, 0, -4) -> "blne"<br/>  
         * StringUtil.substring(str, -4, 0) -> "enlb"<br/>  
         * 
    @return 越界返回null, start==end返回空  
         * 
    @author chenlb 2008-6-18 下午12:39:51  
         
    */  
        
    public static String substring(String str, int start, int end) {   
            
    if(str == null) {   
                
    return null;   
            }   
            
    int len = str.length();   
            
    if(Math.abs(start) >= len) {   
                
    return null;   
            }   
            
    if(Math.abs(end) > len) {   
                
    return null;   
            }   
            StringBuilder sb 
    = new StringBuilder();   
            
    if(end > start) {    //正向   
                substring(sb, str, start, end);   
            } 
    else if(end == start) {   
                
    return "";   
            } 
    else {    //逆向 end < start   
                substring(sb, str, end, start);   
                sb.reverse();   
            }   
            
    return sb.toString();   
        }   
           
        
    private static void substring(StringBuilder sb, String str, int start, int end) {   
            
    int len = str.length();   
            
    if(start < 0) {   
                
    if(end < 0) {   
                    sb.append(str.substring(len
    +start, len+end));   
                } 
    else {   
                    sb.append(str.substring(len
    +start, len));   
                    sb.append(str.substring(
    0, end));   
                }   
            } 
    else {   
                sb.append(str.substring(start, end));   
            }   
        }   
    }  

    测试代码:
    public void testSubstring() {   
            String str 
    = "I am chenlb";   
               
            assertEquals(
    null, StringUtil.substring(str, 012));   
            assertEquals(
    null, StringUtil.substring(str, 1212));   
            assertEquals(
    null, StringUtil.substring(str, 1213));   
               
            assertEquals(
    "", StringUtil.substring(str, 44));   
               
            assertEquals(
    "I am", StringUtil.substring(str, 04));   
            assertEquals(
    "am", StringUtil.substring(str, 24));   
            assertEquals(
    "I am chenlb", StringUtil.substring(str, 011));   
               
            assertEquals(
    "enl", StringUtil.substring(str, -4-1));   
            assertEquals(
    "lbI am", StringUtil.substring(str, -24));   
               
            assertEquals(
    "ma I", StringUtil.substring(str, 40));   
            assertEquals(
    "lne", StringUtil.substring(str, -1-4));   
            assertEquals(
    "Iblne", StringUtil.substring(str, 1-4));   
               
            assertEquals(
    "blne", StringUtil.substring(str, 0-4));   
            assertEquals(
    "enlb", StringUtil.substring(str, -40));   
    }  
    posted @ 2008-06-24 13:53 流浪汗 阅读(546) | 评论 (0)编辑 收藏

    Windows网络命令行程序 

     
    ipconfig /all 查看配置 
    ipconfig /renew 刷新配置 
    ipconfig 管理 DNS 和 DHCP 类别 ID
    Ping 测试连接
    Arp 解决硬件地址问题
    nbtstat 解决 NetBIOS 名称问题
    netstat 显示连接统计
    tracert 跟踪网络连接
    pathping 测试路由器

    posted @ 2008-06-24 13:51 流浪汗 阅读(262) | 评论 (0)编辑 收藏

        今天运行下程序,报错说“内存不够”。在Tomcat可以扩大JVM的内存栈呢?然后看那bin目录下启动文件,找到catalina.bat文件的JAVA_OPTS(大概在103行,5.5.X),在再添加一个set JAVA_OPTS参数即可如:

    set JAVA_OPTS=%JAVA_OPTS% -Xms100m -Xmx512m 
    posted @ 2008-06-24 13:49 流浪汗 阅读(365) | 评论 (0)编辑 收藏
        前段时间学习Linux命令,偶然发现curl命令很有用。这里简单介绍下。网络上部分解析是:curl是一个利用URL语法在命令行方式下工作的文件传输工具。

       它可以取得有规律的url的内容。比如:http://www.example.com/001.html 到 http://www.example.com/100.html ,它有一种表达式可以这些内容下载下来,这功能绝对比迅雷强,迅雷只支持一个变量,curl只你喜欢可任意多。它可继点续传,提交表单……

       来看下简单的使用:

    1.查看响应的头
    curl -I http://chenlb.javaeye.com 
    现在正如robbin说的可以看下X-Runtime: 0.47101

    2.在学校要代理才可以上javaeye.com。用-x设代理
    curl -x proxy.gdut.edu.cn:8080 -I http://chenlb.javaeye.com 

    3.把返回的内容保存下来,用-o filename参数
    curl -o chenlb.html http://chenlb.javaeye.com  

    4.保存内容时要filename很烦,用一个-O参数来指定用服务器的文件名,这个批量下载很有用。
    curl -O http://baike.baidu.com/view/[1-2].htm
    批量下载百科的1.htm 2.htm两个页面,这功能够强。

    我常用的就是以上四个。

    5.很多要referer的,有-e参数可以设置
    curl -o me.html -e http://www.javaeye.com http://chenlb.javaeye.com  

    还有很多很多参数,留给大家去发现,比如:发送数据,提交表单,设置用户与密码,用什么协议啊……
    posted @ 2008-06-24 13:47 流浪汗 阅读(1489) | 评论 (0)编辑 收藏
          java命令引入jar时可以-cp参数,但时-cp不能用通配符(多个jar时什么烦要一个个写,不能*.jar),面通常的jar都在同一目录,且多于1个。前些日子找到(发现)-Djava.ext.dirs太好。

    如:

    java -Djava.ext.dirs=lib MyClass  
    posted @ 2008-06-22 23:58 流浪汗 阅读(5070) | 评论 (0)编辑 收藏
        javascript xslt 处理xml备忘录。支持firefox。
    参考:
    w3school XSLT - 客户端 http://www.w3school.com.cn/xsl/xsl_client.asp
    如何使用Javascript XSLT 处理XML文件 http://java.chinaitlab.com/advance/533787.html

    1.xml文件,cdcatalog.xml
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <catalog>
        
    <cd>
            
    <title>Empire Burlesque</title>
            
    <artist>Bob Dylan</artist>
            
    <country>USA</country>
            
    <company>Columbia</company>
            
    <price>10.90</price>
            
    <year>1985</year>
        
    </cd>
        
    <cd>
            
    <title>Hide your heart</title>
            
    <artist>Bonnie Tyler</artist>
            
    <country>UK</country>
            
    <company>CBS Records</company>
            
    <price>9.90</price>
            
    <year>1988</year>
        
    </cd>
    </catalog>

    2.xsl文件,cdcatalog.xsl
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <xsl:stylesheet version="1.0"
    xmlns:xsl
    ="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>

    <xsl:template match="/">
      
    <html>
      
    <body>
      
    <h2>My CD Collection</h2>
        
    <table border="1">
          
    <tr bgcolor="#9acd32">
            
    <th align="left">Title</th>
            
    <th align="left">Artist</th>
          
    </tr>
          
    <xsl:for-each select="catalog/cd">
          
    <tr>
            
    <td><xsl:value-of select="title"/></td>
            
    <td><xsl:value-of select="artist"/></td>
          
    </tr>
          
    </xsl:for-each>
        
    </table>
      
    </body>
      
    </html>
    </xsl:template>
    </xsl:stylesheet>


    3.html文件,index.html
    <html>
    <body>

    <script type="text/javascript">
    var xml;
    var xsl;
    if(typeof window.ActiveXObject != 'undefined') {
        xml 
    = new ActiveXObject("Microsoft.XMLDOM");
        xsl 
    = new ActiveXObject("Microsoft.XMLDOM");
    else if(document.implementation && document.implementation.createDocument) {    //mozilla
        xml = document.implementation.createDocument(""""null);
        xsl 
    = document.implementation.createDocument(""""null);
    }
    // Load XML 

    xml.async 
    = false;
    xml.load(
    "cdcatalog.xml");

    // Load XSL

    xsl.async 
    = false;
    xsl.load(
    "cdcatalog.xsl");

    // Transform

    if(typeof window.ActiveXObject != 'undefined') {
        document.write(xml.transformNode(xsl));
    else if(document.implementation && document.implementation.createDocument) {    //mozilla
        var xsltProcessor = new XSLTProcessor();
        xsltProcessor.importStylesheet(xsl);
        
    // transformToDocument方式
        var result = xsltProcessor.transformToDocument(xml);
        
    var xmls = new XMLSerializer();
        document.write(xmls.serializeToString(result));
    }

    </script>

    </body>
    </html>


    posted @ 2008-05-18 19:02 流浪汗 阅读(787) | 评论 (1)编辑 收藏
         摘要: 自己实现的优先队列 PriorityQueue  阅读全文
    posted @ 2008-05-08 23:08 流浪汗 阅读(1002) | 评论 (0)编辑 收藏
        想到局域网上建一个dns服务器,昨天晚上搞了好久都不成,包括今天也发了好多时间也不能通过.最后找到

    水小筑之Blog

    http://blog.chinaunix.net/u/5302/showart_238337.html
    的博客, 帮了大忙,网上的很多文章都试过了都没有很好的结果.

    我安装的centos是单CD的服务版本.安装后已经有bind了

    1.配置文件在/etc/named.conf
    //
    // named.conf for Red Hat caching-nameserver 
    //

    options {
        directory 
    "/var/named";
        dump
    -file "/var/named/data/cache_dump.db";
            statistics
    -file "/var/named/data/named_stats.txt";
        
    /*
         
    * If there is a firewall between you and nameservers you want
         
    * to talk to, you might need to uncomment the query-source
         
    * directive below.  Previous versions of BIND always asked
         
    * questions using port 53, but BIND 8.1 uses an unprivileged
         
    * port by default.
         
    */
         
    // query-source address * port 53;
    };

    // 
    // a caching only nameserver config
    // 
    controls {
        inet 
    127.0.0.1 allow { localhost; } keys { rndckey; };
    };

    zone 
    "." IN {
        type hint;
        file 
    "named.ca";
    };

    zone 
    "localdomain" IN {
        type master;
        file 
    "localdomain.zone";
        allow
    -update { none; };
    };

    zone 
    "localhost" IN {
        type master;
        file 
    "localhost.zone";
        allow
    -update { none; };
    };

    zone 
    "chenlb.com" IN {
        type master;
        file 
    "chenlb.com.zone";
        allow
    -query { any; };
        allow
    -transfer { any; };
        allow
    -update { none; };
    };

    zone 
    "0.0.127.in-addr.arpa" IN {
        type master;
        file 
    "named.local";
        allow
    -update { none; };
    };

    zone 
    "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" IN {
            type master;
        file 
    "named.ip6.local";
        allow
    -update { none; };
    };

    zone 
    "255.in-addr.arpa" IN {
        type master;
        file 
    "named.broadcast";
        allow
    -update { none; };
    };

    zone 
    "0.in-addr.arpa" IN {
        type master;
        file 
    "named.zero";
        allow
    -update { none; };
    };

    include 
    "/etc/rndc.key";

        只要添加一个zone就行,看上面
    zone "chenlb.com" IN {
        type master;
        file 
    "chenlb.com.zone";
        allow
    -query { any; };
        allow
    -transfer { any; };
        allow
    -update { none; };
    };

    2.在/var/named/chroot/var/named/目录里建个chenlb.com.zone(上面的file),内容如下:
    $TTL    86400
    @       IN      SOA    chenlb.com.  root.chenlb.com.(
                                          
    2008050201 ; Serial
                                          
    28800      ; Refresh
                                          
    14400      ; Retry
                                          
    3600000    ; Expire
                                          
    86400 )    ; Minimum
            IN NS    chenlb.com.
            IN MX 
    10 mail.chenlb.com.
    @       IN A     
    192.168.0.60
    www     IN A     
    192.168.0.60
    ftp     IN A     
    192.168.0.60
    mail    IN A     
    192.168.0.60

    3.在/var/named目录下建链接
    # ch /var/named
    #
     ln -s /var/named/chroot/var/named/chenlb.com.zone chenlb.com.zone

    4.启动named
    # /etc/init.d/named start

    5.测试前添加nds服务地址
    # vi /etc/resolv.conf

    在加
    nameserver 192.168.0.60
    search chenlb.com
    说明:192.168.0.60是我本机地址

    现在本机下可以ping  www.chenlb.com了

    要在加的机上可以使用DNS服务,要在防火墙里允许

    6.修改/etc/sysconfig/iptables添加下面的
    -A RH-Firewall-1-INPUT -p udp -m udp --dport 53 -j ACCEPT
    -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT

        OK,现在在win里添加dns地址192.168.0.60就在ping  www.chenlb.com了. 呵呵


    posted @ 2008-05-02 20:46 流浪汗 阅读(1006) | 评论 (0)编辑 收藏
        昨天安装好了lighttpd,现在想试下与tomcat的一起工作。把所有的*.jsp让tomcat去处理。用到lighttpd的代理,lighttpd与tomcat比apache与tomcat要简单多。开始喜欢上了lighttpd。

    修改lighttpd的配置
    # vi /usr/local/lighttpd-1.4.19/lighttpd.conf

    去掉mod_proxy注释
    server.modules              = (
    #...
    #                               
    "mod_proxy",
    #...
                                  )

    去掉proxy.server注释
    proxy.server               = ( ".jsp" =>
                                   ( 
    "localhost" =>
                                     (
                                       
    "host" ="192.168.0.60",
                                       
    "port" =8080
                                     )
                                   )
                                 )



    重启lighttpd,然后http://192.168.0.60/index.jsp就可以看到tomcat的页面了。
    posted @ 2008-05-02 00:03 流浪汗 阅读(2270) | 评论 (0)编辑 收藏
        近几日都想玩下服务器。此文是在linux下的lighttpd安装php。参考疯狂的鼠标 的博客: http://blog.csdn.net/shined_zhang/archive/2007/10/28/1852349.aspx

    1.安装lighttpd看http://www.blogjava.net/chenlb/archive/2008/04/30/197617.html

    2.安装mysql看http://www.blogjava.net/chenlb/archive/2007/03/20/105114.html

    3.安装php,先到http://www.php.net 下载,我下载的是php-5.2.5
    # tar -zxvf php-5.2.5.tar.gz
    # cd php-
    5.2.5
    #./configure --prefix
    =/usr/local/php-5.2.5 --enable-fastcgi --with-mysql=/usr/local/mysql --enable-zend-multibyte --with-config-file-path=/usr/local/php-5.2.5/conf --enable-discard-path --enable-force-cgi-redirect
    # make
    # make install
    #mkdir /usr/local/php-
    5.2.5/conf
    #cp php.ini-dist /usr/local/php-
    5.2.5/conf/php.ini

        我在安装过程中也出过问题,说我没有找到xml2。要yum install libxml2*一下。

    4.修改lighttpd的配置。  把mod_fastcgi去掉注释。
    # vi /usr/local/lighttpd-1.4.19/lighttpd.conf

    server.modules              = (
    #
    #                               
    "mod_fastcgi",
    #
                                  )

      

        找到fastcgi.server去掉注释,修改后看起来像。
    fastcgi.server             = ( ".php" =>
                                   ( 
    "localhost" =>
                                     (
                                       
    "socket" ="/usr/local/lighttpd-1.4.19/php-fastcgi.socket",
                                       
    "bin-path" ="/usr/local/php-5.2.5/bin/php-cgi"
                                     )
                                   )
                                )


    5.php测试页面phpinfo.php放到你的www目录下。
    <?php
    echo phpinfo();
    ?>


    最后启动或重启lighttpd即可。

    posted @ 2008-05-01 16:48 流浪汗 阅读(1154) | 评论 (0)编辑 收藏
            想搭个服务器,但外面访问不到,是防火墙的原因,把端口设置一下就行。

    1.在/etc/sysconfig/iptables里添加
    -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT

    2.重启iptables
    [root@localhost ~]# /etc/init.d/iptables restart

    3.看下状态
    [root@localhost ~]# /etc/init.d/iptables status
    posted @ 2008-05-01 14:14 流浪汗 阅读(4399) | 评论 (0)编辑 收藏
            在VMware安装一个CentOS的Sever版,终端里的内容不可滚动,不方便。在win下远程登录不错(win下有个Xshell)。默认安装ssh是有的。只是hosts访问问题。

    1.在hosts.deny文件尾添加sshd:ALL
    意思是拒绝所有访问请求
    [root@localhost ~]# vi /etc/hosts.deny

    修改后看起来如下:
    #
    #
     hosts.deny    This file describes the names of the hosts which are
    #
                   *not* allowed to use the local INET services, as decided
    #
                   by the '/usr/sbin/tcpd' server.
    #
    #
     The portmap line is redundant, but it is left to remind you that
    #
     the new secure portmap uses hosts.deny and hosts.allow.  In particular
    #
     you should know that NFS uses portmap!
    sshd:ALL

    2.在hosts.allow文件尾添加sshd:192.168.0.
    意思是允许192.168.0.1 到254的主机,内网。
    [root@localhost ~]# vi /etc/hosts.allow 
    #
    #
     hosts.allow   This file describes the names of the hosts which are
    #
                   allowed to use the local INET services, as decided
    #
                   by the '/usr/sbin/tcpd' server.
    #
    sshd:192.168.0.

    3.重启ssh
    [root@localhost ~]# /etc/rc.d/init.d/sshd restart
    停止 sshd:                                                [  确定  ]
    启动 sshd                                                  [  确定  ]


    好了,用putty和Xshell(Xmanager)可以登录了。^_^

    4.ssh增强配置
    [root@localhost ~]# vi /etc/ssh/sshd_config  ← 用vi打开SSH的配置文件

    #Protocol 2,1 ← 找到此行将行头“#”删除,再将行末的“,1”删除,只允许SSH2方式的连接
     
    Protocol 
    2 ← 修改后变为此状态,仅使用SSH2

    #ServerKeyBits 768 ← 找到这一行,将行首的“#”去掉,并将768改为1024
     
    ServerKeyBits 
    1024 ← 修改后变为此状态,将ServerKey强度改为1024比特

    #PermitRootLogin yes  ← 找到这一行,将行首的“#”去掉,并将yes改为no
     
    PermitRootLogin no  ← 修改后变为此状态,不允许用root进行登录

    #PasswordAuthentication yes ← 找到这一行,将yes改为no
     
    PasswordAuthentication no ← 修改后变为此状态,不允许密码方式的登录

    #PermitEmptyPasswords no  ← 找到此行将行头的“#”删除,不允许空密码登录
     
    PermitEmptyPasswords no  ← 修改后变为此状态,禁止空密码进行登录

    参考: http://www.centospub.com/make/sshd.html
    posted @ 2008-05-01 10:13 流浪汗 阅读(12537) | 评论 (0)编辑 收藏

    想学习在linux下建一个服务平台。
    安装lighttpd

    1.下载安装
    http://www.lighttpd.net/下载,lighttpd-1.4.19.tar.gz

    $ wget http://www.lighttpd.net/download/lighttpd-1.4.19.tar.gz
    $ gzip 
    -cd lighttpd-1.4.19.tar.gz | tar xf -
    $ cd lighttpd
    -1.4.19
    $ .
    /configure --prefix=/usr/local/lighttpd-1.4.19
    $ make
    $ make install


    2.copy conf

    cp doc/lighttpd.conf /usr/local/lighttpd-1.4.19/ 


    3.配置

    lighttpd.conf里server.document-root是服务目录、server.errorlog是错误日志目录,自己更改。

    4.运行

    $ cd /usr/local/lighttpd-1.4.19
    $ sbin
    /lighttpd -f lighttpd.conf


    呵呵,现在可以运行了。

    posted @ 2008-04-30 23:23 流浪汗 阅读(1327) | 评论 (2)编辑 收藏
    转载: http://www.bullog.cn/blogs/cathayan/archives/33231.aspx

    在Linux下面全面用UTF-8后就曾发现过中文排序有点不理解了,昨天才看到别人讨论,原来Unicode里面的汉字顺序居然是《康熙字典》的偏旁部首顺序。查了一下,康熙字典中的部首共有214个:

    一丨丶丿乙亅二亠人儿入八冂冖冫几凵刀力勹匕匚匸十卜卩厂厶又口囗土士夂夊夕大女子宀寸小尢尸屮山巛工己巾干幺广廴廾弋弓彐彡彳心戈戶手支攴文斗斤方无日曰月木欠止歹殳毋比毛氏气水火爪父爻爿片牙牛犬玄玉瓜瓦甘生用田疋疒癶白皮皿目矛矢石示禸禾穴立竹米糸缶网羊羽老而耒耳聿肉臣自至臼舌舛舟艮色艸虍虫血行衣襾見角言谷豆豕豸貝赤走足身車辛辰辵邑酉釆里金長門阜隶隹雨靑非面革韋韭音頁風飛食首香馬骨高髟鬥鬯鬲鬼魚鳥鹵鹿麥麻黃黍黑黹黽鼎鼓鼠鼻齊齒龍龜龠

    像在Google Docs里面,如果对Spreadsheet表格排序,中文就依据上面的部首顺序进行,部首在前的字就排在前面,如果部首相同,则算笔划数,笔划数相同的就不知道怎么排了。比如有这样的结果:

    刘孙康张李王赵钱齊

    它们的部首分别是:刀子广弓木王走金齊。

    又有:刈刘则刹剂剔,文和贝同为4划,杀和齐同为6划,而点在竖前,撇在横前,按传统应该是“江山千古”(丶丨丿一乛)的顺序。另外还有“寒来暑往”(丶一丨丿乛),“天上人间”(一丨丿丶乛),札字(一丨丿丶乛)法,礼(丶一丨丿乛)字法等。

    这样用Unicode的话,就是不加任何处理,排序出来的汉字也是很有道理的。但如果想排出拼音顺序就还得再想办法。

    查Unicode和康熙的时候,还查到了这个海峰五笔超大字符集输入法,一个用于Win系统的五笔输入法,有86和98标准,最厉害的是:收录UNICODE超大字集全部七万多中日韩汉字,同时他们还提供一个exe来安装这个字体

    CJK基本 [4E00-9FFF] 20992码位 实际20924字

    CJK扩展A [3400-4DBF] 6592码位 实际6582字

    CJK扩展B [20000-2A6DF] 42720码位 实际42711字

    CJK扩展C [2A700-2BA7F] 4224码位 实际4219字

    CJK兼容扩展 [2F800-2FA1F] 544码位 实际542字

    CJK部首扩展 [2E80-2EFF] 128码位 实际116字

    CJK康熙部首 [2F00-2FDF] 224码位 实际214字

    CJK笔画 [31C0-31EF] 48码位 实际36字

    CJK兼容 [F900-FAFF] 512个码位 实际474字
    posted @ 2008-04-21 17:23 流浪汗 阅读(1376) | 评论 (0)编辑 收藏


    log4j.properties文件

    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout
    =org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern
    =%-4r %d %-5p %l - %m%n
    log4j.logger.net.blogjava.chenlb
    =DEBUG
    log4j.rootLogger
    =INFO, stdout

    解释下pattern

    r 开始到日志的毫秒数
    d 日志的时间
    p 日志级别
    l 包括类全名.方法还有在第几行,这样在eclipse的Console里点可以直接转到源码
    m 日志的内容
    n 换行
    c 类全名
    M 日志所在的方法名
    L 日志所在的行号
    t 可能是线程启动的方法名
    F 文件名,包括后缀
    posted @ 2008-04-11 12:01 流浪汗 阅读(557) | 评论 (0)编辑 收藏
    jdk14的logging还有点麻烦,要覆盖jre/lib/logging.properties的配置,还要在启动时加-Djava.util.logging.config.file=mylogging.properties





    java 1.4
    日志纪录在java.util.logging.Level类中定义了下列日志级别常数
    Ø          SERVER表示一个严重失败。常常将有一个伴随的Throwable
    Ø          CONFIG为应用配置期间所生成的消息而设计的。
    Ø          INFO中等优先级。表示一个构件正在做什么(例如,监视一项任务的  运行进度),但不是用来帮助调试该构件。
    Ø          FINE跟踪信息。该级别和较低优先级的级别应该用来帮助调试某些类,但不应该用来总体的说明该应用的工作方式。
    Ø          FINER详细的跟踪信息。
    Ø          FINEST非常详细的跟踪信息。
    Log4jorg.apache.log4j.Level类中定义了下列日志级别常数
    Ø          FATAL表示一个严重失败。导致application的中断。
    Ø          ERROR表示一个错误事件。可以允许Application可以继续运行。
    Ø          WARN表示一个有潜在的危险。
    Ø          INFO表示一个构件正在做重要运行情况,信息比较粗糙。
    Ø          DEBUG表示一个构件详细的运行情况,用于调试Application
    Ø          ALL表示纪录所有级别的日志信息。
    Common-logging的日志级别分为6种,从低到高分别为tracedebuginfowarnerrorfatal
    Ø          FATAL表示一个严重失败。导致application的中断。
    Ø          ERROR表示一个错误事件。可以允许Application可以继续运行。
    Ø          WARN表示一个有潜在的危险。
    Ø          INFO表示一个构件正在做重要运行情况,信息比较粗糙。
    Ø          DEBUG表示一个构件详细的运行情况,用于调试Application
    Ø          TRACE非常详细的跟踪信息,仅仅用于纪录该日志而已。






    posted @ 2008-04-11 11:50 流浪汗 阅读(1065) | 评论 (0)编辑 收藏
        用ajax去请求solr服务。返回json,然后解释。让solr返回json的参数是wt=json。然后javascript用evel()解释成对象。
    我的solr会返回:auother,title,introduce这几个域。先创建一个jsp或html,如:json.jsp

    1.json.jsp关键的html内容
      <form action="select/" name="f1" method="get" onsubmit="xmlhttpPost('/solr/select'); return false;" >
          Chenlb: 
          
    <input type="text" name="q" size="80" value="文档">
          
    <input name="start" type="hidden" value="0">
        
    <input name="rows" type="hidden" value="10">
        
    <input name="indent" type="hidden" value="on">
        
    <input name="wt" type="hidden" value="">
          
    <input type="button" value=" 搜 索 " onclick="xmlhttpPost('/solr/select');">
          
    <input type="button" value=" get json " onclick="document.forms['f1'].wt.value='json';document.forms['f1'].submit();">
          
    <input type="button" value=" get xml " onclick="document.forms['f1'].wt.value='';document.forms['f1'].submit();">
      
    </form>
      
    <div style="background-color: #ccccff; height: 15px;"></div>
      
    <p>
        
    <div id="header"></div>
        
    <div id="response"></div>
        
    <table id="docs" class="tab" cellspacing="1">
            
    <tr height="25" style="background-color: #cccccc; color: #0000ff;">
                
    <td>作者</td>
                
    <td>简介</td>
                
    <td>标题</td>
                
    <td>score</td>
            
    </tr>
        
    </table>

    2.javascript部分
    function xmlhttpPost(strURL) {
        
    var xmlHttpReq = false;
        
    var self = this;
        
    if (window.XMLHttpRequest) { // Mozilla/Safari
            self.xmlHttpReq = new XMLHttpRequest(); 
        }
        
    else if (window.ActiveXObject) { // IE
            self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
        }
        
        
    var params = getstandardargs().concat(getquerystring());
        
    var strData = params.join('&');
        
        
    var header = document.getElementById("response");
        header.innerHTML 
    = strURL+'?'+strData;

        self.xmlHttpReq.open('get', strURL
    +'?'+strData+'&time='+new Date().getTime(), true);
        self.xmlHttpReq.setRequestHeader('Content
    -Type', 'application/x-www-form-urlencoded');
        self.xmlHttpReq.onreadystatechange 
    = function() {
            
    if (self.xmlHttpReq.readyState == 4) {
                updatepage(self.xmlHttpReq.responseText);
            }
        }
        self.xmlHttpReq.send(
    null);
    }

    function getstandardargs() {
        
    var params = [
            'wt
    =json'
            , 'indent
    =on'
            , 'hl
    =true'
            , 'hl.fl
    ='
            , 'fl
    =*,score'
            , 'start
    =0'
            , 'rows
    =10'
            ];

        
    return params;
    }
    function getquerystring() {
      
    var form = document.forms['f1'];
      
    var query = form.q.value;
      qstr 
    = 'q=+ encodeURI(query);    //escape
      return qstr;
    }

    // this function does all the work of parsing the solr response and updating the page.
    function updatepage(str){
      
    //document.getElementById("response").innerHTML = str;
      var rsp = eval("("+str+")"); // use eval to parse Solr's JSON response
      parse(rsp);
    }

    function parse(j) {
        
    var header = document.getElementById("header");
        
    var rh = j.responseHeader;
        
    var header_str = " 搜索: \""+rh.params.q+"\", 花了: "+rh.QTime+"ms, 共显示: "+j.response.numFound+"条记录, 总共有: "+rh.params.rows;
        header.innerHTML 
    = header_str;
        
    var docs = j.response.docs;
        
    var tab = document.getElementById("docs");
        
    for(; tab.rows.length >1; ) {
            tab.deleteRow(
    -1);
        }
        
    var tr;
        
    var td;
        
    for(var i=0; i<docs.length; i++) {
            tr 
    = tab.insertRow(-1);
            td 
    = tr.insertCell(-1);
            td.innerHTML 
    = docs[i].author;
            
            td 
    = tr.insertCell(-1);
            td.innerHTML 
    = docs[i].introduce;
            
            td 
    = tr.insertCell(-1);
            td.innerHTML 
    = docs[i].title;
            
            td 
    = tr.insertCell(-1);
            td.innerHTML 
    = docs[i].score;
        }
       }

    3.现在可以搜索了。
    http://localhost:8080/solr/json.jsp

    solr怎么部署到Tomcat里请看:http://www.blogjava.net/chenlb/archive/2008/03/25/188459.html

    posted @ 2008-03-28 17:33 流浪汗 阅读(2072) | 评论 (0)编辑 收藏
        在Tomcat下部署solr自带的例子

    下载:
    apache-solr-1.2.0.zip http://apache.mirror.phpchina.com/lucene/solr/1.2/apache-solr-1.2.0.zip
    apache-tomcat-5.5.26.zip  http://apache.mirror.phpchina.com/tomcat/tomcat-5/v5.5.26/bin/apache-tomcat-5.5.26.zip

    1.solr解压到E:\solr。tomcat解压到e:\tomcat。

    2.把E:\solr\dist\apache-solr-1.2.0.war放到E:\tomcat\webapps目录下改名为solr.war。

    3.把E:\solr\example目录中的solr文件夹复制到E:\tomcat\目录下。

    4.在E:\tomcat\conf\Catalina\localhost目录下创建一个solr.xml文件,内容如下:
    <?xml version="1.0" encoding="UTF-8"?>

    <Context docBase="" debug="0" crossContext="true" >
       
    <Environment name="solr/home" type="java.lang.String" value="e:/tomcat/solr" override="true" />
    </Context>

    5.启动Tomcat。可以打开http://localhost:8080/solr/admin

    也可以不用JNDI方式。第3步把它复制到E:\tomcat\bin目录下,就不用第4步了。

    我部署时困了很久,启动Tomcat后
    org.apache.catalina.core.StandardContext start
    严重: Error filterStart
    org.apache.catalina.core.StandardContext start
    严重: Context 
    [/solr] startup failed due to previous errors

    老是怀疑solr/home配置错了。但启动日志又有Loaded SolrConfig: solrconfig.xml。又换了solr版本,又换tomcat版本。还是出现上面的错误。只是郁闷。后来怀疑jdk了。JAVA_HOME改前几天我安装的,然后一片惊喜,可以启动了。那JDK是机子本来就有的,怀疑就没有安装好,或版本太低了是:(build 1.5.0-b64),我安装的是 (build 1.5.0_15-b04)。

    终于解决,就写下来。高兴ing... 吃饭。
    posted @ 2008-03-25 12:40 流浪汗 阅读(4121) | 评论 (0)编辑 收藏
        cygwin 使用心得 转载 鱼漂 (一直漂)  http://www.eit.name/blog/read.php?171

    1.在cygwin里访问Windows盘
    cd /cygdrive/c
    cd c:

    2.整合cygwin命令到Windows中
    假设cygwin安装在d:/develop/cygwin,则将d:/develop/cygwin/bin添加到系统变量PATH中(最好加在windows前面,这样的话,有些相同的命令的话,是先执行cygwin的命令,而不是windows命令,比如find)

    就可以直接在cmd.exe下面执行tar czvf xxx.tgz ./
    基本上所有的命令都可以用了,包括ls,more,less,find,grep等。

    3.使用TGZ备份
    将cygwin的BIN加入到PATH
    建一个BAT文件:
    @echo off
    d:
    cd d:\website\8thmanage
    tar czvf 8thmanage.tgz 8thmanage

    4.Windows使用SHELL脚本
    将cygwin的BIN加入到PATH
    在$CYGWIN的目录/var/下面建一脚本t.sh,注意,t.sh里面的路径,都是相对于$CYGWIN的,里面需要访问C盘的,请用/cygdrive/c/
    在Windows下执行:
    d:\cygwin\bin\bash d:\cygwin\var\t.sh
    (可以定期执行)

    5.同步Windows系统用户
    mkpasswd -l > /etc/passwd
    mkgroup -l > /etc/group
    如果有Domain的话,需要加上-d domainname

    6.安装系统服务
    cygrunsrv

    7.cygwing下使用rsync
    a.安装rsync组件
    b.进入cygwin,配置服务器
    vi /etc/rsyncd.conf

    ...screts file=/etc/tom.ipaddr.pas

    配置文件,参考我写的另外一篇rsync的文章,注意:密码文件权限必须是0400
    chmod 0400 /etc/tom.ipaddr.pas
    c.启动服务端
    rsync --daemon

    d.客户端同步
    在客户端的cygwin下面,运行rsync同步,具体命令,请参考另外一篇rsync的文章。

    8.cygwin下使用SSHD
    a.需要安装了cygrunsrc,openssh
    b.运行ssh-host-config -y
    一路回车,直到出现CYGWIN=时,输入tty ntsec,再回车,
    (或者,增加一系统环境变量CUGWIN=nesec tty)
    c.已经安装好SSHD服务到你的Windows服务中,可以直接在服务中启动,关闭。
    (cygrunsrc -S sshd或者net start sshd)

    9.中文显示
    vi ~/.bashrc
    # 让ls和dir命令显示中文和颜色
    alias ls='ls --show-control-chars --color'
    alias dir='dir -N --color'
    # 设置为中文环境,使提示成为中文
    export LANG="zh_CN.GBK"
    # 输出为中文编码
    export OUTPUT_CHARSET="GBK"

    ~/.inputrc为
    set completion-ignore-case on
    set meta-flag on
    set output-meta on
    set convert-meta off

    cygwin.bat脚本为:
    @echo off
    set MAKE_MODE=UNIX
    posted @ 2008-03-19 09:12 流浪汗 阅读(3023) | 评论 (0)编辑 收藏
        用URLEncoder转换。

    String filename = URLEncoder.encode("中文.zip""UTF-8");      
    response.addHeader(
    "Content-Disposition","attachment;filename="+filename); 
    posted @ 2008-03-16 14:29 流浪汗 阅读(375) | 评论 (0)编辑 收藏
            加style="cursor:hand" ,firefox无效。
    posted @ 2008-03-16 12:56 流浪汗 阅读(4141) | 评论 (2)编辑 收藏
         收集于网络,自已小改动下。
    有DrawImage(ImgD, width, height) 调整图像比例的javascript函数。

    <script language="javascript">
    <!--

    var flag=false;
    function DrawImage(ImgD, width, height){
    var image=new Image();
    var iwidth = width;
    var iheight = height;
    image.src
    =ImgD.src;
    if(image.width>0 && image.height>0){
    flag
    =true;
    if(image.width/image.height>= iwidth/iheight){
    if(image.width>iwidth){
    ImgD.width
    =iwidth;
    ImgD.height
    =(image.height*iwidth)/image.width;
    }
    else{
    ImgD.width
    =image.width;
    ImgD.height
    =image.height;
    }
    ImgD.alt
    =image.width+""+image.height;
    }
    else{
    if(image.height>iheight){
    ImgD.height
    =iheight;
    ImgD.width
    =(image.width*iheight)/image.height;
    }
    else{
    ImgD.width
    =image.width;
    ImgD.height
    =image.height;
    }
    ImgD.alt
    =image.width+""+image.height;
    }
    }
    }
    //-->
    </script>
    <style type="text/css">
    .pic_size 
    {border:1px solid #CCCCCC;width:240px;height:200px;margin-top:5px;background:#FFF;}
    </style>
    <div class="pic_size"><table width="100%" height="100%"><tr><td style="text-align: center;vertical-align: middle;"><img src="my.jpg" onload = "DrawImage(this,240,200)"></td></tr></table></div>
    posted @ 2008-03-16 12:43 流浪汗 阅读(363) | 评论 (0)编辑 收藏
        在HTML内头部加以下内容。

    <link rel="shortcut icon" href="/images/my.ico" type="image/x-icon" />
    posted @ 2008-03-16 12:32 流浪汗 阅读(325) | 评论 (0)编辑 收藏
        以前想用循环来System.in (或是其它输入方式老是达不预想的效果,第一次输入后回车,不会接收下一次用户的输入)。后来才发现readline() != null才能达到效果。

    package net.blogjava.chenlb;

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;

    /**
     * 重复接收用户输入一行命令
     * 
    @author chenlb 2008-3-11 下午09:24:50
     
    */
    public class UserInput {

        
        
    public static void main(String[] args) throws IOException {
            System.out.println(
    "说明: 输入QUIT退出");
            System.out.print(
    "\ninput>");
            String inputStr 
    = null;
            BufferedReader br 
    = new BufferedReader(new InputStreamReader(System.in));
            
    while((inputStr = br.readLine()) != null) {
                
    if(inputStr.equals("QUIT")) {
                    System.exit(
    0);
                }
                System.out.println(
    "你输入的是: "+inputStr);    //处理你的逻辑
                System.out.print("\ninput>");
            }

        }

    }
    posted @ 2008-03-11 21:49 流浪汗 阅读(968) | 评论 (0)编辑 收藏
         最近看下Lucene的东西,把它写下来可以看下。Lucene结构和工作原理我就不说了,网上好多。

    我的环境是Lucene2.0
    写一个简单使用Lucene的示例。此类首创建索引,然后显示索引文档的情况,最后搜索(只在content找,和在title或content里找)。

    package net.blogjava.chenlb.lucene;

    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.document.Field;
    import org.apache.lucene.index.IndexReader;
    import org.apache.lucene.index.IndexWriter;
    import org.apache.lucene.queryParser.MultiFieldQueryParser;
    import org.apache.lucene.queryParser.QueryParser;
    import org.apache.lucene.search.BooleanClause;
    import org.apache.lucene.search.Hits;
    import org.apache.lucene.search.IndexSearcher;
    import org.apache.lucene.search.Query;

    /**
     * Lucene简单使用
     * 
    @author chenlb 2008-3-8 下午11:42:55
     
    */
    public class LuceneUse {

        
    public static void main(String[] args) throws Exception {
            LuceneUse liu 
    = new LuceneUse();
            
    //索引
            IndexWriter iw = new IndexWriter("index"new StandardAnalyzer(), true);
            
    //添加要索引的Lucene文档
            Document doc = liu.createDoc("Lucene创建索引示例""chenlb""2008-03-08""Lucene索引的内容在这里,这些内容不被存储.");
            iw.addDocument(doc);
            
            doc 
    = liu.createDoc("文档2""bin""2007-10-03""这是索引的另一个文档");
            iw.addDocument(doc);
            
            doc 
    = liu.createDoc("学习内容""chenlb""2008-3-3""要努力奋斗,祝网友们天天快乐");
            iw.addDocument(doc);
            
            iw.optimize();    
    //优化
            iw.close();
            
            
    //
            System.out.println("===========索引文档内容=============");
            IndexReader reader 
    = IndexReader.open("index");
            
    for(int i=0; i<reader.numDocs(); i++) {
                Document d 
    = reader.document(i);
                liu.printDoc(d);
            }
            
            System.out.println(
    "===========以下是单域查找'天天'结果============");
            
    //单域搜索
            IndexSearcher searcher = new IndexSearcher("index");
            QueryParser parser 
    = new QueryParser("content"new StandardAnalyzer());
            Query q 
    = parser.parse("天天"); 
            
            
    long start = System.currentTimeMillis();
            Hits hits 
    = searcher.search(q);
            
    long end = System.currentTimeMillis();
            
    for(int i=0; i<hits.length(); i++) {
                liu.printDoc(hits.doc(i));
            }
            System.out.println(
    "共找到: "+hits.length()+" 个文档,花了:"+(end-start)+"ms");
            
            
    //多域搜索
            System.out.println("===========以下多域是查找'内容'结果============");
            
    //从title或content找
            q = MultiFieldQueryParser.parse("内容"new String[] {"title""content"}, new BooleanClause.Occur[] {BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD}, new StandardAnalyzer());
            start 
    = System.currentTimeMillis();
            hits 
    = searcher.search(q);
            end 
    = System.currentTimeMillis();
            
    for(int i=0; i<hits.length(); i++) {
                liu.printDoc(hits.doc(i));
            }
            System.out.println(
    "共找到: "+hits.length()+" 个文档,花了:"+(end-start)+"ms");
        }
        
        
    /**
         * 显示文档内容
         
    */
        
    private void printDoc(Document d) {
            System.out.println(
    "标题: "+d.get("title")+", 作者: "+d.get("author")+", 日期: "+d.get("date")+", 内容: "+d.get("content"));
        }
        
        
    /**
         * 创建一个Lucene文档
         
    */
        
    private Document createDoc(String title, String author, String date, String content) {
            Document doc 
    = new Document();
            doc.add(
    new Field("title", title, Field.Store.YES, Field.Index.TOKENIZED));
            doc.add(
    new Field("author", author, Field.Store.YES, Field.Index.NO));
            doc.add(
    new Field("date", date, Field.Store.YES, Field.Index.NO));
            doc.add(
    new Field("content", content, Field.Store.YES, Field.Index.TOKENIZED));
            
    return doc;
        }
    }
    posted @ 2008-03-09 00:47 流浪汗 阅读(964) | 评论 (0)编辑 收藏
        这几天想用Java读富文档。用javax.swing.text和javax.swing.text.rtf包中的类读RTF文档时出现中文乱码问题(出现?号)。
        幸好找到 ANGEL SKY 的博客。用ISO8859_1编码转换。

    代码片断:
    String bodyText = null;
            DefaultStyledDocument styledDoc 
    = new DefaultStyledDocument();    //javax.swing.text.Document的一个实例
            try {
                InputStream is 
    = new FileInputStream(new File("data/java.swing.text读RTF文档测试.rtf"));
                
    new RTFEditorKit().read(is, styledDoc, 0);
                bodyText 
    = new String(styledDoc.getText(0, styledDoc.getLength()).getBytes("ISO8859_1"));    //提取文本
            } catch (IOException e) {
                
    throw new DocumentHandlerException("不能从RTF中摘录文本!", e);
            } 
    catch (BadLocationException e) {
                
    throw new DocumentHandlerException("不能从RTF中摘录文本!", e);
            }
            System.out.println(bodyText);
    posted @ 2008-02-01 17:05 流浪汗 阅读(2270) | 评论 (0)编辑 收藏
        这学期,应聘的时候有一些是线程相关的,虽然自己对线程编程有点概念,但没有写过经典的例子。放假了有点时候,就想写多线程的例子。

        笔试的题目类似地:一个生产者一次生产10个,满了后通知消费者,然后等待。一个消费者产品有满了就消费。到空时通知生产者,然后等待。

        那时对等待/通知机制没怎么写过,那次笔试应该写的大概对(想法对),但写的wait()和notifyAll()的位置不对。现在有时间就写了这个例子。
        描述:生产者一次生产N个产品,池中达到M就等待,通知等待的消费者。消费者有产品就消费,到没有时就通知生产者,然后等待。

    1.生产者:
    package net.blogjava.chenlb.multithreaded;

    import java.util.List;

    /**
     * 
    @author chenlb
     * 
     * 生产者.<br/>
     * 默认产品池大小M=20,产品梯阶大小N=5.在生产过程中,池的大小会超过20,但池中最大应该是M+N-1.
     
    */
    public class Producer implements Runnable {

        
    /**
         * 池默认大小
         
    */
        
    public static final int DEFALUT_SIZE = 20;
        
    /**
         * 默认一次生产的数量
         
    */
        
    public static final int DEFALUT_STEP_SIZE = 5;
        
        
    private static int PRODUCER_ID = 0;    //生产者号
        
        
    private List<Product> pool = null;
        
    private int size = DEFALUT_SIZE;
        
    private int stepSize = DEFALUT_STEP_SIZE;
        
        
    private String name = "Producer_"+(++PRODUCER_ID);    //生产者名
        
        
    private boolean isRun = true;
        
        
    /**
         * 默认产品池大小20, 默认产品增长梯阶大小5
         
    */
        
    public Producer(List<Product> pool) {
            
    this.pool = pool;
        }

        
    /**
         * 
    @param pool
         * 
    @param size 池大小
         
    */
        
    public Producer(List<Product> pool, int size) {
            
    this.pool = pool;
            
    this.size = size;
        }
        
        
        
    /**
         * 
    @param pool
         * 
    @param size 池大小
         * 
    @param stepSize 一次生产多少
         
    */
        
    public Producer(List<Product> pool, int size, int stepSize) {
            
    this.pool = pool;
            
    this.size = size;
            
    this.stepSize = stepSize;
        }

        
    public void run() {
            
    // TODO 生产者线程
            
    //int pi = 0;
            while(isRun) {//&& pi<10
                
    //pi++;
                synchronized (pool) {    //同步产品池
                    if(pool.size() >= size) {
                        
    try {
                            System.out.println(name
    +" 等待!");
                            pool.wait();    
    //同步什么就等待什么,否则抛出java.lang.IllegalMonitorStateException
                        } catch (InterruptedException e) {
                            isRun 
    = false;
                            System.out.println(name
    +" thread interrupt!");                    
                        }
                    } 
    else {
                        
                        
    for(int i=0; i<stepSize; i++) {    //一次生产stepSize个产品
                            pool.add(product());    //生产产品
                        }
                        System.out.println(
    "产品池中有: "+pool.size());
                        pool.notifyAll();    
    //通知等待的线程(主要用来通知消费者, 但生产者线程也会通知到)
                    }
                }
                
                
    try {
                    System.out.println(name
    +" 休息1秒!");
                    Thread.sleep(
    1000);    //调试用
                } catch (InterruptedException e) {
                    System.out.println(name
    +" sleep 1s thread interrupt");
                }
            }
            System.out.println(name
    +" end! pool size: "+pool.size());
        }

        
    private static int P_ID = 0;
        
    /**
         * 生产产品
         * 
    @return 产品
         
    */
        
    private Product product() {
            String name 
    = "product_"+(++P_ID);
            System.out.println(
    this.name+" 生产了: "+name);
            
    return new Production(name);
        }
        
    }


    2.消费者:

    package net.blogjava.chenlb.multithreaded;

    import java.util.List;

    /**
     * 
    @author chenlb
     * 
     * 消费者
     
    */
    public class Consumer implements Runnable {

        
    private static int C_ID = 0;    //消费者ID
        
        
    private List<Product> pool = null;
        
    private String name = "Consumer_"+(++C_ID);
        
    private boolean isRun = true;
        
    public Consumer(List<Product> pool) {
            
    this.pool = pool;
        }
        
        
    public void run() {
            
    // TODO 消费者线程
            
    //int pi = 0;
            while(isRun) {//&& pi<10
                
    //pi++;
                synchronized (pool) {
                    
    if(pool.size() < 1) {
                        
    try {
                            System.out.println(name
    +" 等待!");
                            pool.notifyAll();    
    //通知线程(主要是生产者,但也会通知到生产者线程)
                            pool.wait();
                        } 
    catch (InterruptedException e) {
                            isRun 
    = false;
                            System.out.println(name
    +" thread interrupt!");
                        }
                    } 
    else {
                        Product p 
    = pool.remove(0);    //消费
                        printProduct(p);
                        
                    }
                }
                
    try {
                    Thread.sleep(
    1000);    //调试用
                } catch (InterruptedException e) {
                    
                    System.out.println(name
    +" sleep 1s thread interrupt");
                }
            }
            System.out.println(name
    +" end! pool size: "+pool.size());
        }

        
    private void printProduct(Product p) {
            System.out.println(name
    +" 消费了: "+p.getName());
        }
    }


    3.Demo
    package net.blogjava.chenlb.multithreaded;

    import java.util.LinkedList;
    import java.util.List;

    /**
     * 
    @author chenlb
     *
     
    */
    public class Sale {

        
        
    public static void main(String[] args) {
            
    //链表产品池
            List<Product> pool = new LinkedList<Product>();
            
    //两个生产者
            Producer p1 = new Producer(pool);
            Producer p2 
    = new Producer(pool);
            
            Thread tp1 
    = new Thread(p1);
            Thread tp2 
    = new Thread(p2);
            
            tp1.start();
            tp2.start();
            
            
    //两个消费者
            Consumer c1 = new Consumer(pool);
            Consumer c2 
    = new Consumer(pool);
            
            Thread tc1 
    = new Thread(c1);
            Thread tc2 
    = new Thread(c2);
            
            tc1.start();
            tc2.start();
            
            

        }

    }

    注意:等待时候要用pool.wait()因为同步的是pool。否则会抛出java.lang.IllegalMonitorStateException

    ^_^

    代码下载
    posted @ 2008-01-24 11:36 流浪汗 阅读(532) | 评论 (0)编辑 收藏


    1.聚合关系也称"has-a"关系,组合关系也称"contains-a"关系

    2.聚合关系表示事物的整体/部分关系的较弱情况,组合关系表示事物的整体/部分关系的较强的情况.

    3.在聚合关系中,代表部分事物的可以属于多个聚合对象,可以为多个聚合对象共享,而且可以随时改变它所从属的聚合对象.代表部分事物的对象与代表聚合事物对象的生存期无关,一旦删除了它的一个聚合对象,不一定也就随即删除代表部分事物的对象.在组合关系中,代表整体事物的对象负责创建和删除代表部分事物的对象,代表部分事物只属于一个组合对象.一旦删除了组合对象,也就随即删除了相应的代表部分事物的对象.
    posted @ 2008-01-15 22:02 流浪汗 阅读(2637) | 评论 (0)编辑 收藏
          oracle 用户SYS 和 SYSTEM的默认口令:TIGER
    posted @ 2008-01-03 15:10 流浪汗 阅读(1491) | 评论 (0)编辑 收藏
    .什么是pv
      PV(page view),即页面浏览量,或点击量;通常是衡量一个网络新闻频道或网站甚至一条网络新闻的主要指标。

      高手对pv的解释是,一个访问者在24小时(0点到24点)内到底看了你网站几个页面。这里需要强调:同一个人浏览你网站同一个页面,不重复计算pv量,点100次也算1次。说白了,pv就是一个访问者打开了你的几个页面。

      PV之于网站,就像收视率之于电视,从某种程度上已成为投资者衡量商业网站表现的最重要尺度。

      pv的计算:当一个访问着访问的时候,记录他所访问的页面和对应的IP,然后确定这个IP今天访问了这个页面没有。如果你的网站到了23点,单纯IP有60万条的话,每个访问者平均访问了3个页面,那么pv表的记录就要有180万条。

        有一个可以随时查看PV流量以及你的网站世界排名的工具alexa工具条,安装吧!网编们一定要安装这个。

      .什么是uv
    uv(unique visitor),指访问某个站点或点击某条新闻的不同IP地址的人数。

      在同一天内,uv只记录第一次进入网站的具有独立IP的访问者,在同一天内再次访问该网站则不计数。独立IP访问者提供了一定时间内不同观众数量的统计指标,而没有反应出网站的全面活动。

      .什么是PR值
    PR值,即PageRank,网页的级别技术。取自Google的创始人Larry Page,它是Google排名运算法则(排名公式)的一部分,用来标识网页的等级/重要性。级别从1到10级,10级为满分。PR值越高说明该网页越受欢迎(越重要)。

      例如:一个PR值为1的网站表明这个网站不太具有流行度,而PR值为7到10则表明这个网站非常受欢迎(或者说极其重要)。

      我们可以这样说:一个网站的外部链接数越多其PR值就越高;外部链接站点的级别越高(假如Macromedia的网站链到你的网站上),网站的PR值就越高。例如:如果ABC.COM网站上有一个XYZ.COM网站的链接,那为ABC.COM网站必须提供一些较好的网站内容,从而Google会把来自XYZ.COM的链接作为它对ABC.COM网站投的一票。

      你可以下载和安装Google工具条来检查你的网站级别(PR值)。  


    详细看: http://www.skynuo.com/faq_qc7.htm

    posted @ 2007-12-31 13:51 流浪汗 阅读(365) | 评论 (0)编辑 收藏

    RIA(Rich Internet Application,富互联网应用系统)技术允许我们在因特网上以一种象使用Web一样简单的方式来部署富客户端程序。这是一个用户接口,它比用HTML能实现的接口更加健壮、反应更加灵敏和更具有令人感兴趣的可视化特性。无论将来RIA是否能够如人们所猜测的那样完全代替HTML应用系统,对于那些采用胖客户端技术运行复杂应用系统的机构来说,RIA确实提供了一种廉价的选择。

    RIA的产生背景

      基于HTML的应用程序之所以变得流行是由于应用系统的部署成本低、结构简单,且HTML易于学习和使用。很多用户和开发人员都乐于放弃由桌面计算机带来的用户界面改进,来实现对新数据和应用系统的快速访问。与丧失一些重要的UI功能相比,基于Web的方式所带来的好处要更大得多。

      然而,某些应用系统并不完全适合采用HTML技术。复杂的应用系统可能要求多次提取网页来完成一项事务处理,在某些领域中,如医药和财务领域,这往往导致交互速度低得无法接受。让我考虑一个项目管理系统:我们可以将其实现为一个HTML应用系统,但是如果用户可以看到并且操作图表、进度表和各种层次结构,那么显然会工作得更好。

      此外,虽然HTML开始走向简单,但是即使简单的交互活动也仍然需要用很多的脚本来完成。即使一个输入窗体经过仔细的布置和全面的脚本设计它从浏览器所能发送的也仅仅是简单的"名字/值"对。如果一个HTML窗体能够以XML文档形式发送和接收更复杂的数据结构,那就好多了。

      RIA利用相对健壮的客户端描述引擎,这个引擎能够提供内容密集、响应速度快和图形丰富的用户界面。除了提供一个具有各种控件(滑标、日期选择器、窗口、选项卡、微调控制器和标尺等)的界面之外,RIA一般还允许使用SVG(Scalable Vector Graphics,可伸缩向量图)或其他技术来随时构建图形。一些RIA技术甚至能够提供全活动的动画来对数据变化作出响应。

      RIA的另一个好处在于,数据能够被缓存在客户端,从而可以实现一个比基于HTML的响应速度更快且数据往返于服务器的次数更少的用户界面。对于无线设备和需要偶尔连接的设备来说,将来的趋势肯定是向富客户端的方向发展,并且会逐渐远离基于文本的Web客户端。那些运行在膝上设备上的应用系统,可以被设计成以离线方式工作,或者至少当连接丢失的时候能基本上以离线的方式工作。



    看详细的介绍(来源):http://develop.csai.cn/web/200610261348351031.htm
    posted @ 2007-12-30 14:05 流浪汗 阅读(279) | 评论 (0)编辑 收藏
            CEO(Chief executive officer)首席执行官 类似总经理、总裁,是企业的法人代表。

      COO(Chief operating officer)首席运营官 类似常务总经理

      CFO(Chief financial officer)首席财务官 类似财务总经理

      CTO(Chief technology officer)首席技术官 类似总工程师

      CIO(Chief information officer)首席信息官 主管企业信息的收集和发布

    http://edu.yesky.com/344/3049844.shtml

    posted @ 2007-12-26 11:21 流浪汗 阅读(325) | 评论 (0)编辑 收藏
          这学期的项目中,用hibernate和oracle。表结构我们不能改,这样的遗留系统用hibernate有点麻烦。汗!别人把可变长的字符类型设计为CHAR,郁闷死。这样所有?形式的sql语句基本上无效(不是恰好这么长就找不到数据),这是oracle的JDBC限定了(mysql的JDBC不会)。然后就想到在=号左边用TRIM可以解决PrepareStatement找不到数据的问题。

         麻烦来了。同学用100W行数据来测试。发现比较卡。然后追踪hibernate的SQL日志发现有trim的语句就慢。然后把此SQL语句在PL/SQL客户端试下,发现在26秒才能找到结果。汗!这么严重!去了TRIM不到1秒的事情。

         字段类型的设计不好,就这样...

    可以看下 oracle jdbc char 字段 PreparedStatement 查询问题
    posted @ 2007-12-26 10:42 流浪汗 阅读(1201) | 评论 (0)编辑 收藏
          项目中有applet,现在想只编译applet包下面的内容。

    部分代码:
        <target name="compile.applet" depends="compile.java">
            
    <mkdir dir="${deploy.applet.dir}" />
            
    <javac destdir="${deploy.applet.dir}" encoding="UTF-8" source="1.4"
                srcdir
    ="${src.java.dir}" includes="**/applet/**/*.java">

                
    <classpath refid="project.classpath" />
            
    </javac>
        
    </target>

    同时也相复制特定子目录下的文件夹:
        <target name="deploy.applet" depends="compile.java">
            
    <copy todir="${deploy.applet.dir}" preservelastmodified="true">
                
    <fileset dir="${build.java.dir}">
                    
    <include name="**/applet/**/*.class"/>
                
    </fileset>
            
    </copy>
        
    </target>


    两个都用到inclue方便。
    posted @ 2007-12-15 12:13 流浪汗 阅读(506) | 评论 (0)编辑 收藏
          今天同学想rebuild项目源码,但出现上面情况。上网找一下说与系统时间有问题。今天他机器有点问题,时间回到“前几天”的状态,面rebuild前的class文件的时间比“前几天”的状态新了。改正时间就行了。

    ^_^
    posted @ 2007-12-13 23:13 流浪汗 阅读(3826) | 评论 (2)编辑 收藏
         今天上课看到老师用Xbrowser连接linux,好玩。回来试下

    Enable XDMCP

    修改 /etc/gdm/custom.conf,将 [xdmcp] 部分的 Enable 设置为 1,即:
          [xdmcp]
          Enable=true
          Port=177
        
    修改 /etc/gdm/custom.conf,将 [security] 部分的 DisallowTCP 设置为 false,即:
          [security]
          DisallowTCP=false

    保存即可。

    修改 /etc/inittab,将运行级别设置为5(默认是这样),即:
          id:5:initdefault:

    我机器没有防火墙,所以这么简单,可以用Xbrowser看了,^_^

    转载:http://www.math.ecnu.edu.cn/~jypan/Teaching/Linux2007/Xmanager.txt
    ---------------------------------------------------------
    用 Xmanager 远程连接 Fedore Core

    ========================================
    法一:直接开启一个 gnome-session
    1. 点击桌面图标 Xmanager Enterprise
    2. 点击 Xmanager - Passive,在屏幕右下角出现Xmanager的图标
    3. 右击Xmanager图标 --> Tools --> Xstart
    4. Host: 远程服务器IP地址
       Protocol: SSH
       输入username 和 passwd
       Execution Command:
         gnome-session --display=本地主机IP:0.0
       点击 Run
    ===========================================================
    法二:开启一个登录窗口
    服务器:Fedora Core 4/Fedora Core 6
    终端:Xmanager 2.1.00.34

    服务器配置:(Gnome)
    ------------------------
    1. 配置 XDM
      (1). Change runlevel to 5
        修改 /etc/inittab,将运行级别设置为5,即:
          id:5:initdefault:

      (2). Enable XDMCP
        修改 /etc/X11/gdm/gdm.conf,将 [xdmcp] 部分的 Enable 设置为 1,即:
          [xdmcp]
          Enable=1
       
        修改 /etc/X11/gdm/gdm.conf,将 [security] 部分的 DisallowTCP 设置为 false,即:
          [security]
          DisallowTCP=false

        注:如果服务器是FC5或FC6,则配置文件为 /etc/gdm/custom.conf

    2. 配置防火墙 (TCP/UDP Ports) / 若已经关闭防火墙,则忽略这一步
          Open UDP port 177 from the PC to the remote host direction.
          Open incoming TCP ports 6000~6010 from the remote host to your PC.

    3. 重新启动服务器,即输入下面的命令即可:
       # init 3; init 5

    -------------------------


    终端配置
    ------------------------
    1、点击 Xmanager Enterprise 图标,打开 Xbrowser
       这时 Xbrowser 窗口中会显示局域网中所有的可用服务器
       (若没有显示,则表示服务器配置有问题)
       直接双击你想使用的服务器即可开启一个登录窗口


    终端配置(通过ssh登陆)
    ------------------------
    如果只能通过 ssh 登录,则需要进行一些配置
    首先配置 Xshell
    1、打开 Xshell,右击你想要连接的 session,
       如果没有的话,就创建一个新的 session

    2、右击 session,选择“Properties”,
       Connection 部分:
         “Name”中输入session的名字(随便写)
         “Method”为“SSH”,“Host”为服务器IP地址
         “Port Number”为“22”
      
       User Authentication 部分
         “Method”为“Password”
         “User Name”/“Password”为你的帐号和密码

    3、点击 Connection 部分中“Method”后面的“Setup”
       选择“Tunneling”,点击“TCP/IP Forwarding”中的“Add”,
       出现对话框,进行下面的操作:
         “Type”改为“Outgoing”,
         “Listen Port”取“6020”
         “Destination Host”改为“localhost”
         “Destination Port”取“6020”
         (注:Listen/Destination Port 可以是6020至6255中任意一个没有使用的值)
        保存设置

        Xshell 配置完成,下面开始配置 Xbrowser
    ------------------------
    1、点击 Xmanager Enterprise 图标,打开 Xbrowser
       选择 “Tools”--> “Option”
       在“New Address”输入服务器的IP地址,然后点击“Add”,
       保存设置。
     
    2、回到 Xbrowser 窗口,这时能看到你增加的服务器图标。
       右击服务器图标,选择“Save As”,创建一个新的 session,
       然后右击这个 session,选择“Properties”。
       在 “Proxy”部分打勾,Host为 “0.0.0.0”,
       Port Number 为“6020”
       (注:这个值应该与Xshell配置中第三步的“Listen Port”相同)

    3、点击“X Server”,把
       “Allocate display number automatically”前面的勾去掉,
       在“Display Number box”中输入 “20”
       (这个数字应等于上一步中的Port Number减去6000)
       保存设置

    4、双击该服务器图标即可开启一个登录窗口

    参见:
    http://www.netsarang.com/products/xmg_tutorial9.html
    http://www.netsarang.com/products/xmg_faq.html

    -----------------------------------------------



    posted @ 2007-11-20 13:45 流浪汗 阅读(2013) | 评论 (0)编辑 收藏
    WebBrowser是IE内置的浏览器控件,无需用户下载.

    一、WebBrowser控件
      <object ID='WebBrowser' WIDTH=0 HEIGHT=0 CLASSID='CLSID:8856F961-340A-11D0-A96B-00C04FD705A2'></object>
    二、WebBrowder控件的方法
    //打印

    WebBrowser1.ExecWB(6,1);

    //打印设置

    WebBrowser1.ExecWB(8,1);

    //打印预览

    WebBrowser1.ExecWB(7,1);

    关于这个组件还有其他的用法,列举如下:
    WebBrowser.ExecWB(1,1) 打开
    Web.ExecWB(2,1) 关闭现在所有的IE窗口,并打开一个新窗口
    Web.ExecWB(4,1) 保存网页
    Web.ExecWB(6,1) 打印
    Web.ExecWB(7,1) 打印预览
    Web.ExecWB(8,1) 打印页面设置
    Web.ExecWB(10,1) 查看页面属性
    Web.ExecWB(15,1) 好像是撤销,有待确认
    Web.ExecWB(17,1) 全选
    Web.ExecWB(22,1) 刷新
    Web.ExecWB(45,1) 关闭窗体无提示
    但是打印是会把整个页面都打印出来的,页面里面有什么东西就打印出来,我们有时候只需要打印数据表格,这时我们就要写一个样式了:把不想打印的部份隐藏起来:
    样式内容:
    <style type="text/css" media=print>
    .noprint{display : none }
    </style>
    然后使用样式就可以:
    <p class="noprint">不需要打印的地方</p>

    -----以上转载: http://blog.csdn.net/minjunyu/archive/2007/07/08/1682757.aspx-------------------

    示例代码:

    <HTML><HEAD><TITLE>javascript打印-打印页面设置-打印预览代码</TITLE>
    <META http-equiv=Content-Type content="text/html; charset=gb2312" />
    <SCRIPT language=javascript> 
      
    function printsetup(){ 
      
    // 打印页面设置 
      wb.execwb(8,1); 
      } 
      
    function printpreview(){ 
      
    // 打印页面预览 
         
      wb.execwb(
    7,1); 
          
         
      } 

      
    function printit() 
      { 
      
    if (confirm('确定打印吗?')) { 
      wb.execwb(
    6,6
      } 
      } 
      
    </SCRIPT>
    <style type="text/css" media=print>
    .noprint
    {display : none }
    </style>

    </HEAD>
    <BODY>

    <DIV align=center>
    <OBJECT id=wb height=0 width=0 
    classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 name=wb></OBJECT>
    net.blogjava.chenlb do print 中文 ^_^
    <class="noprint">
    <INPUT onclick=javascript:printit() type=button value=打印 name=button_print /> 
    <INPUT onclick=javascript:printsetup(); type=button value=打印页面设置 name=button_setup /> 
    <INPUT onclick=javascript:printpreview(); type=button value=打印预览 name=button_show />
    </p>
    </DIV>
    </BODY>
    </HTML>

    posted @ 2007-11-18 22:53 流浪汗 阅读(1226) | 评论 (0)编辑 收藏
         CRUD是 Create(创建)、Read(读取)、Update(更新)和Delete(删除)的缩写。
    posted @ 2007-11-18 18:17 流浪汗 阅读(2225) | 评论 (0)编辑 收藏
         blogjava的随笔管理里有Agg View一直不知道什么意思? 今天找一下,原来是Rss阅读器的阅读计数。

    游子的博客

    http://www.cnitblog.com/liaoqingshan/archive/2006/04/24/9413.html
    posted @ 2007-11-14 19:17 流浪汗 阅读(438) | 评论 (0)编辑 收藏
          N久没能用上远程桌面了,就是因为报“由于网络错误,连接被中断,请重新连接到远程计算机。”郁闷,很多时候需要用远程桌面,因老是不用了,所以改用pcAnywhere,这pcAnywhere不爽,别人也要安装。还是用windows远程桌面好。

         今天,找到了 liyunliang的博客
    --------------------------------------原文------------------------------------------

     问: 远程桌面连接出现"由于网络错误,连接被中断,请重新连接到远程计算机"错误!,xp2系统,网络是通的,系统日志显示严重错误“RDP 协议组件 "DATA ENCRYPTION" 在协议流中发现一个错误并且中断了客户端连接。”
      
    答:已经修复好了,删除了certificate子键,起动机器之后就好了!

     
      这是因为Certificate子键负责终端服务通信中数据信息的认证和加密,它一旦被损坏,终端服务的协议组件就会检测到错误,中断客户机与终端服务器之间的通信。导致Certificate子键损坏的原因很多,如管理员安装和卸载某些系统软件、对终端服务参数的不合理配置等。这时我们需要重置该键值中的内容,才能修复终端服务。
      
      进入注册表编辑器窗口,展开“HKEY_LOCAL_MA CHINE\SYSTEM\CurrentCon trolSet\Services\TermService\ Parameters”,找到名为“Certificate”的子键,将它删除,重新启动XP系统或Windows 2000 Server服务器,系统就会重新生成“Certificate”子键,这样客户端就能正常连接到终端服务器了。
      
         在终端服务器出现无法连接的问题后,我们首先要判断这是不是网络故障引起的,检测远程客户端和XP系统(Windows 2000 Server服务器)是否能够正常连接到网络;然后就要检查终端服务器的加密级别是否设置过高。排除上述原因后,就有可能是“Certificate”子键损坏了。此外,“HKEY_LOCAL _MACHINE\SYSTEM\Cur rentControlSet\Services\Term Service\Parameters”下的“X509 Certificate”和“X509 Certificate ID”损坏了也有可能导致终端服务出现问题,它们的修复方法与“Certificate”子键损坏后的修复方法是相同的。

    -------------------------------------end----------------------------------------------

    ^_^

    原文地址:http://hi.baidu.com/liyunliang/blog/item/ecdf37e98393143eb90e2d07%2Ehtml
    posted @ 2007-11-04 21:56 流浪汗 阅读(5248) | 评论 (4)编辑 收藏
          今天,师弟开发时有遇到一个小问题:struts表单点取消时,出现org.apache.struts.action.InvalidCancelException异常,弄了一阵子,发现用了validate="true"就会出现此异常。然后找到 freiberg 的博客。

    说到用

    <set-property property="cancellable" value="true"/>

    可以解决,马上复制去试下,行喔,^_^。

    ---------------------------------引用--------------------------------------

    Any existing applications that use the Cancel processing will need to modify their struts-config.xml to set the cancellable property for actions which require it.

    In Struts 1.2.9 the <set-property> is used to set the cancellable property for an action....

        <action path="/fooAction"
    input="/foo.jsp"
    validate="true">
    <set-property property="cancellable" value="true"/>
    <forward name="success" path="/bar.jsp"/>
    </action>
    

    From Struts 1.3.x a new cancellable attribute can be used....

        <action path="/fooAction"
    input="/foo.jsp"
    validate="true"
    cancellable="true">
    <forward name="success" path="/bar.jsp"/>
    </action>
    

    In both Struts 1.2.9 and Struts 1.3.x an exception handler can be configured to handle the InvalidCancelException

        <action path="/fooAction"
    input="/foo.jsp"
    validate="true"
    cancellable="true">
    <forward name="success" path="/bar.jsp"/>
    <exception key="errors.cancel"
    type="org.apache.struts.action.InvalidCancelException"
    path="/foo.jsp"/>
    </action>
    

    ---------------------------------------end-----------------------------------------------------

    刚好我用的是struts是1.2.9的

    原文:http://www.blogjava.net/freiberg/archive/2007/10/20/154384.html

    posted @ 2007-10-31 16:25 流浪汗 阅读(1418) | 评论 (1)编辑 收藏
          今天,师弟更新数据的时候出现问题。出现“更新分区关键字列将导致分区的更改” ,看了下数据库,更新的表有分区,而且更新的字段是分区的关键字(从报错可以看出来了)。
          网上找了下,说用这样可以:

    alter table xxx enable row_movement;

    但我没有试也没有这样做,可能是不放心,解决办法是不更新分区的关键字(因为系统不用更新它的,之前更新是因为hibernate处理它了)。如果的确要更新可以先删除了,再添加一个。引用http://www.itpub.net/283642,1.html

    Question: Why am I getting an ora-14402 error when I update a partition key
    Answer: You cannot update the value of the partition key, the only way you can go about this is by deleting the old row and adding a new row to the table


    posted @ 2007-10-29 21:09 流浪汗 阅读(4320) | 评论 (0)编辑 收藏

          与写对应的是读.

     

    package net.blogjava.chenlb;

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;

    import jxl.Cell;
    import jxl.Sheet;
    import jxl.Workbook;
    import jxl.read.biff.BiffException;


    /**
     * jxl 的Excel阅读器.
     * 
    @author chenlb 2007-10-20 下午01:36:01
     
    */
    public class JxlExcelReader {
        
        
    /**
         * 
    @return 返回String[] 的列表
         
    */
        
    public List readExcel(InputStream in) {
            List lt 
    = new ArrayList();
            Workbook wb 
    = null;
            
            
    try {
                wb 
    = Workbook.getWorkbook(in);
                Sheet[] sheets 
    = wb.getSheets();    //获取工作
                for(int i=0; i<sheets.length; i++) {
                    Sheet sheet 
    = sheets[i];
                    
    for(int j=0; j<sheet.getRows(); j++) {
                        Cell[] cells 
    = sheet.getRow(j);    //读取一行
                        if(cells != null && cells.length > 0) {    //这一行有内容才添加
                            String[] dataCells = new String[cells.length];
                            
    for(int k=0; k<cells.length; k++) {
                                dataCells[k] 
    = ""+cells[k].getContents(); //读内容
                            }//column
                            lt.add(dataCells);
                        }
                    }
    //one sheet
                }//xls file
            } catch (BiffException e) {
                e.printStackTrace();
            } 
    catch (IOException e) {    
                e.printStackTrace();
            } 
    finally {
                
    if(wb != null) {
                    wb.close();
                }
            }
            
            
    return lt;
        }

    }
    posted @ 2007-10-29 11:04 流浪汗 阅读(998) | 评论 (0)编辑 收藏
          项目中要写excel,把这个例子写出来,以后可以看。

    1.写excel类
    package net.blogjava.chenlb;

    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.List;

    import jxl.Workbook;
    import jxl.write.Label;
    import jxl.write.WritableSheet;
    import jxl.write.WritableWorkbook;
    import jxl.write.WriteException;
    import jxl.write.biff.RowsExceededException;

    /**
     * Jxl 的 Excel写数据器.
     * 
    @author chenlb 2007-10-29 上午10:39:31
     
    */
    public class JxlExcelWriter {
        
        
    /**
         * 
    @param datas 封装着Object[]的列表, 一般是String内容.
         * 
    @param title 每个sheet里的标题.
         
    */
        
    public void writeExcel(OutputStream out, List datas, String[] title) {
            
    if(datas == null) {
                
    throw new IllegalArgumentException("写excel流需要List参数!");
            }
            
    try {
                WritableWorkbook workbook 
    = Workbook.createWorkbook(out);
                WritableSheet ws 
    = workbook.createSheet("sheet 1"0);
                
    int rowNum = 0;    //要写的行
                if(title != null) {
                    putRow(ws, 
    0, title);//压入标题
                    rowNum = 1;
                }
                
    for(int i=0; i<datas.size(); i++, rowNum++) {//写sheet
                    Object[] cells = (Object[]) datas.get(i);
                    putRow(ws, rowNum, cells);    
    //压一行到sheet
                }
                
                workbook.write();
                workbook.close();    
    //一定要关闭, 否则没有保存Excel
            } catch (RowsExceededException e) {
                System.out.println(
    "jxl write RowsExceededException: "+e.getMessage());
            } 
    catch (WriteException e) {
                System.out.println(
    "jxl write WriteException: "+e.getMessage());
            } 
    catch (IOException e) {
                System.out.println(
    "jxl write file i/o exception!, cause by: "+e.getMessage());
            }
        }

        
    private void putRow(WritableSheet ws, int rowNum, Object[] cells) throws RowsExceededException, WriteException {
            
    for(int j=0; j<cells.length; j++) {//写一行
                Label cell = new Label(j, rowNum, ""+cells[j]);
                ws.addCell(cell);
            }
        }
    }

    2.使用
        public void testWriteExcel() {
            List datas 
    = new ArrayList();
            String[] data 
    = {"1""chenlb"};
            datas.add(data);
            
    try {
                OutputStream out 
    = new FileOutputStream(new File("doc/chenlb.blogjava.net.xls"));
                JxlExcelWriter jxlExcelWriter 
    = new JxlExcelWriter();
                jxlExcelWriter.writeExcel(out, datas, 
    new String[] {"Id""name"});
                out.close();
            } 
    catch (FileNotFoundException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
    catch (IOException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }

    posted @ 2007-10-29 10:52 流浪汗 阅读(5904) | 评论 (1)编辑 收藏
          当为遗留系统加入spring时,经典问题就是遗留系统需要引用spring管理的bean。幸好spring有机制可以处理这些。

    建一个类实现ApplicationContextAware接口,有一个引用ApplicationContext的静态成员,然后,遗留系统需要引用spring管理的bean的地方,使用这个类。

    1.比如:我这里建一个SpringContext类

    package net.blogjava.chenlb;

    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;

    /**
     * 此类可以取得Spring的上下文.
     * Spring 使new方法创建的对象可以引用spring管理的bean.
     * 2007-10-18 上午11:12:33
     * 
    @author chenlb
     
    */
    public class SpringContext implements ApplicationContextAware {

        
    protected static ApplicationContext context;
        
        
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            context 
    = applicationContext;
        }

        
    public static ApplicationContext getContext() {
            
    return context;
        }

    }

    2.然后在spring配置文件里加
    <bean id="springContext" class="net.blogjava.chenlb.SpringContext"></bean>

    3.其它类中引用
    MyBean myBean = (MyBean) SpringContext.getContext().getBean("myBean");

    4.如果老是写SpringContext.getContext().getBean("...");麻烦,可以建一个工厂类来返回你要的bean
    package net.blogjava.chenlb;



    public class MyServerFactory {


        
    public static MyBean1 getMyBean1() {
            
    return (MyBean1) SpringContext.getContext().getBean("myBean1");
        }
        

    }


    ^_^
    posted @ 2007-10-27 16:31 流浪汗 阅读(15389) | 评论 (1)编辑 收藏
         jstl 1.0 formatDate yyyy-mm 不能正常工作,格式出来的月是00,要用yyyy-MM,才能,郁闷。
    posted @ 2007-10-25 22:38 流浪汗 阅读(368) | 评论 (1)编辑 收藏
          开发项目,今天又难到问题。junit测试写数据到oracle时,出现:ORA-01461: can bind a LONG value only for insert into a LONG column错误,郁闷,试了几次发现,中文才会有这个问题,而且jsp页面里输入的中文又不会报这个错(前端是struts)。像mysql的话,很有可能是数据库字符编码问题,就怀疑是否为字符编码问题(这种思维不知道会不会很傻),因为项目所有编码都是utf-8, 看了下oracle是zhs16GBK。然后就建一个gbk的项目来测试,结果还是出现此问题。后来就换用旧系统的classes12.jar驱动测试下,^_^, 不会了,太好了。看了下classes12.jar的版本是9.0.2.0.0的而且又是classes12.jar不爽,后来看到一个帖子,说:用9的和10.2的没有此问题,我回去看下之前出问题的版本是10.1.0.2.0,郁闷,用的数据库是10.2.0.1.0。马上换成10.2.0.1.0的版本。当初不注意,今天花了我几个小时。我一直以为jdbc是数据库对应的。

    对应的jdbc在oracle安装目录可以找到oracle\product\10.2.0\db_1\jdbc\lib\ojdbc14.jar

    问题总算解决,^_^
    posted @ 2007-10-20 21:08 流浪汗 阅读(25234) | 评论 (14)编辑 收藏

          用java好久了,还没有写个压缩文件的示例,昨晚弄了下,把写下来,以后可以看。

    关系到
    java.util.zip.ZipEntry
    java.util.zip.ZipOutputStream

    如果要解决中文文件名问题,用到ant.jar

    这两个类。

    ZipOutputStream.putNextEntry(ZipEntry);就可以了,然后ZipOutputStream.wirte();就得了。

    package net.blogjava.chenlb.zip;

    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    //import java.util.zip.ZipEntry;
    //import java.util.zip.ZipOutputStream;
    //用ant.jar的zip.*可以解决中文文件名问题
    import org.apache.tools.zip.ZipEntry;
    import org.apache.tools.zip.ZipOutputStream;

    /**
     * 压缩文件.
     * 2007-10-17 下午11:19:50
     * 
    @author chenlb
     
    */
    public class RecursiveZip {

        
        
    public static void main(String[] args) {

            RecursiveZip recursiveZip 
    = new RecursiveZip();
            System.out.println(
    "====开始====");
            
    try {
                OutputStream os 
    = new FileOutputStream("e:/doc-recursive.zip");
                BufferedOutputStream bs 
    = new BufferedOutputStream(os);
                ZipOutputStream zo 
    = new ZipOutputStream(bs);
                
                
    //recursiveZip.zip("e:/recursive-zip/中文文件名.txt", new File("e:/recursive-zip"), zo, true, true);
                recursiveZip.zip("e:/recursive-zip"new File("e:/recursive-zip"), zo, truetrue);
                
                zo.closeEntry();
                zo.close();
            } 
    catch (FileNotFoundException e) {
                e.printStackTrace();
            } 
    catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println(
    "====完成====");
        }

        
    /**
         * 
    @param path 要压缩的路径, 可以是目录, 也可以是文件.
         * 
    @param basePath 如果path是目录,它一般为new File(path), 作用是:使输出的zip文件以此目录为根目录, 如果为null它只压缩文件, 不解压目录.
         * 
    @param zo 压缩输出流
         * 
    @param isRecursive 是否递归
         * 
    @param isOutBlankDir 是否输出空目录, 要使输出空目录为true,同时baseFile不为null.
         * 
    @throws IOException
         
    */
        
    public void zip(String path, File basePath, ZipOutputStream zo, boolean isRecursive, boolean isOutBlankDir) throws IOException {
            
            File inFile 
    = new File(path);

            File[] files 
    = new File[0];
            
    if(inFile.isDirectory()) {    //是目录
                files = inFile.listFiles();
            } 
    else if(inFile.isFile()) {    //是文件
                files = new File[1];
                files[
    0= inFile;
            }
            
    byte[] buf = new byte[1024];
            
    int len;
            
    //System.out.println("baseFile: "+baseFile.getPath());
            for(int i=0; i<files.length; i++) {
                String pathName 
    = "";
                
    if(basePath != null) {
                    
    if(basePath.isDirectory()) {
                        pathName 
    = files[i].getPath().substring(basePath.getPath().length()+1);
                    } 
    else {//文件
                        pathName = files[i].getPath().substring(basePath.getParent().length()+1);
                    }
                } 
    else {
                    pathName 
    = files[i].getName();
                }
                System.out.println(pathName);
                
    if(files[i].isDirectory()) {
                    
    if(isOutBlankDir && basePath != null) {    
                        zo.putNextEntry(
    new ZipEntry(pathName+"/"));    //可以使空目录也放进去
                    }
                    
    if(isRecursive) {    //递归
                        zip(files[i].getPath(), basePath, zo, isRecursive, isOutBlankDir);
                    }
                } 
    else {
                    FileInputStream fin 
    = new FileInputStream(files[i]);
                    zo.putNextEntry(
    new ZipEntry(pathName));
                    
    while((len=fin.read(buf))>0) {
                        zo.write(buf,
    0,len);
                    }
                    fin.close();
                }
            }
        }
    }


    posted @ 2007-10-18 13:53 流浪汗 阅读(3015) | 评论 (3)编辑 收藏
          昨天出了一个奇怪的问题,hibernate通过实体Id(char(10)型)取得数据,session.find("from TableName where id=?","value");取不到数据,但数据库里是有这个条数据。真奇怪,后来用pl/sql看数据库,鼠标点到Id那时,可以看到内容后面还有一些空格,带着期望与质疑把字段里的值自制过来, session.find("from TableName where id=?","value    ");后发现可以。我特别试了下connection.createStatement("select * from table_name where id='value'");则正常取数据,session.find("from TableName where id=?","value");而却找不到数据,然后又试了下
    ptmt = connection.prepareStatement(select * from table_name where id=?");
    ptmt.setString(1,"year");

    这样也不行,以是结论是:jdbc驱动PrepareStatement对char字段类型的查找问题,因为hibernate是用PrepareStatement的,自然,hibernate对char对应的属性条件查找出现找不到的情况,

    解决办法是:
    1.属性用TRIM函数处理:session.find("from TableName where TRIM(id)=?","value");
    2.char改为varchar2类型

    今天试了下mysql,它不会这样的情况,所以结论是:Oracle JDBC PreparedStatement的bug(有可能它故意这样)


    posted @ 2007-10-17 22:22 流浪汗 阅读(5535) | 评论 (1)编辑 收藏
          jsp 直接输出二进制文件怎么办呢?

    download.jsp
    <%@ page language="java" pageEncoding="utf-8"%>
    <%@ page import="java.io.*" %>
    <%
    try {
        FileInputStream fin 
    = new FileInputStream(application.getRealPath("/")+"/readme.zip");
        response.addHeader(
    "Content-Disposition","attachment;filename=read.zip"); 
        
    byte[] buf = new byte[1024];
        
    int readSize = fin.read(buf);
        OutputStream os 
    = response.getOutputStream();
        
        
    while(readSize != -1) {
            os.write(buf, 
    0, readSize);
            readSize 
    = fin.read(buf);
        }
        os.flush();
        os.close();
        os 
    = null ;
        response.flushBuffer();
        out.clear();
        out  
    =  pageContext.pushBody();
            
    catch (IllegalStateException e) {

    }
    %>

    webapps/test/readme.zip文件可以被下载,可能第一次会输出文字。
    posted @ 2007-10-16 23:57 流浪汗 阅读(572) | 评论 (0)编辑 收藏
    1.    encode.html
    <script language="JavaScript">
    document.write(encodeURI('http:
    //www.blogjava.net/chenlb/abc 中文'));
    </script>

    2.
    decode.jsp

            
    /*
             * <script language="JavaScript">
             * document.write(encodeURI('
    http://www.blogjava.net/chenlb/abc 中文'));
             * </script>
             
    */
            String url 
    = "http://www.blogjava.net/chenlb/abc%20%E4%B8%AD%E6%96%87";
            
    try {
                System.out.println(URLDecoder.decode(url, 
    "UTF-8"));
                System.out.println(URLDecoder.decode(url, 
    "GBK"));//乱码
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            

    posted @ 2007-10-13 21:27 流浪汗 阅读(9841) | 评论 (6)编辑 收藏

         用了svn管理源码已经好久了,但久了没有配置也忘了,今天有同学问我svn怎么安装配置,一时间命令忘记了。找了下文档,还是可以把它搭起来,为了方便以后查阅,blog记录下。

    下载
    svn-1.4.0-setup.exe(服务器)
    TortoiseSVN-1.4.3.8645-win32-svn-1.4.3.msi(客户端)
    LanguagePack-1.4.3.8645-win32-zh_CN.exe(客户端中文包)

    1.安装
    安装服务器(svn-1.4.0-setup.exe)和客户端(TortoiseSVN-1.4.3.8645-win32-svn-1.4.3.msi),按照提示即可。

    2.创建资源库

    svnadmin create d:/svnroot/repos

    3.运行svn服务
    svnserve -d -r d:/svnroot

    4.授权
    进入d:/svnroot/repos目录下的conf目录,打开svnserve.conf,去掉anon-access = read前面的#号注释,最好anon-access = read前没有空格也去掉,然后把anon-access = read改为anon-access = none,意思是说没有用户名与密码的不能读写,同样地把auth-access = write和password-db = passwd 去注释(和前面的空格)

    5.设置密码
    打开conf/passwd文件,在文件尾加如下:
    user_name = your_password

    6.导入
    右击你待导入的目录TortoiseSVN->Import(导入)...,然后URL里输入svn://localhost/repos即可。

    7.检出项目
    右击一个新的目录(待存放的项目的目录)SVN Check Out(检出)...,然后URL里输入svn://localhost/repos即可。完成后,这个新的目录左下角有一个绿色的钩。
    posted @ 2007-10-09 22:05 流浪汗 阅读(629) | 评论 (0)编辑 收藏
         前几天开始写代码,在weblogic 8.1.4上用hibernate3写hql语句,hql语句中出现有实体属性名(而不表字段名,两个不一样),竟然报错说表中没有这个字段,同时出现org.hibernate.hql.ast.HqlToken异常。郁闷,于是网上搜索下,说是weblogic 8.1.4 与 hibernate3冲突。都用了antlr.jar。

    多谢 蹒跚而行的博客 http://blog.chinajavaworld.com/entry.jspa?id=829

    转载他的

    ClassNotFoundException: org.hibernate.hql.ast.HqlToken 错误weblogic异常退出。
    原因:
    Hibernate3.0 采用新的基于ANTLR的HQL/SQL查询翻译器,在Hibernate的配置文件中,hibernate.query.factory_class属性用来选择查询翻译器。
    (1)选择Hibernate3.0的查询翻译器:
    hibernate.query.factory_class= org.hibernate.hql.ast.ASTQueryTranslatorFactory
    (2)选择Hibernate2.1的查询翻译器
    hibernate.query.factory_class= org.hibernate.hql.classic.ClassicQueryTranslatorFactory
    为了使用3.0的批量更新和删除功能,只能选择(1)否则不能解释批量更新的语句,当使用的时候出现了不支持条件输入中文的情况。选择(2)可以支持输入中文,但没法解释批量更新语句了
    在hibernate3中需要用到antlr,然而这个包在weblogic.jar中已经包含了antrl类库,就会产生一些类加载的错误,无法找到在war或者ear中的hibernate3.jar。
    出现这个错误之后,antlr会调用System.exit(),这样weblogic就会中止服务。
    解决方法:
    1.是在hibernate.properties文件中增加属性:hibernate.query.factory_class,属性的值是org.hibernate.hql.classic.ClassicQueryTranslatorFactory,这样就可以解决问题了。
    但是部分功能会有问题,譬如
    但本系在批量删除和更新会有问题,本系统不采用
    2.将antlr-2.7.5H3.jar到Weblogic的pre_Classpath :用WinRar或Winzip打开C:\bea\weblogic81\server\lib\weblogic.jar 删除里面的antlr目录, 然后再antlr-2.7.5H3.jar放在weblogic.jar的同一目录(注:替换之后没做做过严格测试,尚不知是否有后遗症)
    3. 1、拷贝Hibernate3里带的包antlr-2.7.5H3.jar到%WL_HOME%\server\lib下
    2、修改% mydomain% \ startWebLogic.cmd :
    在set CLASSPATH之前加上下面一句:
    set PRE_CLASSPATH=%WL_HOME%\server\lib\antlr-2.7.5H3.jar;
    在set CLASSPATH之后加上下面一句:
    set CLASSPATH=%PRE_CLASSPATH%;%CLASSPATH%
    一切OK!
    具体原因可参照此页:http://dev2dev.bea.com/blog/pmalani/archive/2005/07/configuring_web.html

     

    我用antlr-2.7.6.jar可以,我用的hibernate3.2.3ga
    posted @ 2007-10-07 16:37 流浪汗 阅读(1214) | 评论 (0)编辑 收藏
          实验室机房里安装的Weblogic 每次想打开网页看一下时都说连接不上,说页面打不开。最后得出原因是:过久了Web服务就关闭了,远程连下机器Web服务才开,每次都要这样远程链下机器,真烦,想到Windows服务方式运行不会这样。于是就找了下。今天终于找到了,^_^
           
    D:\bea\user_projects\domains\mydomain目录下的installService.cmd文件中的:runAdmin下面的内容
    1.
    set WLS_USER=weblogic
    set WLS_PW
    =
     
    改为
    set WLS_USER=weblogic
    set WLS_PW
    =weblogic

    2.
    set CMDLINE="%JAVA_VM% %MEM_ARGS% %JAVA_OPTIONS% -classpath \"%CLASSPATH%\" -Dweblogic.Name=%SERVER_NAME% -Dweblogic.management.username=%WLS_USER% -Dweblogic.ProductionModeEnabled=%PRODUCTION_MODE% -Djava.security.policy=\"%WL_HOME%\server\lib\weblogic.policy\" weblogic.Server"

    改为

    set CMDLINE="%JAVA_VM% %MEM_ARGS% %JAVA_OPTIONS% -classpath \"%CLASSPATH%\" -Dweblogic.Name=%SERVER_NAME% -Dweblogic.ProductionModeEnabled=%PRODUCTION_MODE% -Djava.security.policy="%WL_HOME%\server\lib\weblogic.policy" weblogic.Server"

    双击installService.cmd,就OK了
    注意防火墙要允许7001端口

    非常感谢囫囵不吞枣
    的博客 http://blog.sina.com.cn/s/blog_3ec64d78010005wu.html

    ^_^

    posted @ 2007-10-06 23:02 流浪汗 阅读(1088) | 评论 (1)编辑 收藏

    前几天用spring+hibernate+struts写了个增/删/改/查的例子。调试期间问题就来了,当查询结果翻页好几次就没N久没有响应了。最后控制报错。网上查了,它说数据库连接(池)问题。

    出现错误如下:

    <2007-9-30 下午120303 CST> <Error> <WebLogicServer> <BEA-000337> <ExecuteThread: '13' for queue: 'weblogic.kernel.Default' has been busy for "901" seconds working on the request "Http Request: /admin/school.do", which is more than the configured time (StuckThreadMaxTime) of "600" seconds.>

    先说下我配置

    1.环境:

    spring 2.0.6,hibernate 3.2.3,struts 1.2.9,oracle 10.2,weblogic 8.1.4

    jdbc是ojdbc14.jar

    2.连接池用DBCP

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">   
        
    <property name="driverClassName" value="${jdbc.driverClassName}"/>   
        
    <property name="url" value="${jdbc.url}"/>   
        
    <property name="username" value="${jdbc.username}"/>   
        
    <property name="password" value="${jdbc.password}"/>   
    bean>   

    3.分页方法(参考springside的),此类继承HibernateDaoSupport
    public Page listByPage(Class entityClass, int pageNo, int pageSize, List criterions, List orders) {    
        Criteria criteria 
    = createCriteria(entityClass, criterions);    
        CriteriaImpl impl 
    = (CriteriaImpl) criteria;    
       
        
    // 先把Projection和OrderBy条件取出来,清空两者来执行Count操作    
        Projection projection = impl.getProjection();    
        
    //获取总记录数    
        int totalCount = ((Integer) criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();    
       
            
        
    if(totalCount < 1) {    
            
    return new Page();    
        }    
            
        
    //加排序    
        if(orders != null) {    
            
    for(int i=0; i 
                criteria.addOrder((Order) orders.get(i));    
            }    
        }    
        
    //原来的投影    
        criteria.setProjection(projection);    
        
    int startIndex = Page.getStartOfPage(pageNo, pageSize);    
        
    //取得结果    
        List list = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();    
            
        
    return new Page(startIndex, totalCount, pageSize, list);    
    }    
       
    public Criteria createCriteria(Class entityClass, List criterions) {    
        Criteria criteria 
    = getSession().createCriteria(entityClass);    
        
    if(criterions != null) {    
            
    for(int i=0; i 
                criteria.add((Criterion) criterions.get(i));    
            }    
        }    
            
        
    return criteria;    
    }   

    另外,没有用OpenSessionInViewFilter,struts与spring的整合:DelegatingRequestProcessor、action path与bean name同名。

     

    翻页不过10次,服务器就没响应了,最后出现上面的错误的了。

    刚用weblogic,也刚用ssh套餐。郁闷。

    前天解决了。

    问题解决,问题的原因是数据库连接耗尽,我用HiberanteDaoSupport的getSession()方法取得Session后没有释放Session。

    出问题的代码处(红色部分):

    public Criteria createCriteria(Class entityClass, List criterions) {        
        Criteria criteria 
    = getSession().createCriteria(entityClass);        
        
    if(criterions != null) {        
            
    for(int i=0; i     
                criteria.add((Criterion) criterions.get(i));        
            }        
        }        
                
        
    return criteria;        
    }   

    用完Session释放后就没事了,调用HiberanteDaoSupport的releaseSession(session);方法后即可解决。


    现在正确的代码:


    public Page listByPage(Class entityClass, int pageNo, int pageSize, List criterions, List orders) {    
        Session session 
    = getSession();    
        
    //创建criteria    
        Criteria criteria = session.createCriteria(entityClass);    
        
    //为criteria添加criterions    
        createCriteria(entityClass, criteria, criterions);    
        CriteriaImpl impl 
    = (CriteriaImpl) criteria;    
       
        
    // 先把Projection和OrderBy条件取出来,清空两者来执行Count操作    
        Projection projection = impl.getProjection();    
        
    //获取总记录数    
        int totalCount = ((Integer) criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();    
       
            
        
    if(totalCount < 1) {    
            
    return new Page();    
        }    
            
        
    //加排序    
        if(orders != null) {    
            
    for(int i=0; i 
                criteria.addOrder((Order) orders.get(i));    
            }    
        }    
        
    //原来的投影    
        criteria.setProjection(projection);    
        
    int startIndex = Page.getStartOfPage(pageNo, pageSize);    
        
    //取得结果    
        List list = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();    
        
    //释放hiberante资源,一定要释放,要不然就数据库连接耗尽.    
        releaseSession(session);    
        
    return new Page(startIndex, totalCount, pageSize, list);    
    }    
       
    public Criteria createCriteria(Class entityClass, Criteria criteria, List criterions) {    
        
    if(criterions != null) {    
            
    for(int i=0; i 
                criteria.add((Criterion) criterions.get(i));    
            }    
        }    
            
        
    return criteria;    
    }   


    ^_^
    posted @ 2007-10-06 21:10 流浪汗 阅读(6095) | 评论 (4)编辑 收藏

    今天看了javascript的书,突然有点想法,javascript处理iframe中网页,一开始,遇到引用iframe问题,如:a.htm里有iframe为subpage.htm,在a.htm引用iframe里的文档(即:subpage.htm)。方法如下:
    1.

    var targetDoc = window.parent.frames['targetIframe'].document;

    2.
    var targetDoc = document.getElementById('targetIframe').contentWindow.document;

    解决引用问题后,src为其它网页时双拒绝访问,郁闷,baidu下才得知是跨域不用被javascript处理。郁闷,想法又能实现了。不知谁有好的建议。^_^


    我想要的效果是:自己的网页的一个区可以显示其它网页(这个很重要,显示效果就像真的在浏览器里,被显示的网页我称:subpage),然后javascript处理下subpage,使得实现想要的效果,比如:点subpage里链接时alert()出一些内容,等。
    posted @ 2007-09-24 20:34 流浪汗 阅读(2291) | 评论 (1)编辑 收藏

    1、安装好weblogic8.1
    2、利用Configuration Wizard配置Domain和server,按照缺省即可

    如:
    第二部后,我机上结果:有了D:\bea\user_projects\domains\mydomain目录其中mydomain是向导中自己写的。然后把web应用程序放到D:\bea\user_projects\domains\mydomain\applications目录中,applications相当于Tomcat中的webapps目录。

    WEB-INF目录下可以不用weblogic.xml文件,文件内容如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
    <weblogic-web-app>
        
    <context-root>/WebModule1</context-root>
    </weblogic-web-app>

    如果有<context-root>/WebModule1</context-root>,WebModule1才是web应用的根地址,访问地址就成了这样:http://localhost:7001/WebModule1/index.jsp

    如果没有<context-root>/WebModule1</context-root>或没有weblogic.xml文件,访问地址为:http://localhost:7001/blank/index.jsp
    其中blank是applications下的Web应用程序的根目录。
    posted @ 2007-09-22 18:48 流浪汗 阅读(5874) | 评论 (0)编辑 收藏
        我等这些装双系统(Windows、Linux)的人,很关心的问题是在Linux下能访问Windows的分区。在FC4下试过,FC4访问ntfs分区下还要打上内核补丁。FC7不用了(可能FC5就不用了)。FC7手动挂载如下:
    mount -t ntfs /dev/sda5 /mnt/win/d

    说明:我的是SATA的硬盘,所以是sda,D盘(Windows下的第二个盘块)是5。如果不知道硬盘顺序情况,用fdisk -l查看。

    1.在/root下建立winmount.sh文件(vi winmount.sh),内容如下:
    #!/bin/bash
    case $1 in
        m)
            mount 
    -t ntfs /dev/sda5 /mnt/win/d
        ;;
        u)
            umount 
    /mnt/win/d
        ;;
    esac


    2.分可执行权限
    chmod u+x winmount.sh

    3.让开机自动启动
    在/etc/rc.d/rc.local里添加如下内容:
    sh ./root/winmount.sh m

    ^_^, 好重启后就可以了,FC7上测试通过。

    这些得益于 红客burton的博客 http://burton.bokee.com/1627823.html




    posted @ 2007-09-10 21:58 流浪汗 阅读(1211) | 评论 (2)编辑 收藏
        一直想在Linux下安装视频播放器,以年前就在FC4下安装了mplayer,安装了两个星期,安装还是没有界面的,郁闷。N久没有用Linux了,这学期一开始就让Linux的课,就又用Linux了,安装的是FC7。用了几天决定安装mplayer,曾在虚拟机里安装过,但make时说我硬件不支持界面。郁闷,今晚终于把mplayer安装上了。得益于qwent写的安装手册。
    如下(我在FC7下安装没事,现在一边听歌一边写blog):

    在fc5中安装mplayer,安装借鉴了qwent的《写给初学者的mplayer安装过程的拾遗》。
    在www.mplayerhq.hu下载mplayer及codecs文件:
    MPlayer-1.0rc1.tar.bz2
    blue-1.6.tar.bz2
    all-20061022.tar.bz2
    windows-all-20061022.zip
    #cd /usr/src/mplayer
    #tar xjvf all-20061022.tar.bz2
    #mv all-20061022 /usr/lib/codecs
    #chmod 644 /usr/lib/codecs/*
    #chown root.root /usr/lib/codecs/*
    #unzip windows-all-20061022.zip
    #mv windows-all-20061022 /usr/lib/wincodecs
    #chmod 644 /usr/lib/wincodecs/*
    #chown root.root /usr/lib/wincodecs/*
    #tar xjvf MPlayer-1.0rc1.tar.bz2
    #cd MPlayer-1.0rc1/
    #./configure --enable-gui --enable-largefiles --enable-menu --prefix=/usr --with-codecsdir=/usr/lib/codecs/ --with-win32libdir=/usr/lib/wincodecs/ --confdir=/etc/mplayer
    #make
    #make install

    安装后提示(我自己加的):
    *** Download skin(s) at http://www.mplayerhq.hu/dload.html
    *** for GUI, and extract to /usr/share/mplayer/skins/
    install -m 644 etc/mplayer.xpm /usr/share/pixmaps/mplayer.xpm
    install -m 644 etc/mplayer.desktop /usr/share/applications/mplayer.desktop
     
    #cd ..
    #bzip2 -cd Blue-1.6.tar.bz2|tar xvf - -C /usr/share/mplayer/skins/
    #mv /usr/share/mplayer/skins/Blue/ /usr/share/mplayer/skins/default/
    #cd /usr/share/fonts/chinese/TrueType/
    #cp ukai.ttf ~/.mplayer/subfont.ttf
     (我的上面一行出错,说没有那个目录或文件,先mkdir ~/.mplayer就好了)
    桌面建立一启动器,命令为/usr/bin/gmplayer,图标名称是mplayer-desktop.xpm
     
     (我的没有出现下面错误,安装Linux时选择开发的),  ^_^  好高兴
    附:
    1,make时提示:Error: X11 support required for GUI compilation.
    缺少gtk+和gtk+-devel包
    #yum install gtk+
    #yum install gtk+-devel
    2,安装完运行程序时提示:cannot load bitmap font:/usr/share/mplayer/font/font.desc
    缺少字体文件
    在http: //www.linuxfans.org/nuke/modules.php?name=Site_Downloads&op=geninfo& did=2858下载字体文件,解压缩后将其中一个文件夹中的文件放入/usr/share/mplayer/font/下面
    #mv font-arial-cp1250.tar.tar font-arial-cp1250.tar.bz2
    #tar xjvf font-arial-cp1250.tar.bz2
    #cd font-arial-18-cp1250/font-arial-18-cp1250/
    #cp * /usr/share/mplayer/font/
    重启mplayer,错误消失。

    posted @ 2007-09-09 23:44 流浪汗 阅读(1612) | 评论 (0)编辑 收藏
        用过虑器,但只对post有效,get方式请看。http://www.blogjava.net/chenlb/archive/2007/07/17/130922.html

    1.用tomcat里面的例子(在webapps\servlets-examples\WEB-INF\classes\里把filters目录放到你的classer\下,其实只要SetCharacterEncodingFilter就可以了,在web.xml里加

    <filter>     
      
    <filter-name>Set Character Encoding</filter-name>     
      
    <filter-class>filters.SetCharacterEncodingFilter</filter-class>     
      
    <init-param>     
        
    <param-name>encoding</param-name>     
        
    <param-value>utf8</param-value>     
      
    </init-param>     
    </filter>     
     
    <filter-mapping>     
        
    <filter-name>Set Character Encoding</filter-name>     
        
    <url-pattern>/*</url-pattern>     
     
    </filter-mapping>


    2.如果用spring,用spring提供的过虑器,同样在web.xml里加
    <filter>  
      
    <filter-name>Set Character Encoding</filter-name>  
      
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
      
    <init-param>  
        
    <param-name>encoding</param-name>  
        
    <param-value>utf8</param-value>  
      
    </init-param>  
    </filter>  
     
    <filter-mapping>  
        
    <filter-name>Set Character Encoding</filter-name>  
        
    <url-pattern>/*</url-pattern>  
     
    </filter-mapping>


    posted @ 2007-09-09 09:47 流浪汗 阅读(422) | 评论 (0)编辑 收藏
        收集于:vocat的专栏 
    http://blog.csdn.net/vocat/archive/2006/10/21/1344388.aspx

    结合我的情况,写下来以后忘记了,可以看下。

    =============================如下是:vocat原文===============================

    很多和我一样的菜鸟,为了学linux都会在原来windows的基础上安装linux。但windows的病毒是在太多了,难保哪天中了病毒杀不掉甚至进不windows了就只好重装了。重装后往往就默认直接进入windows,而没有出现个菜单让你选择是进windows和linux。原因嘛,网上搜下到处都是,下面直接进入正题,找回进不去的linux。

    先准备好以下两个软件

    grub for dos(http://sourceforge.net/project/showfiles.php?group_id=104188),选择GRUB4DOS那个就行,用这个来引导linux

    explore2fs(http://www.chrysocome.net/explore2fs),这个是在windows下看linux文件用的

    以上两个软件或者百度,google下,到处都有,很多,好啦,开始进入步骤

    1:把下好的grub for dos 解压到C盘根目录下,取名为grub,把里面的grlrd复制到C盘根目录下

    2:找到C盘下面的boot.ini文件(这是个隐藏文件),在里面最后一行加入c:\grldr="linux"

    3:新建一个menu.lst文件,把它放在C盘根目录下,里面的内容,以我的为例,如下

    title redhat 9.0
    root (hd0,7)
    kernel (hd0,7)/boot/vmlinuz-2.4.20-8 root=/dev/hda8
    initrd (hd0,7)/boot/initrd-2.4.20-8.img
    boot

    总共5行,每行的意思如下

    第一行:title redhat 9.0
    这个title跟的值是指你要在菜单上出现用来显示linux的名称

    第二行:root (hd0,7)
    一般的写法为root(hdX,Y)
    对于X,如果你只有一个硬盘且装在这个硬盘(好像是废话……)那么当然为0啦,否则的话以此类推为1,2,等
    对于Y,这个会稍微复杂些。在windows下面,由一个主分区-C盘,和N个扩展分区-D,E,F……等组成。但在linux下,hd1~hd4代表主分区,对应于windows下就是C盘,hd5开始为扩展分区,如hd5对应D盘,hd6对应E盘等。grub的分区算法和linux类似,但有一个差别是,它是从0开始计数的,也就是说0~3对应C盘,4对应D盘,以此类推。我自己的电脑分区如下C盘-windows,D,E,F存储资料,剩下的空间给了linux,所以为root(hd0,7)

    第三行:kernel (hd0,7)/boot/vmlinuz-2.4.20-8 root=/dev/hda8
    把vmlinuz-2.4.20-8换成你对应的文件就行啦。用explre2fs这个软件就可以在windows下看linux分区的文件啦。要有点注意的是,root=/dev/hda8 中的hda8而不是hda7,因为此时是按照liuux的规则而不是grub的规则。

    第四行:initrd (hd0,7)/boot/initrd-2.4.20-8.img
    也只要把initrd-2.4.20-8.img 替换成你相应的文件就行啦

    第五行:root
    好像没什么好说吧……

    OK,大功告成也~

    =============================以上是:vocat原文===============================

    现在来看我的情况:我硬盘有C、D、E、F分区,其中linux分区在E、F之间,有/boot、/、swap三个分区。
    整个硬盘分区的顺序C、D、E、/boot、/、swap、F

    我的menu.lst的写法是:

    title FC7
    root (hd0
    ,7
    kernel /vmlinuz-
    2.6.21-1.3194.fc7 ro root=LABEL=/ rhgh quiet
    initrd /initrd-
    2.6.21-1.3194.fc7.img 
    boot


    kernel (hd0,7)/boot/vm...  root=/dev/sda8
    initrd (hd0,7)/boot/initrd...
    反而不行

    我的是怎样看到的呢?,是安装Linux后启动后的第一幕的前面几行就是。

    posted @ 2007-09-07 21:22 流浪汗 阅读(5513) | 评论 (0)编辑 收藏
        UTF-8修改(写xml文件乱码),报Invalid byte 2 of 2-byte UTF-8 sequence错误。写gb2312和gbk没事,写xml是网上的例子,用了FileWirter。然后找到

    ~临风轻扬~ 

    博客:http://blog.csdn.net/redez/archive/2005/11/11/527897.aspx

    说到用FileOutPutStream

    看例子(是个测试类,只给出这个修改方法,测试类请看——dom4j 读 xml:http://www.blogjava.net/chenlb/archive/2007/09/05/143036.html):

        public void testModXml() {
            List list 
    = document.selectNodes("/company/tel" );
            Random rm 
    = new Random();
            
    for(Element tel : (List<Element>) list) {
                
                logger.info(
    "tel: "+tel.getTextTrim());
                tel.setText(
    "020-12345678-"+rm.nextInt(100));
            }
            
            Element root 
    = document.getRootElement();
            
            
    for(int i=0; i<2; i++) {
                Element tel 
    = root.addElement("tel");
                tel.setText(
    "020-12345678-"+rm.nextInt(100));
            }
            
            
            XMLWriter writer;
            
    try {
                OutputFormat format 
    = OutputFormat.createPrettyPrint();
                
    //format.setEncoding("UTF-8");
                FileOutputStream fos = new FileOutputStream(xmlFile);
                
    //writer = new XMLWriter(new FileWriter(xmlFile), format);
                writer = new XMLWriter(fos, format);
                writer.write(document);
                writer.close();
            } 
    catch (IOException e) {
                
    // TODO 自动生成 catch 块
                logger.error("修改xml文件失败!");
                e.printStackTrace();
            }   
        }


     

    posted @ 2007-09-06 00:10 流浪汗 阅读(6174) | 评论 (1)编辑 收藏
         由于要保存一些项目中只有一个而且很少改的,用数据库存储太浪费了,用xml保存吧。

     1.现在来看下读xml,xml文件如下:
    <?xml version="1.0" encoding="UTF-8"?>

    <company> 
      
    <tel>020-12345678-66</tel>  
      
    <tel>020-12345678-85</tel>  
      
    <introduce> 
      
    <![CDATA[
    <br/><h1>公司简介</h1>
      
    ]]>
      
    </introduce>  
    </company>

    2.用dom4j 读,
    package cn.rentbus;

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    //import java.io.FileWriter;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Random;

    import junit.framework.TestCase;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.Node;
    import org.dom4j.io.OutputFormat;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;

    public class Dom4jXmlTest extends TestCase {

        
    protected final Log logger = LogFactory.getLog(getClass());
        
        
    private SAXReader reader;
        
    private Document document;
        
    private File xmlFile;
        
        
    protected void setUp() throws Exception {
            xmlFile 
    = new File("WEB-INF/company.xml");
            reader 
    = new SAXReader();
            document 
    = reader.read(xmlFile);

        }

        
    protected void tearDown() throws Exception {
            
    super.tearDown();
        }

        
    public void testReadXml() {
            Element root 
    = document.getRootElement();
            
            
    for ( Iterator i = root.elementIterator( "tel" ); i.hasNext(); ) {
                Element tel 
    = (Element) i.next();
                logger.info(
    "tel: "+tel.getTextTrim());
                
    // do something
            }
            
            logger.info(
    "==== XPath use on tel ====");
            
            List list 
    = document.selectNodes("/company/tel" );
            
    for(Element tel : (List<Element>) list) {
                logger.info(
    "tel: "+tel.getTextTrim());
            }
            
            
    for ( Iterator i = root.elementIterator( "introduce" ); i.hasNext(); ) {
                Element introduce 
    = (Element) i.next();
                logger.info(
    "introduce: "+introduce.getTextTrim());
                
    // do something
            }
            
            logger.info(
    "==== XPath use on introduce ====");
            
            Node node 
    = document.selectSingleNode("/company/introduce");
            
            String introduce 
    = node.getText();
            logger.info(
    "introduce: "+introduce.trim());
            
            
        }
        
    }


    注意:如果用到XPath,需要jaxen-1.1-beta-6.jar(发本包/lib下有)

    我的环境:
    dom4j-1.6.1.jar
    jaxen-1.1-beta-6.jar
    posted @ 2007-09-05 23:58 流浪汗 阅读(3635) | 评论 (2)编辑 收藏
        不知那天开始,任务管理器标题没了,光秃秃的,想看任务管理器其它的内容没法切换。郁闷……
        百度一下,有结果了。发现百度的知道发展得很好,很多电脑应用问题都有答案。

        解决方法是:双击任务管理器面板就出来了,再双击又是光秃秃的……,^_^

    百度知道
    http://zhidao.baidu.com/question/869385.html
    posted @ 2007-09-03 20:38 流浪汗 阅读(698) | 评论 (0)编辑 收藏
        Javascript检测整数或小数,写的正则表达式:
    ^(+|\-)?\d+(.\d+)?$
    报错,说数量词错误。

    然后改用:
    ^[+\-]?\d+(.\d+)?$
    就行了,^_^
    posted @ 2007-08-27 14:56 流浪汗 阅读(11033) | 评论 (7)编辑 收藏

    这里使用一个小技巧,就是先将其转换为可编辑的JSP文件,然后再像操作其它的JSP页面一样操作,就这么简单。

    因为ms word和excel的文档都支持html文本格式,因此可以先用word或excel做好模版,另存为web页,然后将该html改成jsp,将数据部分动态填入即可,不用很辛苦的调整格式 。

    word页面只要在jsp头设置如下指令:
    <%@page contentType="application/msword;charset=gb2312" %>

    excel如下:
    <%@page contentType="application/vnd.ms-excel;charset=gb2312" %>

      使用这种方式,就不用使用其它的复杂技术,并且可以达到很好的效果,所谓走路走捷径,呵呵,例子就不给了。

    http://blog.csdn.net/fenglibing/archive/2007/06/27/1668809.aspx
    posted @ 2007-08-22 13:15 流浪汗 阅读(294) | 评论 (0)编辑 收藏
        由于项目里要发邮件,用了spring 和 velocity 模板。写下来以后可以看,好记性不如博客。
    版本说明下:
    spring 2.0.6
    velocity 1.5
    javamail 用 spring/lib下的

    1.封装邮件信息类:
    package com.chenlb.mail;

    import java.util.Map;

    import javax.mail.MessagingException;
    import javax.mail.internet.MimeMessage;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.apache.velocity.app.VelocityEngine;
    import org.springframework.mail.MailException;
    import org.springframework.mail.javamail.JavaMailSender;
    import org.springframework.mail.javamail.MimeMessageHelper;
    import org.springframework.ui.velocity.VelocityEngineUtils;

    /**
     * 邮件发送器
     * @作者 chenlb
     * @创建时间 2007-7-28 下午03:35:31 
     
    */
    public class VelocityTemplateMailMessage {

        
    protected final Log logger = LogFactory.getLog(getClass());
        
        
    private JavaMailSender javaMailSender;
        
    private VelocityEngine velocityEngine;
        
    private String from;
        
    private String title;
        
    private String encoding;
        
    private String templateLocation;
        
    private String[] toEmails;
        
    private Map model;


        
    public boolean send() {
            MimeMessage msg 
    = javaMailSender.createMimeMessage();
            MimeMessageHelper helper 
    = new MimeMessageHelper(msg);
            
            
    try {
                helper.setFrom(from);
                helper.setSubject(title);
                helper.setTo(toEmails);
                helper.setText(getMessage(), 
    true);   //如果发的不是html内容去掉true参数
                javaMailSender.send(msg);
                
            } 
    catch (MessagingException e) {
                
    // TODO 自动生成 catch 块
                if(logger.isWarnEnabled()) {
                    logger.warn(
    "邮件信息导常! 邮件标题为: "+title);
                }
                
    return false;
                
    //e.printStackTrace();
            } catch (MailException me) {
                
    // TODO: handle exception
                if(logger.isWarnEnabled()) {
                    logger.warn(
    "发送邮件失败! 邮件标题为: "+title);
                }
                
    return false;
            }
            
    return true;    
        }
        
        
        
    /**
         * 邮件模板中得到信息
         * 
    @return 返回特发送的内容
         
    */
        
    private String getMessage() {
            
    return VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, 
                    templateLocation, encoding, model);
        }

        
    private String[] createToEmail(String to) {
            
    return new String[] {to};
        }
        
        
    public void setToEmail(String to) {
            setToEmails(createToEmail(to));
        }
        
        
    public void setJavaMailSender(JavaMailSender javaMailSender) {
            
    this.javaMailSender = javaMailSender;
        }
        
        
    public void setVelocityEngine(VelocityEngine velocityEngine) {
            
    this.velocityEngine = velocityEngine;
        }

        
    public void setEncoding(String encoding) {
            
    this.encoding = encoding;
        }

        
    public void setModel(Map model) {
            
    this.model = model;
        }

        
    public void setTemplateLocation(String templateLocation) {
            
    this.templateLocation = templateLocation;
        }

        
    public void setTitle(String title) {
            
    this.title = title;
        }

        
    public void setToEmails(String[] toEmails) {
            
    this.toEmails = toEmails;
        }

        
    public void setFrom(String from) {
            
    this.from = from;
        }

        
    public String getTemplateLocation() {
            
    return templateLocation;
        }
    }

    2.spring配置文件,applictionContext-mail.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
            "dtd/spring-beans-2.0.dtd"
    >
    <!-- http://www.springframework.org/ -->
    <beans>

    <!-- 属性文件加载 -->
        
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            
    <property name="locations">
              
    <list>
                  
    <value>classpath:mail.properties</value>
              
    </list>
          
    </property>
        
    </bean>

    <!-- 邮件发送器 -->
        
    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
            
    <property name="host" value="${mail.host}" />
            
    <property name="username" value="${mail.username}" />
            
    <property name="password" value="${mail.password}" />
            
    <property name="defaultEncoding" value="UTF-8"></property>
            
    <property name="javaMailProperties">
                
    <props>
                    
    <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
                    
    <prop key="mail.smtp.timeout">${mail.smtp.timeout}</prop>
                
    </props>
            
    </property>
        
    </bean>
        
        
    <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
            
    <property name="resourceLoaderPath" value="classpath:velocity"></property>
        
    </bean>
        
        
    <bean id="templateMail" class="com.chenlb.mail.VelocityTemplateMailMessage">
            
    <property name="javaMailSender" ref="mailSender"></property>
            
    <property name="from" value="${mail.from}"></property>
            
    <property name="encoding" value="UTF-8"></property>
            
    <property name="templateLocation" value="test.vm"></property>
            
    <property name="velocityEngine" ref="velocityEngine"></property>
            
    <property name="title" value="wwww.blogjava.net/chenlb"></property>
        
    </bean>
        
    </beans>
    说明:模板文件放到classpath的velocity目录下,可自行改。

    3.发送者邮件信息,mail.properties(classpath位置):
    mail.from=yourname@126.com
    mail.host
    =smtp.126.com
    mail.password
    =yourpassword
    mail.smtp.auth
    =true
    mail.smtp.timeout
    =25000
    mail.username
    =yourname

    4.模板文件,text.vm(classpath的velocity目录下):
    你好!${me} 这是模板生成的邮件。

    5.使用:
    VelocityTemplateMailMessage vtmm = (VelocityTemplateMailMessage) context.getBean("templateMail");
    Map
    <String, String> data = new HashMap<String, String>();
    data(
    "me","yourname");
    vtmm.setModel(data);
    vtmm.setToMail(
    "yourOtherMail@163.com");
    vtmm.setTitle(
    "mail with veloctiy and spring");
    vtmm.send();

     

    看下是否收到邮件了。^_^

    posted @ 2007-08-21 19:43 流浪汗 阅读(3322) | 评论 (6)编辑 收藏

       

    请参:

    方法一:使用插入分节符的方式在第一页的最后,插入/分隔符/分节符使之与后面的成为两节再从第二页即第二节的页眉处插入页码设置页码的起始编号为1.

    方法二:使用首页不同的设置,可见页面设置/版式:首页不同,将首页设置为与后面不一样的页眉页脚,在第二页的页眉中的页码格式设置(页眉页码工具栏),设置起始页码为1.

    方法三使用域计算,在页眉或者页脚处插入如下域代码:{ if { page } > 1 { = { page } - 1 } "" }

    此域代码的意思是如果页码大于1,则当前页码数-1,反之则为空.

    注意花括号为CTRL+F9系统自动插入的,文字为英文标点下的字符输入,中间有空格详细的域使用方法可见置顶贴子<也谈域在WORD中的应用>

    相关链接:http://club.excelhome.net/dispbbs.asp?BoardID=23&replyID=326315&id=67463&skin=0

    http://club.excelhome.net/dispbbs.asp?boardID=23&ID=48825&page=1

    posted @ 2007-08-21 17:08 流浪汗 阅读(2092) | 评论 (0)编辑 收藏