posts - 19, comments - 1, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Unicode编码

Unicode是一种字符编码规范 。

先从ASCII说起。ASCII是用来表示英文字符的一种编码规范,每个ASCII字符占用1个字节(8bits)

因此,ASCII编码可以表示的最大字符数是256,其实英文字符并没有那么多,一般只用前128个(最高位为0),其中包括了控制字符、数字、大小写字母和其他一些符号 。

而最高位为1的另128个字符被成为“扩展ASCII”,一般用来存放英文的制表符、部分音标字符等等的一些其他符号

这种字符编码规范显然用来处理英文没有什么问题 。(实际上也可以用来处理法文、德文等一些其他的西欧字符,但是不能和英文通用),但是面对中文、阿拉伯文之类复杂的文字,255个字符显然不够用

于是,各个国家纷纷制定了自己的文字编码规范,其中中文的文字编码规范叫做“GB2312-80”,它是和ASCII兼容的一种编码规范,其实就是利用扩展ASCII没有真正标准化这一点,把一个中文字符用两个扩展ASCII字符来表示。

但是这个方法有问题,最大的问题就是,中文文字没有真正属于自己的编码,因为扩展ASCII码虽然没有真正的标准化,但是PC里的ASCII码还是有一个事实标准的(存放着英文制表符),所以很多软件利用这些符号来画表格。这样的软件用到中文系统中,这些表格符就会被误认作中文字,破坏版面。而且,统计中英文混合字符串中的字数,也是比较复杂的,我们必须判断一个ASCII码是否扩展,以及它的下一个ASCII是否扩展,然后才“猜”那可能是一个中文字 。

总之当时处理中文是很痛苦的。而更痛苦的是GB2312是国家标准,台湾当时有一个Big5编码标准,很多编码和GB是相同的,所以……,嘿嘿。

这时候,我们就知道,要真正解决中文问题,不能从扩展ASCII的角度入手,也不能仅靠中国一家来解决。而必须有一个全新的编码系统,这个系统要可以将中文、英文、法文、德文……等等所有的文字统一起来考虑,为每个文字都分配一个单独的编码,这样才不会有上面那种现象出现。

于是,Unicode诞生了。

Unicode有两套标准,一套叫

Unicode-16UCS-2,用2个字节为字符编码,另一套叫Unicode-32UCS-4,用4个字节为字符编码。

以目前常用的

Unicode-16UCS-2为例,它可以表示的字符数为2^16=65535,基本上可以容纳所有的欧美字符和绝大部分的亚洲字符 。

UTF-8的问题后面会提到 。

在Unicode里,所有的字符被一视同仁。汉字不再使用“两个扩展ASCII”,而是使用“1个Unicode”,注意,现在的汉字是“一个字符”了,于是,拆字、统计字数这些问题也就自然而然的解决了 。

但是,这个世界不是理想的,不可能在一夜之间所有的系统都使用Unicode来处理字符,所以Unicode在诞生之日,就必须考虑一个严峻的问题:和ASCII字符集之间的不兼容问题。

我们知道,ASCII字符是单个字节的,比如“A”的ASCII是65。而Unicode是双字节的,比如“A”的Unicode是0065,这就造成了一个非常大的问题:以前处理ASCII的那套机制不能被用来处理Unicode了 。

另一个更加严重的问题是,C语言使用'\0'作为字符串结尾,而Unicode里恰恰有很多字符都有一个字节为0,这样一来,C语言的字符串函数将无法正常处理Unicode,除非把世界上所有用C写的程序以及他们所用的函数库全部换掉 。

于是,比Unicode更伟大的东东诞生了,之所以说它更伟大是因为它让Unicode不再存在于纸上,而是真实的存在于我们大家的电脑中。那就是:UTF 。

UTF= UCS Transformation Format UCS转换格式

它是将Unicode编码规则和计算机的实际编码对应起来的一个规则。现在流行的UTF有2种:UTF-8和UTF-16 。

其中UTF-16和上面提到的Unicode本身的编码规范是一致的,这里不多说了。而UTF-8不同,它定义了一种“区间规则”,这种规则可以和ASCII编码保持最大程度的兼容 。

UTF-8有点类似于Haffman编码,它将Unicode编码为00000000-0000007F的字符,用单个字节来表示;

00000080-000007FF的字符用两个字节表示

00000800-0000FFFF的字符用3字节表示

因为目前为止Unicode-16规范没有指定FFFF以上的字符,所以UTF-8最多是使用3个字节来表示一个字符。但理论上来说,UTF-8最多需要用6字节表示一个字符。

在UTF-8里,英文字符仍然跟ASCII编码一样,因此原先的函数库可以继续使用。而中文的编码范围是在0080-07FF之间,因此是2个字节表示(但这两个字节和GB编码的两个字节是不同的),用专门的Unicode处理类可以对UTF编码进行处理。

下面说说中文的问题。

由于历史的原因,在Unicode之前,一共存在过3套中文编码标准。

GB2312-80,是中国大陆使用的国家标准,其中一共编码了6763个常用简体汉字。Big5,是台湾使用的编码标准,编码了台湾使用的繁体汉字,大概有8千多个。HKSCS,是中国香港使用的编码标准,字体也是繁体,但跟Big5有所不同。

这3套编码标准都采用了两个扩展ASCII的方法,因此,几套编码互不兼容,而且编码区间也各有不同

因为其不兼容性,在同一个系统中同时显示GB和Big5基本上是不可能的。当时的南极星、RichWin等等软件,在自动识别中文编码、自动显示正确编码方面都做了很多努力 。

他们用了怎样的技术我就不得而知了,我知道好像南极星曾经以同屏显示繁简中文为卖点。

后来,由于各方面的原因,国际上又制定了针对中文的统一字符集GBK和GB18030,其中GBK已经在Windows、Linux等多种操作系统中被实现。

GBK兼容GB2312,并增加了大量不常用汉字,还加入了几乎所有的Big5中的繁体汉字。但是GBK中的繁体汉字和Big5中的几乎不兼容。

GB18030相当于是GBK的超集,比GBK包含的字符更多。据我所知目前还没有操作系统直接支持GB18030。

这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级。整理这篇文章的动机是两个问题:


问题一:
使用Windows记事本的“另存为”,可以在GBK、Unicode、Unicode big endian和UTF-8这几种编码方式间相互转换。同样是txt文件,Windows是怎样识别编码方式的呢?

我很早前就发现Unicode、Unicode big endian和UTF-8编码的txt文件的开头会多出几个字节,分别是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但这些标记是基于什么标准呢?

问题二:
最近在网上看到一个ConvertUTF.c,实现了UTF-32、UTF-16和UTF-8这三种编码方式的相互转换。对于Unicode(UCS2)、GBK、UTF-8这些编码方式,我原来就了解。但这个程序让我有些糊涂,想不起来UTF-16和UCS2有什么关系。
查了查相关资料,总算将这些问题弄清楚了,顺带也了解了一些Unicode的细节。写成一篇文章,送给有过类似疑问的朋友。本文在写作时尽量做到通俗易懂,但要求读者知道什么是字节,什么是十六进制。

0、big endian和little endian
big endian和little endian是CPU处理多字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面,就是big endian。还是将49写在前面,就是little endian。

“endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。

我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。

1、字符编码、内码,顺带介绍汉字编码
字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的big5。

GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。

GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区。汉字区包括21003个字符。2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。现在的PC平台必须支持GB18030,对嵌入式产品暂不作要求。所以手机、MP3一般只支持GB2312。

从ASCII、GB2312、GBK到GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK到GB18030都属于双字节字符集 (DBCS)。

有的中文Windows的缺省内码还是GBK,可以通过GB18030升级包升级到GB18030。不过GB18030相对GBK增加的字符,普通人是很难用到的,通常我们还是用GBK指代中文Windows内码。

这里还有一些细节:

GB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0。

在DBCS中,GB内码的存储格式始终是big endian,即高位在前。

GB2312的两个字节的最高位都是1。但符合这个条件的码位只有128*128=16384个。所以GBK和GB18030的低字节最高位都可能不是1。不过这不影响DBCS字符流的解析:在读取DBCS字符流时,只要遇到高位为1的字节,就可以将下两个字节作为一个双字节编码,而不用管低字节的高位是什么。

2、Unicode、UCS和UTF
前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。而Unicode只与ASCII兼容(更准确地说,是与ISO-8859-1兼容),与GB码不兼容。例如“汉”字的Unicode编码是6C49,而GB码是BABA。

Unicode也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。

根据维基百科全书( http://zh.wikipedia.org/wiki/ )的记载:历史上存在两个试图独立设计Unicode的组织,即国际标准化组织(ISO)和一个软件制造商的协会(unicode.org)。ISO开发了ISO 10646项目,Unicode协会开发了Unicode项目。

在1991年前后,双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode2.0开始,Unicode项目采用了与ISO 10646-1相同的字库和字码。

目前两个项目仍都存在,并独立地公布各自的标准。Unicode协会现在的最新版本是2005年的Unicode 4.1.0。ISO的最新标准是10646-3:2003。

UCS规定了怎么用多个字节表示各种文字。怎样传输这些编码,是由UTF(UCS Transformation Format)规范规定的,常见的UTF规范包括UTF-8、UTF-7、UTF-16。

IETF的RFC2781和RFC3629以RFC的一贯风格,清晰、明快又不失严谨地描述了UTF-16和UTF-8的编码方法。我总是记不得IETF是Internet Engineering Task Force的缩写。但IETF负责维护的RFC是Internet上一切规范的基础。

3、UCS-2、UCS-4、BMP

UCS有两种格式:UCS-2和UCS-4。顾名思义,UCS-2就是用两个字节编码,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码。下面让我们做一些简单的数学游戏:

UCS-2有2^16=65536个码位,UCS-4有2^31=2147483648个码位。

UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个plane。每个plane根据第3个字节分为256行 (rows),每行包含256个cells。当然同一行的cells只是最后一个字节不同,其余都相同。

group 0的plane 0被称作Basic Multilingual Plane, 即BMP。或者说UCS-4中,高两个字节为0的码位被称作BMP。

将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。而目前的UCS-4规范中还没有任何字符被分配在BMP之外。

4、UTF编码

UTF-8就是以8位为单元对UCS进行编码。从UCS-2到UTF-8的编码方式如下:

UCS-2编码(16进制) UTF-8 字节流(二进制)
0000 - 007F 0xxxxxxx
0080 - 07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx

例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 110001 001001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

读者可以用记事本测试一下我们的编码是否正确。

UTF-16以16位为单元对UCS进行编码。对于小于0x10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。对于不小于0x10000的UCS码,定义了一个算法。不过由于实际使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以认为UTF-16和UCS-2基本相同。但UCS-2只是一个编码方案,UTF-16却要用于实际的传输,所以就不得不考虑字节序的问题。

5、UTF的字节序和BOM
UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?

Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想法:

在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。

这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。

UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

Windows就是使用BOM来标记文本文件的编码方式的。

6、进一步的参考资料
本文主要参考的资料是 "Short overview of ISO-IEC 10646 and Unicode" (
http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html )。

我还找了两篇看上去不错的资料,不过因为我开始的疑问都找到了答案,所以就没有看:

"Understanding Unicode A general introduction to the Unicode Standard" ( http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter04a )
"Character set encoding basics Understanding character set encodings and legacy encodings" (
http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter03 )

posted @ 2006-09-28 11:06 xyang 阅读(212) | 评论 (0)编辑 收藏

    ie默认根据服务器传回来的contentType头进行显示(忽略mata标签),对于html这种静态文件,由于没有contentType头则根据<meta http-equiv="Content-Type" content="text/html; charset=GBK" />标签中的编码类型进行显示.

    pageEncoding指定的是jsp编译时的编码格式,必须对应于jsp文件内容的编码,否则是乱码
默认pageEncoding为:ISO-8859-1,如果不指定contentType,输出对应于pageEncoding的编码方式
也就是如果都不设置的话,默认输出ISO-8859-1,肯定是乱码(保存为unicode即可正常显示).

    response.setCharacterEncoding("GBK")
<%@ page contentType="text/html; charset=UTF-8">
这两句作用相同,设置输出的编码类型,但response.setCharacterEncoding("GBK")优先级高

    通过 get/post 方式从 ie中发送汉字,发送编码方式由Content-Type决定,request.getParameter("XX")得到的字符串是用ISO-8859-1表示的,所以必须在取值前用HttpServeletRequest.setCharacterEncoding 设置想得到的编码类型,或是在<Connector>中添加URIEncoding="GBK"属性,来获取正确的编码类型,但是,在执行setCharacterEncoding()之前,不能执行任何getParameter()。java doc上说明:This method must be called prior to reading request parameters or reading input using getReader()。而且,该指定只对POST方法有效,对GET方法无效。分析原因,应该是在执行第一个getParameter()的时候, java将会按照编码分析所有的提交内容,而后续的getParameter()不再进行分析,所以setCharacterEncoding()无效。 而对于GET方法提交表单是,提交的内容在URL中,一开始就已经按照编码分析所有的提交内容,setCharacterEncoding()自然就无效。



<% @ page contentType = " text/html; charset=UTF-8 "  pageEncoding = " UTF-8 " %>
<%
request.setCharacterEncoding(
" UTF-8 " );
response.setCharacterEncoding(
" UTF-8 " );
%>
< html >
  
< head >
    
< title > test </ title >
    
< meta  http-equiv ="Content-Type"  content ="text/html; charset=UTF-8"   />
  
</ head >
  
< body > = <% = new   String (request.getParameter( " foo " ).getBytes( " iso8859-1 " ), " UTF-8 " ) %> =
      
< form  action =""  method ="get" >
      foo = 
< input  type ="text"  name ="foo"  value ="${param[" foo"]}" >
          
< input  type ="submit" >
      
</ form >
      tomcat:
< Connector  port ="8080"  URIEncoding ="GBK"   />
  
</ body >
</ html >

posted @ 2006-09-28 09:47 xyang 阅读(376) | 评论 (0)编辑 收藏

作者:owen1944

一、字节和unicode

Java内核是unicode的,就连class文件也是,但是很多媒体,包括文件/流的保存方式是使用字节流的。因此Java要对这些字节流经行转化。char是unicode的,而byte是字节。Java中byte/char互转的函数在sun.io的包中间有。其中ByteToCharConverter类是中调度,可以用来告诉你,你用的convertor。其中两个很常用的静态函数是:

 

public static ByteToCharConverter getDefault();
public static ByteToCharConverter getConverter(String encoding);

 

如果你不指定converter,则系统会自动使用当前的encoding,gb平台上用gbk,en平台上用8859_1。


byte ——〉char:
"你"的gb码是:0xc4e3 ,unicode是0x4f60
String encoding = "gb2312";
byte b[] = {(byte)'\u00c4',(byte)'\u00e3'};
ByteToCharConverter converter = ByteToCharConverter.getConverter(encoding);
char c[] = converter.convertAll(b);
for (int i = 0; i < c.length; i++) {
System.out.println(Integer.toHexString(c[i]));
}
结果是什么?0x4f60
如果encoding ="8859_1",结果又是什么?0x00c4,0x00e3

 

如果代码改为:


byte b[] = {(byte)'\u00c4',(byte)'\u00e3'};
ByteToCharConverter converter = ByteToCharConverter. getDefault();
 char c[] = converter.convertAll(b);
 for (int i = 0; i < c.length; i++) {
    System.out.println(Integer.toHexString(c[i]));
 }

 

结果将又是什么?

这就要根据平台的编码而定。


char ——〉byte:
    String encoding = "gb2312";
    char c[] = {'\u4f60'};
    CharToByteConverter converter = CharToByteConverter.getConverter(encoding);
    byte b[] = converter.convertAll(c);
    for (int i = 0; i < b.length; i++) {
       System.out.println(Integer.toHexString(b[i]));
    }
结果是什么?0x00c4,0x00e3
如果encoding ="8859_1",结果又是什么?0x3f
如果代码改为
String encoding = "gb2312";
    char c[] = {'\u4f60'};
    CharToByteConverter converter = CharToByteConverter.getDefault();
    byte b[] = converter.convertAll(c);
    for (int i = 0; i < b.length; i++) {
       System.out.println(Integer.toHexString(b[i]));
    }

 

结果将又是什么?还是根据平台的编码而定。

很多中文问题就是从这两个最简单的类派生出来的。而却有很多类不直接支持把encoding输入,这给我们带来诸多不便。很多程序难得用encoding了,直接用default的encoding,这就给我们移植带来了很多困难。

二、utf-8

utf-8是和unicode一一对应的,其实现很简单:


7位的unicode: 0 _ _ _ _ _ _ _
11位的unicode: 1 1 0 _ _ _ _ _ 1 0 _ _ _ _ _ _
16位的unicode: 1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _
21位的unicode: 1 1 1 1 0 _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _

 

大多数情况是只使用到16位以下的unicode:


"你"的gb码是:0xc4e3 ,unicode是0x4f60
    0xc4e3的二进制:
          1100 ,0100 ,1110 ,0011

 

由于只有两位我们按照两位的编码来排,但是我们发现这行不通,因为第7位不是0因此,返回"?"


0x4f60的二进制:
               0100 ,1111 ,0110 ,0000
         我们用utf-8补齐,变成:
               1110 ,0100 ,1011 ,1101 ,1010 ,0000
         e4--bd-- a0
         于是返回:0xe4,0xbd,0xa0。

 

三、string和byte[]

string其实核心是char[],然而要把byte转化成string,必须经过编码。string.length()其实就是char数组的长度,如果使用不同的编码,很可能会错分,造成散字和乱码。例如:


String encoding = “”;
byte [] b={(byte)'\u00c4',(byte)'\u00e3'};
String str=new String(b,encoding);

 

如果encoding=8859_1,会有两个字,但是encoding=gb2312只有一个字这个问题在处理分页是经常发生。

四、Reader,Writer / InputStream,OutputStream

Reader和Writer核心是char,InputStream和OutputStream核心是byte。但是Reader和Writer的主要目的是要把char读/写InputStream/OutputStream。例如:


文件test.txt只有一个"你"字,0xc4,0xe3
String encoding = "gb2312";
    InputStreamReader reader = new InputStreamReader(new FileInputStream(
        "text.txt"), encoding);
    char c[] = new char[10];
    int length = reader.read(c);
    for (int i = 0; i < length; i++) {
       System.out.println(c[i]);
    }

 

结果是什么?是"你"。如果encoding ="8859_1",结果是什么?"??"两个字符,表示不认识。反过来的例子自己做。
五、我们要对Java的编译器有所了解:

 

 

 

 

 

 

Javac ?encoding

 

我们常常没有用到encoding这个参数。其实encoding这个参数对于跨平台的操作是很重要的。如果没有指定encoding,则按照系统的默认encoding,gb平台上是gb2312,英文平台上是iso8859_1。Java的编译器实际上是调用sun.tools.Javac.main的类,对文件进行编译,这个类有compile函数中间有一个encoding的变量,-encoding的参数其实直接传给encoding变量。编译器就是根据这个变量来读取Java文件的,然后把用utf-8形式编译成class文件。例子代码:


String str = "你";
    FileWriter writer = new FileWriter("text.txt");
    write.write(str);
    writer.close();

如果用gb2312编译,你会找到e4 bd a0的字段 ;
如果用8859_1编译, 00c4 00e3的二进制:
0000,0000 ,1100,0100 ,0000,0000 ,1110,0011
因为每个字符都大于7位,因此用11位编码:
1100,0001,1000,0100,1100,0011,1010,0011
c1-- 84-- c3--  a3
你会找到c1 84 c3 a3

 

但是我们往往忽略掉这个参数,因此这样往往会有跨平台的问题:

样例代码在中文平台上编译,生成zhclass

样例代码在英文平台上编译,输出enclass

(1) zhclass在中文平台上执行ok,但是在英文平台上不行

(2) enclass在英文平台上执行ok,但是在中文平台上不行

原因是:

(1) 在中文平台上编译后,其实str在运行态的char[]是0x4f60, 在中文平台上运行,filewriter的缺省编码是gb2312,因此chartobyteconverter会自动用调用gb2312的converter,把str转化成byte输入到fileoutputstream中,于是0xc4,0xe3放进了文件。但是如果是在英文平台下,chartobyteconverter的缺省值是8859_1, filewriter会自动调用8859_1去转化str,但是他无法解释,因此他会输出"?"

(2) 在英文平台上编译后,其实str在运行态的char[]是0x00c4 0x00e3, 在中文平台上运行,中文无法识别,因此会出现??;在英文平台上,0x00c4-->0xc4,0x00e3->0xe3,因此0xc4,0xe3被放进了文件。

六、其它原因:


<%@ page contentType="text/html; charset=GBK" %>

 

设置浏览器的显示编码,如果response的数据是utf8编码,显示将是乱码,但是乱码和上述原因还不一样。

七、发生编码的地方:

1. 从数据库到Java程序 byte——〉char

2. 从Java程序到数据库 char——〉byte

3. 从文件到Java程序 byte——〉char

4. 从Java程序到文件 char——〉byte

5. 从Java程序到页面显示 char——〉byte

6. 从页面form提交数据到Java程序byte——〉char

7. 从流到Java程序byte——〉char

8. 从Java程序到流char——〉byte

可以使用配置过滤器的方法解决中文乱码的:


<web-app>
  <filter>
    <filter-name>RequestFilter</filter-name>
    <filter-class>net.golden.uirs.util.RequestFilter</filter-class>
    <init-param>
      <param-name>charset</param-name>
      <param-value>gb2312</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>RequestFilter</filter-name>
    <url-pattern>*.Jsp</url-pattern>
  </filter-mapping>
</web-app>


  public void doFilter(ServletRequest req, ServletResponse res,
                       FilterChain fChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    HttpSession session = request.getSession();
    String userId = (String) session.getAttribute("userid");
req.setCharacterEncoding(this.filterConfig.getInitParameter("charset"));
// 设置字符集?
实际上是设置了byte ——〉char的encoding
    try {
      if (userId == null || userId.equals("")) {
        if (!request.getRequestURL().toString().matches(
            ".*/uirs/logon/logon(Controller){0,1}\\x2EJsp$")) {
          session.invalidate();
          response.sendRedirect(request.getContextPath() +
                                "/uirs/logon/logon.Jsp");
        }
      }
      else {
   // 看看是否具有信息上报系统的权限
        if (!net.golden.uirs.util.UirsChecker.check(userId, "信息上报系统",
            net.golden.uirs.util.UirsChecker.ACTION_DO)) {
          if (!request.getRequestURL().toString().matches(
              ".*/uirs/logon/logon(Controller){0,1}\\x2EJsp$")) {
            response.sendRedirect(request.getContextPath() +
                                  "/uirs/logon/logonController.Jsp");
          }
        }
      }
    }
    catch (Exception ex) {
      response.sendRedirect(request.getContextPath() +
                            "/uirs/logon/logon.Jsp");
    }
    fChain.doFilter(req, res);
  }

 

 

posted @ 2006-09-28 00:27 xyang 阅读(146) | 评论 (0)编辑 收藏

1. 概述

本文主要包括以下几个方面:编码基本知识,java,系统软件,url,工具软件等。

在下面的描述中,将以"中文"两个字为例,经查表可以知道其GB2312编码是"d6d0 cec4",Unicode编码为"4e2d 6587",UTF编码就是"e4b8ad e69687"。注意,这两个字没有iso8859-1编码,但可以用iso8859-1编码来"表示"。

2. 编码基本知识

最早的编码是iso8859-1,和ascii编码相似。但为了方便表示各种各样的语言,逐渐出现了很多标准编码,重要的有如下几个。

2.1. iso8859-1

属于单字节编码,最多能表示的字符范围是0-255,应用于英文系列。比如,字母'a'的编码为0x61=97。

很明显,iso8859-1编码表示的字符范围很窄,无法表示中文字符。但是,由于是单字节编码,和计算机最基础的表示单位一致,所以很多时候,仍旧使用 iso8859-1编码来表示。而且在很多协议上,默认使用该编码。比如,虽然"中文"两个字不存在iso8859-1编码,以gb2312编码为例,应 该是"d6d0 cec4"两个字符,使用iso8859-1编码的时候则将它拆开为4个字节来表示:"d6 d0 ce c4"(事实上,在进行存储的时候,也是以字节为单位处理的)。而如果是UTF编码,则是6个字节"e4 b8 ad e6 96 87"。很明显,这种表示方法还需要以另一种编码为基础。

2.2. GB2312/GBK

这就是汉子的国标码,专门用来表示汉字,是双字节编码,而英文字母和iso8859-1一致(兼容iso8859-1编码)。其中gbk编码能够用来同时表示繁体字和简体字,而gb2312只能表示简体字,gbk是兼容gb2312编码的。

2.3. unicode

这是最统一的编码,可以用来表示所有语言的字符,而且是定长双字节(也有四字节的)编码,包括英文字母在内。所以可以说它是不兼容iso8859-1编码 的,也不兼容任何编码。不过,相对于iso8859-1编码来说,uniocode编码只是在前面增加了一个0字节,比如字母'a'为"00 61"。

需要说明的是,定长编码便于计算机处理(注意GB2312/GBK不是定长编码),而unicode又可以用来表示所有字符,所以在很多软件内部是使用unicode编码来处理的,比如java。

2.4. UTF

考虑到unicode编码不兼容iso8859-1编码,而且容易占用更多的空间:因为对于英文字母,unicode也需要两个字节来表示。所以 unicode不便于传输和存储。因此而产生了utf编码,utf编码兼容iso8859-1编码,同时也可以用来表示所有语言的字符,不过,utf编码 是不定长编码,每一个字符的长度从1-6个字节不等。另外,utf编码自带简单的校验功能。一般来讲,英文字母都是用一个字节表示,而汉字使用三个字节。

注意,虽然说utf是为了使用更少的空间而使用的,但那只是相对于unicode编码来说,如果已经知道是汉字,则使用GB2312/GBK无疑是最节省 的。不过另一方面,值得说明的是,虽然utf编码对汉字使用3个字节,但即使对于汉字网页,utf编码也会比unicode编码节省,因为网页中包含了很 多的英文字符。

3. java对字符的处理

在java应用软件中,会有多处涉及到字符集编码,有些地方需要进行正确的设置,有些地方需要进行一定程度的处理。

3.1. getBytes(charset)

这是java字符串处理的一个标准函数,其作用是将字符串所表示的字符按照charset编码,并以字节方式表示。注意字符串在java内存中总是按unicode编码存储的。比如"中文",正常情况下(即没有错误的时候)存储为"4e2d 6587",如果charset为"gbk",则被编码为"d6d0 cec4",然后返回字节"d6 d0 ce c4"。如果charset为"utf8"则最后是"e4 b8 ad e6 96 87"。如果是"iso8859-1",则由于无法编码,最后返回 "3f 3f"(两个问号)。

3.2. new String(charset)

这是java字符串处理的另一个标准函数,和上一个函数的作用相反,将字节数组按照charset编码进行组合识别,最后转换为unicode存储。参考上述getBytes的例子,"gbk" 和"utf8"都可以得出正确的结果"4e2d 6587",但iso8859-1最后变成了"003f 003f"(两个问号)。

因为utf8可以用来表示/编码所有字符,所以new String( str.getBytes( "utf8" ), "utf8" ) === str,即完全可逆。

3.3. setCharacterEncoding()

该函数用来设置http请求或者相应的编码。

对于request,是指提交内容 的编码,指定后可以通过getParameter()则直接获得正确的字符串,如果不指定,则默认使用iso8859-1编码,需要进一步处理。参见下述 "表单输入"。值得注意的是在执行setCharacterEncoding()之前,不能执行任何getParameter()。java doc上说明:This method must be called prior to reading request parameters or reading input using getReader()。而且,该指定只对POST方法有效,对GET方法无效。分析原因,应该是在执行第一个getParameter()的时候, java将会按照编码分析所有的提交内容,而后续的getParameter()不再进行分析,所以setCharacterEncoding()无效。 而对于GET方法提交表单是,提交的内容在URL中,一开始就已经按照编码分析所有的提交内容,setCharacterEncoding()自然就无 效。

对于response,则是指定输出内容的编码,同时,该设置会传递给浏览器,告诉浏览器输出内容所采用的编码。

3.4. 处理过程

下面分析两个有代表性的例子,说明java对编码有关问题的处理方法。

3.4.1. 表单输入

User input  *(gbk:d6d0 cec4)  browser  *(gbk:d6d0 cec4)  web server  iso8859-1(00d6 00d 000ce 00c4)  class,需要在class中进行处理:getbytes("iso8859-1")为d6 d0 ce c4,new String("gbk")为d6d0 cec4,内存中以unicode编码则为4e2d 6587

l 用户输入的编码方式和页面指定的编码有关,也和用户的操作系统有关,所以是不确定的,上例以gbk为例。

l 从browser到web server,可以在表单中指定提交内容时使用的字符集,否则会使用页面指定的编码。而如果在url中直接用?的方式输入参数,则其编码往往是操作系统本身的编码,因为这时和页面无关。上述仍旧以gbk编码为例。

l Web server接收到的是字节流,默认时(getParameter)会以iso8859-1编码处理之,结果是不正确的,所以需要进行处理。但如果预先设 置了编码(通过request. setCharacterEncoding ()),则能够直接获取到正确的结果。

l 在页面中指定编码是个好习惯,否则可能失去控制,无法指定正确的编码。

3.4.2. 文件编译

假设文件是gbk编码保存的,而编译有两种编码选择:gbk或者iso8859-1,前者是中文windows的默认编码,后者是linux的默认编码,当然也可以在编译时指定编码。

Jsp  *(gbk:d6d0 cec4)  java file  *(gbk:d6d0 cec4)  compiler read  uincode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4)  compiler write  utf(gbk: e4b8ad e69687; iso8859-1: *)  compiled file  unicode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4)  class。所以用gbk编码保存,而用iso8859-1编译的结果是不正确的。

class  unicode(4e2d 6587)  system.out / jsp.out  gbk(d6d0 cec4)  os console / browser。

l 文件可以以多种编码方式保存,中文windows下,默认为ansi/gbk。

l 编译器读取文件时,需要得到文件的编码,如果未指定,则使用系统默认编码。一般class文件,是以系统默认编码保存的,所以编译不会出问题,但对于 jsp文件,如果在中文windows下编辑保存,而部署在英文linux下运行/编译,则会出现问题。所以需要在jsp文件中用 pageEncoding指定编码。

l Java编译的时候会转换成统一的unicode编码处理,最后保存的时候再转换为utf编码。

l 当系统输出字符的时候,会按指定编码输出,对于中文windows下,System.out将使用gbk编码,而对于response(浏览器),则使用 jsp文件头指定的contentType,或者可以直接为response指定编码。同时,会告诉browser网页的编码。如果未指定,则会使用 iso8859-1编码。对于中文,应该为browser指定输出字符串的编码。

l browser显示网页的时候,首先使用response中指定的编码(jsp文件头指定的contentType最终也反映在response上),如果未指定,则会使用网页中meta项指定中的contentType。

3.5. 几处设置

对于web应用程序,和编码有关的设置或者函数如下。

3.5.1. jsp编译

指定文件的存储编码,很明显,该设置应该置于文件的开头。例如:<%@page pageEncoding="GBK"%>。另外,对于一般class文件,可以在编译的时候指定编码。

3.5.2. jsp输出

指定文件输出到browser是使 用的编码,该设置也应该置于文件的开头。例如:<%@ page contentType="text/html; charset= GBK" %>。该设置和response.setCharacterEncoding("GBK")等效。

3.5.3. meta设置

指定网页使用的编码,该设置对静态 网页尤其有作用。因为静态网页无法采用jsp的设置,而且也无法执行response.setCharacterEncoding()。例如:< META http-equiv="Content-Type" content="text/html; charset=GBK" />

如果同时采用了jsp输出和meta设置两种编码指定方式,则jsp指定的优先。因为jsp指定的直接体现在response中。

需要注意的是,apache有一个设置可以给无编码指定的网页指定编码,该指定等同于jsp的编码指定方式,所以会覆盖静态网页中的meta指定。所以有人建议关闭该设置。

3.5.4. form设置

当浏览器提交表单的时候,可以指定相应的编码。例如:<form accept-charset= "gb2312">。一般不必不使用该设置,浏览器会直接使用网页的编码。

4. 系统软件

下面讨论几个相关的系统软件。

4.1. mysql数据库

很明显,要支持多语言,应该将数据库的编码设置成utf或者unicode,而utf更适合与存储。但是,如果中文数据中包含的英文字母很少,其实unicode更为适合。

数据库的编码可以通过mysql的 配置文件设置,例如default-character-set=utf8。还可以在数据库链接URL中设置,例如: useUnicode=true&characterEncoding=UTF-8。注意这两者应该保持一致,在新的sql版本里,在数据库链接 URL里可以不进行设置,但也不能是错误的设置。

4.2. apache

appache和编码有关的配置在httpd.conf中,例如AddDefaultCharset UTF-8。如前所述,该功能会将所有静态页面的编码设置为UTF-8,最好关闭该功能。

另外,apache还有单独的模块来处理网页响应头,其中也可能对编码进行设置。

4.3. linux默认编码

这里所说的linux默认编码,是指运行时的环境变量。两个重要的环境变量是LC_ALL和LANG,默认编码会影响到java URLEncode的行为,下面有描述。

建议都设置为"zh_CN.UTF-8"。

4.4. 其它

为了支持中文文件名,linux在加载磁盘时应该指定字符集,例如:mount /dev/hda5 /mnt/hda5/ -t ntfs -o iocharset=gb2312。

另外,如前所述,使用GET方法提 交的信息不支持request.setCharacterEncoding(),但可以通过tomcat的配置文件指定字符集,在tomcat的 server.xml文件中,形如:<Connector ... URIEncoding="GBK"/>。这种方法将统一设置所有请求,而不能针对具体页面进行设置,也不一定和browser使用的编码相同,所 以有时候并不是所期望的。

5. URL地址

URL地址中含有中文字符是很麻烦的,前面描述过使用GET方法提交表单的情况,使用GET方法时,参数就是包含在URL中。

5.1. URL编码

对于URL中的一些特殊字符,浏览器会自动进行编码。这些字符除了"/?&"等外,还包括unicode字符,比如汉子。这时的编码比较特殊。

IE有一个选项"总是使用UTF- 8发送URL",当该选项有效时,IE将会对特殊字符进行UTF-8编码,同时进行URL编码。如果改选项无效,则使用默认编码"GBK",并且不进行 URL编码。但是,对于URL后面的参数,则总是不进行编码,相当于UTF-8选项无效。比如"中文.html?a=中文",当UTF-8选项有效时,将 发送链接"%e4%b8%ad%e6%96%87.html?a=\x4e\x2d\x65\x87";而UTF-8选项无效时,将发送链接"\x4e\x2d\x65\x87.html?a=\x4e\x2d\x65\x87"。注意后者前面的"中文"两个字只有4个字节,而前者却有18个字节,这主要时URL编码的原因。

当web server(tomcat)接收到该链接时,将会进行URL解码,即去掉"%",同时按照ISO8859-1编码(上面已经描述,可以使用URLEncoding来设置成其它编码)识别。上述例子的结果分别是"\ue4\ub8\uad\ue6\u96\u87.html?a=\u4e\u2d\u65\u87"和"\u4e\u2d\u65\u87.html?a=\u4e\u2d\u65\u87",注意前者前面的"中文"两个字恢复成了6个字符。这里用"\u",表示是unicode。

所以,由于客户端设置的不同,相同的链接,在服务器上得到了不同结果。这个问题不少人都遇到,却没有很好的解决办法。所以有的网站会建议用户尝试关闭UTF-8选项。不过,下面会描述一个更好的处理办法。

5.2. rewrite

熟悉的人都知道,apache有一个功能强大的rewrite模块,这里不描述其功能。需要说明的是该模块会自动将URL解码(去除%),即完成上述 web server(tomcat)的部分功能。有相关文档介绍说可以使用[NE]参数来关闭该功能,但我试验并未成功,可能是因为版本(我使用的是 apache 2.0.54)问题。另外,当参数中含有"?& "等符号的时候,该功能将导致系统得不到正常结果。

rewrite本身似乎完全是采用字节处理的方式,而不考虑字符串的编码,所以不会带来编码问题。

5.3. URLEncode.encode()

这是Java本身提供对的URL编码函数,完成的工作和上述UTF-8选项有效时浏览器所做的工作相似。值得说明的是,java已经不赞成不指定编码来使用该方法(deprecated)。应该在使用的时候增加编码指定。

当不指定编码的时候,该方法使用系统默认编码,这会导致软件运行结果得不确定。比如对于"中文",当系统默认编码为"gb2312"时,结果是"%4e%2d%65%87",而默认编码为"UTF-8",结果却是"%e4%b8%ad%e6%96%87",后续程序将难以处理。另外,这儿说的系统默认编码是由运行tomcat时的环境变量LC_ALL和LANG等决定的,曾经出现过tomcat重启后就出现乱码的问题,最后才郁闷的发现是因为修改修改了这两个环境变量。

建议统一指定为"UTF-8"编码,可能需要修改相应的程序。

5.4. 一个解决方案

上面说起过,因为浏览器设置的不同,对于同一个链接,web server收到的是不同内容,而软件系统有无法知道这中间的区别,所以这一协议目前还存在缺陷。

针对具体问题,不应该侥幸认为所有客户的IE设置都是UTF-8有效的,也不应该粗暴的建议用户修改IE设置,要知道,用户不可能去记住每一个web server的设置。所以,接下来的解决办法就只能是让自己的程序多一点智能:根据内容来分析编码是否UTF-8。

比较幸运的是UTF-8编码相当有规律,所以可以通过分析传输过来的链接内容,来判断是否是正确的UTF-8字符,如果是,则以UTF-8处理之,如果不是,则使用客户默认编码(比如"GBK"),下面是一个判断是否UTF-8的例子,如果你了解相应规律,就容易理解。

public static boolean isValidUtf8(byte[] b,int aMaxCount){

       int lLen=b.length,lCharCount=0;

       for(int i=0;i<lLen && lCharCount<aMaxCount;++lCharCount){

              byte lByte=b[i++];//to fast operation, ++ now, ready for the following for(;;)

              if(lByte>=0) continue;//>=0 is normal ascii

              if(lByte<(byte)0xc0 || lByte>(byte)0xfd) return false;

              int lCount=lByte>(byte)0xfc?5:lByte>(byte)0xf8?4

                     :lByte>(byte)0xf0?3:lByte>(byte)0xe0?2:1;

              if(i+lCount>lLen) return false;

              for(int j=0;j<lCount;++j,++i) if(b[i]>=(byte)0xc0) return false;

       }

       return true;

}

相应地,一个使用上述方法的例子如下:

public static String getUrlParam(String aStr,String aDefaultCharset)

throws UnsupportedEncodingException{

       if(aStr==null) return null;

       byte[] lBytes=aStr.getBytes("ISO-8859-1");

       return new String(lBytes,StringUtil.isValidUtf8(lBytes)?"utf8":aDefaultCharset);

}

不过,该方法也存在缺陷,如下两方面:

l 没有包括对用户默认编码的识别,这可以根据请求信息的语言来判断,但不一定正确,因为我们有时候也会输入一些韩文,或者其他文字。

l 可能会错误判断UTF-8字符,一个例子是"学习"两个字,其GBK编码是" \xd1\xa7\xcf\xb0",如果使用上述isValidUtf8方法判断,将返回true。可以考虑使用更严格的判断方法,不过估计效果不大。

有一个例子可以证明google也遇到了上述问题,而且也采用了和上述相似的处理方法,比如,如果在地址栏中输入" http://www.google.com/search?hl=zh-CN&newwindow=1&q=学习 ",google将无法正确识别,而其他汉字一般能够正常识别。

最后,应该补充说明一下,如果不使用rewrite规则,或者通过表单提交数据,其实并不一定会遇到上述问题,因为这时可以在提交数据时指定希望的编码。另外,中文文件名确实会带来问题,应该谨慎使用。

6. 其它

下面描述一些和编码有关的其他问题。

6.1. SecureCRT

除了浏览器和控制台与编码有关外,一些客户端也很有关系。比如在使用SecureCRT连接linux时,应该让SecureCRT的显示编码(不同的session,可以有不同的编码设置)和linux的编码环境变量保持一致。否则看到的一些帮助信息,就可能是乱码。

另外,mysql有自己的编码设置,也应该保持和SecureCRT的显示编码一致。否则通过SecureCRT执行sql语句的时候,可能无法处理中文字符,查询结果也会出现乱码。

对于Utf-8文件,很多编辑器 (比如记事本)会在文件开头增加三个不可见的标志字节,如果作为mysql的输入文件,则必须要去掉这三个字符。(用linux的vi保存可以去掉这三个 字符)。一个有趣的现象是,在中文windows下,创建一个新txt文件,用记事本打开,输入"连通"两个字,保存,再打开,你会发现两个字没了,只留 下一个小黑点。

6.2. 过滤器

如果需要统一设置编码,则通过 filter进行设置是个不错的选择。在filter class中,可以统一为需要的请求或者回应设置编码。参加上述setCharacterEncoding()。这个类apache已经给出了可以直接使 用的例子SetCharacterEncodingFilter。

6.3. POST和GET

很明显,以POST提交信息时,URL有更好的可读性,而且可以方便的使用setCharacterEncoding()来处理字符集问题。但GET方法形成的URL能够更容易表达网页的实际内容,也能够用于收藏。

从统一的角度考虑问题,建议采用 GET方法,这要求在程序中获得参数是进行特殊处理,而无法使用setCharacterEncoding()的便利,如果不考虑rewrite,就不存 在IE的UTF-8问题,可以考虑通过设置URIEncoding来方便获取URL中的参数。

6.4. 简繁体编码转换

GBK同时包含简体和繁体编码,也 就是说同一个字,由于编码不同,在GBK编码下属于两个字。有时候,为了正确取得完整的结果,应该将繁体和简体进行统一。可以考虑将UTF、GBK中的所 有繁体字,转换为相应的简体字,BIG5编码的数据,也应该转化成相应的简体字。当然,仍旧以UTF编码存储。

例如,对于"语言 語言",用UTF表示为"\xE8\xAF\xAD\xE8\xA8\x80 \xE8\xAA\x9E\xE8\xA8\x80",进行简繁体编码转换后应该是两个相同的 "\xE8\xAF\xAD\xE8\xA8\x80>"。

posted @ 2006-09-28 00:25 xyang 阅读(196) | 评论 (0)编辑 收藏

算法常用术语中英对照

Data Structures 基本数据结构
Dictionaries 字典
Priority Queues 堆
Graph Data Structures 图
Set Data Structures 集合
Kd-Trees 线段树
Numerical Problems 数值问题
Solving Linear Equations 线性方程组
Bandwidth Reduction 带宽压缩
Matrix Multiplication 矩阵乘法
Determinants and Permanents 行列式
Constrained and Unconstrained Optimization 最值问题
Linear Programming 线性规划
Random Number Generation 随机数生成
Factoring and Primality Testing 因子分解/质数判定
Arbitrary Precision Arithmetic 高精度计算
Knapsack Problem 背包问题
Discrete Fourier Transform 离散Fourier变换
Combinatorial Problems 组合问题
Sorting 排序
Searching 查找
Median and Selection 中位数
Generating Permutations 排列生成
Generating Subsets 子集生成
Generating Partitions 划分生成
Generating Graphs 图的生成
Calendrical Calculations 日期
Job Scheduling 工程安排
Satisfiability 可满足性
Graph Problems -- polynomial 图论-多项式算法
Connected Components 连通分支
Topological Sorting 拓扑排序
Minimum Spanning Tree 最小生成树
Shortest Path 最短路径
Transitive Closure and Reduction 传递闭包
Matching 匹配
Eulerian Cycle / Chinese Postman Euler回路/中国邮路
Edge and Vertex Connectivity 割边/割点
Network Flow 网络流
Drawing Graphs Nicely 图的描绘
Drawing Trees 树的描绘
Planarity Detection and Embedding 平面性检测和嵌入
Graph Problems -- hard 图论-NP问题
Clique 最大团
Independent Set 独立集
Vertex Cover 点覆盖
Traveling Salesman Problem 旅行商问题
Hamiltonian Cycle Hamilton回路
Graph Partition 图的划分
Vertex Coloring 点染色
Edge Coloring 边染色
Graph Isomorphism 同构
Steiner Tree Steiner树
Feedback Edge/Vertex Set 最大无环子图
Computational Geometry 计算几何
Convex Hull 凸包
Triangulation 三角剖分
Voronoi Diagrams Voronoi图
Nearest Neighbor Search 最近点对查询
Range Search 范围查询
Point Location 位置查询
Intersection Detection 碰撞测试
Bin Packing 装箱问题
Medial-Axis Transformation 中轴变换
Polygon Partitioning 多边形分割
Simplifying Polygons 多边形化简
Shape Similarity 相似多边形
Motion Planning 运动规划
Maintaining Line Arrangements 平面分割
Minkowski Sum Minkowski和
Set and String Problems 集合与串的问题
Set Cover 集合覆盖
Set Packing 集合配置
String Matching 模式匹配
Approximate String Matching 模糊匹配
Text Compression 压缩
Cryptography 密码
Finite State Machine Minimization 有穷自动机简化
Longest Common Substring 最长公共子串
Shortest Common Superstring 最短公共父串
DP——Dynamic Programming——动态规划
recursion —— 递归

编程词汇
A2A integration  A2A整合       
abstract   抽象的        
abstract base class (ABC)抽象基类
abstract class 抽象类
abstraction 抽象、抽象物、抽象性
access 存取、访问
access level访问级别
access function  访问函数
account  账户
action   动作
activate 激活
active   活动的
actual parameter  实参
adapter 适配器
add-in  插件
address 地址
address space     地址空间
address-of operator 取地址操作符
ADL (argument-dependent lookup)
ADO(ActiveX Data Object)ActiveX数据对象
advanced    高级的
aggregation 聚合、聚集
algorithm 算法
alias 别名
align 排列、对齐
allocate 分配、配置
allocator分配器、配置器
angle bracket 尖括号
annotation   注解、评注
API (Application Programming Interface) 应用(程序)编程接口
app domain (application domain)应用域
application  应用、应用程序
application framework 应用程序框架
appearance 外观
append     附加
architecture 架构、体系结构
archive file 归档文件、存档文件
argument引数(传给函式的值)。参见parameter          
array   数组
arrow operator  箭头操作符
ASP(Active Server Page)活动服务器页面
ASP.NET worker process ASP.NET工作者进程
assembly     装配件、配件
assembly language   汇编语言
assembly manifest   装配件清单
assert(ion) 断言
assign      赋值
assignment  赋值、分配
assignment operator 赋值操作符
associated  相关的、相关联的
associative container 关联式容器(对应sequential container)        
asynchronous  异步的
atomic    原子的
atomic operation   原子操作
attribute   特性、属性
authentication service 验证服务
authorization  授权
audio   音频
A.I.    人工智能
B2B integration  B2B整合、B2B集成(business-to-business integration)        
background   背景、后台(进程)
backward compatible    向后兼容、向下兼容
backup   备份
backup device备份设备
backup file  备份文件
bandwidth  带宽
base class 基类
base type  基类型
batch   批处理
BCL (base class library)基类库
binary  二进制  
binary search 二分查找
binary tree 二叉树
binary function  双参函数
binary large object二进制大对象
binary operator 二元操作符
binding 绑定
bit 位
bitmap  位图
bitwise 按位...
bitwise copy       为单元进行复制;位元逐一复制,按位拷
bitwise operation  按位运算
block  块、区块、语句块
bookkeeping  簿记
boolean 布林值(真假值,true或false)                 
border  边框
bounds checking 边界检查
boxing  装箱、装箱转换
brace (curly brace) 大括号、花括号
bracket (square brakcet) 中括号、方括号
breakpoint 断点
browser applications  浏览器应用(程序)
browser-accessible application  可经由浏览器访问的应用程序
build  编连(专指编译和连接
built-in  内建、内置
bus  总线
business  业务、商务(看场合)
business Logic 业务逻辑
business rules 业务规则
buttons  按钮
bug  臭虫
by/through 通过
byte  位元组(由8 bits组成)   
cache 高速缓存
calendar 日历
call 调用
callback  回调
call-level interface (CLI)调用级接口(CLI)
call operator 调用操作符
candidate key 候选键 (for database)
cascading delete 级联删除 (for database)
cascading update 级联更新 (for database)
casting   转型、造型转换
catalog   目录
chain     链(function calls)
character 字符
character format  字符格式
character set     字符集
CHECK constraints CHECK约束 (for database)
checkpoint 检查点 (for database)
check box  复选框
check button 复选按钮
child class  子类
CIL (common intermediate language)通用中间语言、通用中介语言
class    类
class declaration  类声明
class definition   类定义
class derivation list 类继承列表
class factory    类厂
class hierarchy  类层次结构
class library    类库
class loader     类装载器
class template   类模板
class template partial specializations 类模板部分特化
class template specializations         类模板特化
classification  分类
clause  子句
client application  客户端应用程序
client cursor  客户端游标 (for database)
code page 代码页
cleanup   清理、清除
CLI (Common Language Infrastructure)   通用语言基础设施
client 客户、客户端
client area  客户区
client-server 客户机/服务器、客户端/服务器
clipboard 剪贴板
clone  克隆
CLS (common language specification) 通用语言规范
code access security  代码访问安全
COFF (Common Object File Format)    通用对象文件格式
collection  集合
COM (Component Object Model)  组件对象模型
combo box 组合框
command line 命令行
comment  注释
commit   提交 (for database)
communication  通讯
compatible 兼容
compile time 编译期、编译时
compiler 编译器
component组件
composite index 复合索引、组合索引 (for database)
composite key 复合键、组合键 (for database)
composition   复合、组合
concept 概念
concrete具体的
concrete class  具体类
concurrency 并发、并发机制
constraint  约束 (for database)
configuration 配置、组态
connection    连接 (for database)
connection pooling 连接池
console    控制台
constant   常量
construct  构件、成分、概念、构造(for language)
constructor (ctor) 构造函数、构造器
container  容器
containment包容
context 环境、上下文
control 控件
cookie  (不译)
copy    拷贝
CORBA   通用对象请求中介架构(Common Object Request Broker Architecture)
cover   覆盖、涵盖
create/creation    创建、生成
crosstab query     交叉表查询 (for database)
CRTP (curiously recurring template pattern)
CTS (common type system)通用类型系统
cube   多维数据集 (for database)
cursor 光标
cursor 游标 (for database)
custom 定制、自定义
data   数据
data connection   数据连接 (for database)
Data Control Language (DCL)  数据控制语言(DCL) (for database)
Data Definition Language (DDL) 数据定义语言(DDL) (for database)
data dictionary 数据字典 (for database)
data dictionary view  数据字典视图 (for database)
data file  数据文件 (for database)
data integrity  数据完整性 (for database)
data manipulation language (DML)数据操作语言(DML) (for database)
data mart  数据集市 (for database)
data pump  数据抽取 (for database)
data scrubbing  数据清理 (for database)
data source     数据源 (for database)
Data source name (DSN) 数据源名称(DSN) (for database)
data warehouse    数据仓库 (for database)
dataset   数据集 (for database)
database  数据库 (for database)
database catalog  数据库目录 (for database)
database diagram  数据关系图 (for database)
database file     数据库文件 (for database)
database object   数据库对象 (for database)
database owner    数据库所有者 (for database)
database project  数据库工程 (for database)
database role     数据库角色 (for database)
database schema  数据库模式、数据库架构 (for database)
database script  数据库脚本 (for database)
data-bound       数据绑定 (for database)
data-aware control数据感知控件 (for database)
data member   数据成员、成员变量
dataset       数据集 (for database)
data source   数据源 (for database)
data structure数据结构
data table    数据表 (for database)
datagram    数据报文
DBMS (database management system)数据库管理系统 (for database)
DCOM (distributed COM)分布式COM
dead lock  死锁 (for database)
deallocate 归还
debug      调试
debugger   调试器
decay      退化
decision support 决策支持
declaration 声明
declarative referential integrity (DRI)声明引用完整性(DRI) (for database)
deduction  推导
DEFAULT constraint默认约束 (for database)
default database  默认数据库 (for database)
default instance  默认实例 (for database)
default result set 默认结果集 (for database)
default     缺省、默认值
defer       推迟
definition  定义
delegate    委托
delegation  委托
dependent name      
deploy       部署
dereference  解引用
dereference operator (提领)运算子                     
derived class  派生类
design by contract 契约式设计
design pattern  设计模式
destroy   销毁
destructor(dtor)析构函数、析构器
device   设备
DHTML (dynamic HyperText Markup Language)动态超文本标记语言
dialog   对话框
digest   摘要
digital  数字的
DIME (Direct Internet Message Encapsulation)直接Internet消息封装
directive  (编译)指示符
directory  目录
dirty pages脏页 (for database)
dirty read 脏读 (for database)
disassembler 反汇编器
DISCO (Discovery of Web Services)Web Services的查找
disk  盘
dispatch 调度、分派、派发(我喜欢“调度”)
DISPID (Dispatch Identifier)分派标识符
distributed computing 分布式计算
distributed query     分布式查询 (for database)
DNA (Distributed interNet Application) 分布式网间应用程序
document 文档
DOM (Document Object Model)文档对象模型
dot operator  (圆)点操作符
driver 驱动(程序)
DTD (document type definition)  文档类型定义
double-byte character set (DBCS)双字节字符集(DBCS)
dump       转储
dump file  转储文件
dynamic cursor    动态游标 (for database)
dynamic filter    动态筛选 (for database)
dynamic locking   动态锁定 (for database)
dynamic recovery  动态恢复 (for database)
dynamic snapshot  动态快照 (for database)
dynamic SQL statements 动态SQL语句 (for database)
dynamic assembly 动态装配件、动态配件
dynamic binding  动态绑定
EAI (enterprise application integration)企业应用程序集成(整合)
EBCO (empty base class optimization)   空基类优化(机制)
e-business   电子商务
EDI (Dlectronic Data Interchange)电子数据交换
efficiency 效率
efficient  高效
end-to-end authentication 端对端身份验证
end user 最终用户
engine   引擎
entity  实体
encapsulation   封装
enclosing class 外围类别(与巢状类别 nested class有关)
enum (enumeration) 枚举
enumerators 枚举成员、枚举器
equal       相等
equality    相等性
equality operator  等号操作符
error log   错误日志 (for database)
escape code 转义码
escape character 转义符、转义字符
exclusive lock   排它锁 (for database)
explicit transaction 显式事务 (for database)
evaluate 评估
event    事件
event driven  事件驱动的
event handler 事件处理器
evidence  证据
exception 异常
exception declaration 异常声明
exception handling 异常处理、异常处理机制
exception-safe 异常安全的
exception specification 异常规范
exit     退出
explicit 显式
explicit specialization  显式特化
export      导出
expression  表达式
facility    设施、设备
fat client  胖客户端
feature     特性、特征
fetch 提取
field 字段(java)
field 字段 (for database)
field length 字段长度 (for database)
file   文件
filter 筛选 (for database)
finalization 终结
firewall  防火墙
finalizer 终结器
firmware 固件
flag     标记
flash memory 闪存
flush 刷新
font  字体
foreign key (FK)  外键(FK) (for database)
form   窗体
formal parameter  形参
forward declaration  前置声明
forward-only  只向前的
forward-only cursor  只向前游标 (for database)
fragmentation 碎片 (for database)
framework  框架
full specialization  完全特化
function  函数
function call operator (即operator ()) 函数调用操作符
function object 函数对象
function overloaded resolution函数重载决议
functionality    功能
function template函数模板
functor  仿函数
GAC (global assembly cache) 全局装配件缓存、全局配件缓存
GC (Garbage collection)     垃圾回收(机制)、垃圾收集(机制)
game     游戏
generate 生成
generic  泛化的、一般化的、通用的
generic algorithm通用算法
genericity 泛型
getter (相对于 setter)取值函数
global        全局的
global object 全局对象
global scope resolution operator 全局范围解析操作符
grant       授权 (for database)
granularity 粒度
group       组、群
group box   分组框
GUI   图形界面
GUID (Globally Unique Identifier) 全球唯一标识符
hand shaking   握手
handle     句柄
handler    处理器
hard-coded 硬编码的
hard-copy  截屏图
hard disk  硬盘
hardware   硬件
hash table 散列表、哈希表
header file头文件
heap       堆
help file  帮助文件
hierarchy  层次结构、继承体系
hierarchical data 阶层式数据、层次式数据
hook   钩子
Host (application)宿主(应用程序)
hot key   热键
hyperlink 超链接
HTML (HyperText Markup Language) 超文本标记语言
HTTP pipeline  HTTP管道
HTTP (HyperText Transfer Protocol) 超文本传输协议
icon   图标
IDE (Integrated Development Environment)集成开发环境
IDL (Interface Definition Language)    接口定义语言
identifier 标识符
idle time  空闲时间
if and only if当且仅当
IL (Intermediate Language) 中间语言、中介语言
image 图象
IME   输入法
immediate base      直接基类
immediate derived   直接派生类
immediate updating  即时更新 (for database)
implicit transaction隐式事务 (for database)
incremental update  增量更新 (for database)
index          索引 (for database)
implement      实现
implementation 实现、实现品
implicit       隐式
import         导入
increment operator  增加操作符
infinite loop       无限循环
infinite recursive  无限递归
information      信息
infrastructure   基础设施
inheritance      继承、继承机制
inline           内联
inline expansion 内联展开
initialization   初始化
initialization list 初始化列表、初始值列表
initialize      初始化
inner join      内联接 (for database)
in-place active 现场激活
instance        实例
instantiated    具现化、实体化(常应用于template)            
instantiation   具现体、具现化实体(常应用于template)        
integrate       集成、整合
integrity       完整性、一致性
integrity constraint完整性约束 (for database)
interprocess communication (IPC)进程间通讯(IPC)
interacts  交互
interface  接口
  for GUI  界面
interoperability 互操作性、互操作能力
interpreter   解释器
introspection 自省
invariants    不变性
invoke        调用
isolation level  隔离级别 (for database)
iterate   迭代
iterative 反复的、迭代的
iterator  迭代器
iteration 迭代(回圈每次轮回称为一个iteration)         
item      项、条款、项目
JIT compilation  JIT编译 即时编译
key          键 (for database)
key column   键列 (for database)
laser        激光
late binding 迟绑定
left outer join  左向外联接 (for database)
level      阶、层例
high level 高阶、高层
library    库
lifetime   生命期、寿命
link       连接、链接
linkage    连接、链接
linker     连接器、链接器
literal constant 字面常数
list   列表、表、链表
list box 列表框
livelock 活锁 (for database)
load   装载、加载
load balancing  负载平衡
loader 装载器、载入器
local  局部的
local object    局部对象
lock  锁
log   日志
login 登录
login security mode登录安全模式 (for database)
lookup table   查找表 (for database)
loop           循环
loose coupling 松散耦合
lvalue         左值
machine code   机器码、机器代码
macro        宏
maintain     维护
managed code 受控代码、托管代码
Managed Extensions 受控扩充件、托管扩展
managed object 受控对象、托管对象
mangled name      
manifest     清单
manipulator  操纵器(iostream预先定义的一种东西)           
many-to-many relationship 多对多关系 (for database)
many-to-one relationship  多对一关系 (for database)
marshal  列集
member   成员
member access operator    成员取用运算子(有dot和arrow两种)            
member function           成员函数
member initialization list成员初始值列表
memberwise  以member为单元…、members 逐一…           
memberwise copy 
memory      内存
memory leak 内存泄漏
menu     菜单
message  消息
message based  基于消息的
message loop   消息环
message queuing消息队列
metadata 元数据
metaprogramming元编程
method 方法
micro  微
middleware  中间件
middle tier 中间层
modeling    建模
modeling language 建模语言
modifier  修饰字、修饰符
modem     调制解调器
module    模块
most derived class最底层的派生类
mouse   鼠标
mutable 可变的
mutex   互斥元、互斥体
multidimensional OLAP (MOLAP)    多维OLAP(MOLAP) (for database)
multithreaded server application 多线程服务器应用程序
multiuser       多用户
multi-tasking   多任务
multi-thread    多线程
multicast delegate 组播委托、多点委托
named parameter    命名参数
named pipe  命名管道
namespace   名字空间、命名空间
native      原生的、本地的
native code 本地码、本机码
Native Image Generator (NGEN)本地映像生成器
nested class  嵌套类
nested query  嵌套查询 (for database)
nested table  嵌套表 (for database)
network       网络
network card  网卡
nondependent name
object        对象
object based  基于对象的
object file   目标文件
object model  对象模型
object oriented 面向对象的
object pooling  对象池化
ODBC data source ODBC数据源 (for database)
ODBC driver      ODBC驱动程序 (for database)
ODR (one-definition rule)
OLE Automation objects   OLE自动化对象 (for database)
OLE Automation server    OLE自动化服务器 (for database)
OLE DB consumer  OLE DB使用者 (for database)
OLE DB for OLAP  用于OLAP的OLE DB (for database)
OLE DB provider  OLE DB提供者 (for database)
one-to-many relationship 一对多关系 (for database)
one-to-one relationship  一对一关系 (for database)
online analytical processing (OLAP)    联机分析处理(OLAP) (for database)
online redo log     联机重做日志 (for database)
online transaction processing (OLTP)   联机事务处理(OLTP) (for database)
Open Data Services (ODS)   开放式数据服务(ODS) (for database)
Open Database Connectivity (ODBC) 开放式数据库连接(ODBC) (for database)
operand   操作数
operating system (OS) 操作系统
operation  操作
operator   操作符、运算符
option     选项
optimizer  优化器
outer join 外联接 (for database)
overflow   上限溢位(相对于underflow)                   
overhead   额外开销
overload   重载
overload resolution   重载决议
overloaded function   重载的函数
overloaded operator  被重载的操作符
override   覆写、重载、重新定义
package    包
packaging  打包
palette    调色板
parallel   并行
parameter  参数、形式参数、形参
parameter list 参数列表
parameterize   参数化
parent class   父类
parentheses    圆括弧、圆括号
parse    解析
parser   解析器
part     零件、部件
partial specialization 局部特化
pass by address   传址(函式引数的传递方式)(非正式用语)        
pass by reference 传地址、按引用传递
pass by value 按值传递
pattern       模式
PDA (personal digital assistant)个人数字助理
PE (Portable Executable) file   可移植可执行文件
performance   性能
persistence   持久性
PInvoke (platform invoke service) 平台调用服务
pixel  像素
placement delete
placement new   
placeholder 占位符
platform    平台
POD (plain old data (type))        
POI (point of instantiation)                
pointer  指针
poll     轮询
pooling  池化
polymorphism  多态
pop up     弹出式
port       端口
postfix    后缀
precedence 优先序(通常用于运算子的优先执行次序)        
prefix     前缀
preprocessor    预处理器
primary key (PK)主键(PK)  (for database)
primary table   主表 (for database)
primary template原始模板
primitive type  原始类型
print      打印
printer    打印机
procedure  过程
procedural 过程式的、过程化的
process    进程
profile    评测
profiler   效能(性能)评测器
program    程序
programmer 程序员
programming编程、程序设计
progress bar 进度指示器
project    项目、工程
property   属性
protocol   协议
pseudo code伪码
qualified  经过资格修饰(例如加上scope运算子)           
qualified name
qualifier 修饰符
quality   质量
queue     队列
race condition 竞争条件(多线程环境常用语)
radian         弧度
radio button   单选按钮
raise          引发(常用来表示发出一个exception)           
random number  随机数
range   范围、区间
rank    等级
raw     未经处理的
readOnly只读
record  记录 (for database)
recordset  记录集 (for database
recursive  递归
re-direction  重定向
refactoring   重构
refer     引用、参考
reference 引用、参考
reference counting引用计数
referential integrity (RI)引用完整性(RI) (for database)
register     寄存器
reflection   反射
refresh data 刷新数据 (for database)
regular expression  正则表达式
relational database 关系数据库
remote         远程
remote request 远程请求
represent      表述,表现
resolve        解析、决议        
resolution     解析过程
result set     结果集 (for database)
retrieve data  检索数据  
return         返回
return type    返回类型
return value   返回值
right outer join  右向外联接 (for database)
revoke       撤销
robust       健壮
robustness   健壮性
roll back    回滚 (for database)
roll forward 前滚 (for database)
routine      例程
row          行 (for database)
row lock     行锁 (for database)
rowset       行集 (for database)
RPC (remote procedure call)RPC(远程过程调用)
runtime 执行期、运行期、执行时、运行时
rvalue  右值
save    保存
savepoint  保存点 (for database)
SAX (Simple API for XML)
scalable  可伸缩的、可扩展的
schedule  调度
scheduler 调度程序
schema    模式、纲目结构
scroll bar滚动条
scope     作用域、生存空间
scope operator 生存空间操作符
scope resolution operator 生存空间解析操作符
screen   屏幕
SDK (Software Development Kit)软件开发包
sealed class 密封类
search    查找
semantics 语义
semaphore 信号量
sequential container序列式容器
server    服务器、服务端
serial    串行
serialization/serialize 序列化
server cursor服务端游标、服务器游标 (for database)
session      会话 (for database)
setter       设值函数
shared lock  共享锁 (for database)
sibling      同级
side effect  副作用
signature    签名
single-threaded  单线程
slider滑块
slot  槽
smart pointer 智能指针
SMTP (Simple Mail Transfer Protocol)   简单邮件传输协议
snapshot       截屏图
snapshot       快照 (for database)
specialization 特化
specification  规范、规格
splitter       切分窗口
SOAP (simple object access protocol)   简单对象访问协议
software      软件
source code   源码、源代码
SQL (Structured Query Language)  结构化查询语言 (for database)
stack  栈、堆栈
stack unwinding   叠辗转开解(此词用于exception主题)         
standard library  标准库       
standard template library 标准模板库
stateless 无状态的
statement 语句、声明
static cursor 静态游标 (for database)
static SQL statements 静态SQL语句 (for database)
stored procedure 存储过程 (for database)
status bar 状态条
stream   流
string   字符串
stub     存根
subobject子对象
subquery 子查询 (for database)
subroutine  子例程
subscript operator 下标操作符
subset   子集
subtype  子类型
support  支持
suspend  挂起
symbol   记号
syntax   语法
system databases   系统数据库 (for database)
system tables      系统表 (for database)
table       表 (for database)
table lock  表锁 (for database)
table-level constraint 表级约束 (for database)
tape backup  磁带备份 (for database)
target  标的,目标
task switch  工作切换             
TCP (Transport Control Protocol)       传输控制协议
template       模板
template-id
template argument deduction      模板参数推导
template explicit specialization 模板显式特化
template parameter   模板参数
template template parameter
temporary object 临时对象
temporary table  临时表 (for database)
text 文本
text file   文本文件
thin client 瘦客户端
third-party 第三方
thread      线程
thread-safe 线程安全的
throw 抛出、引发(常指发出一个exception)      
token 符号、标记、令牌(看场合)
trace 跟踪
transaction 事务 (for database)
transaction log  事务日志 (for database)
transaction rollback  事务回滚 (for database)
transactional replication  事务复制 (for database)
translation unit 翻译单元
traverse 遍历
trigger  触发器 (for database)
two-phase commit 两阶段提交 (for database)
tuple
two-phase lookup 两阶段查找
type  类型
UDDI(Universary Description, Discovery and Integration)统一描述、查询与集成
UML (unified modeling language)统一建模语言
unary function 单参函数
unary operator 一元操作符
unboxing       拆箱、拆箱转换
underflow      下限溢位(相对于overflow)
Union query    联合查询 (for database)
UNIQUE constraints  UNIQUE约束 (for database)
unique index   唯一索引 (for database)
unmanaged code 非受控代码、非托管代码
unmarshal      散集
unqualified     未经限定的、未经修饰的
URI (Uniform Resource identifier) 统一资源标识符
URL (Uniform Resource Locator)    统一资源定位器
user            用户
user interface  用户界面
value types 值类型
variable 变量
vector   向量(一种容器,有点类似array)               
viable   可行的
video    视频
view     视图
VEE (Virtual Execution Engine)虚拟执行引擎
vendor  厂商
view    视图 (for database)
virtual function  虚函数
virtual machine   虚拟机
virtual memory    虚拟内存
vowel          元音字母
Web Services   web服务     
WHERE clause   WHERE子句 (for database)
wildcard characters 通配符字符 (for database)
wildcard search     通配符搜索 (for database)
window              窗口
window function     窗口函数
window procedure    窗口过程
Windows authentication Windows身份验证
wizard  向导
word    单词
word processor  字处理器
wrapper      包装、包装器
write enable 写启用 (for database)
write-ahead log 预写日志 (for database)
write-only      只写
WSDL (Web Service Description Language)Web Service描述语言
XML Message Interface (XMI)       XML消息接口
XML (eXtensible Markup Language)  可扩展标记语言
XSD (XML Schema Definition)       XML模式定义语言
XSL (eXtensible Stylesheet Language) 可扩展样式表语言
XSLT (eXtensible Stylesheet Language Transformation)可扩展样式表语言转换
xxx based     基于xxx的
xxx oriented  面向xxx

posted @ 2006-09-28 00:23 xyang 阅读(758) | 评论 (0)编辑 收藏

1、配置系统管理(Admin Web Application)
  
  大多数商业化的J2EE服务器都提供一个功能强大的管理界面,且大都采用易于理解的Web应用界面。Tomcat按照自己的方式,同样提供一个成熟的管理工具,并且丝毫不逊于那些商业化的竞争对手。Tomcat的Admin Web Application最初在4.1版本时出现,当时的功能包括管理context、data source、user和group等。当然也可以管理像初始化参数,user、group、role的多种数据库管理等。在后续的版本中,这些功能将得到很大的扩展,但现有的功能已经非常实用了。Admin Web Application被定义在自动部署文件:CATALINA_BASE/webapps/admin.xml 。(译者注:CATALINA_BASE即tomcat安装目录下的server目录)
  
  你必须编辑这个文件,以确定Context中的docBase参数是绝对路径。也就是说,CATALINA
  
  _BASE/webapps/admin.xml的路径是绝对路径。作为另外一种选择,你也可以删除这个自动部署文件,而在server.xml文件中建立一个Admin Web Application的context,效果是一样的。你不能管理Admin Web Application这个应用,换而言之,除了删除CATALINA_BASE/webapps/admin.xml ,你可能什么都做不了。
  
  如果你使用UserDatabaseRealm(默认),你将需要添加一个user以及一个role到CATALINA_BASE/conf/tomcat-users.xml文件中。你编辑这个文件,添加一个名叫“admin”的role 到该文件中,如下:
  
  <role name="admin"/>
  
  你同样需要有一个用户,并且这个用户的角色是“admin”。象存在的用户那样,添加一个用户(改变密码使其更加安全):
  
  <user name="admin"
  password="deep_dark_secret"
  roles="admin"/>
  
  当你完成这些步骤后,请重新启动Tomcat,访问http://localhost:8080/admin,你将看到一个登录界面。Admin Web Application采用基于容器管理的安全机制,并采用了Jakarta Struts框架。一旦你作为“admin”角色的用户登录管理界面,你将能够使用这个管理界面配置Tomcat。
  
  2、配置应用管理(Manager Web Application)
  
  Manager Web Application让你通过一个比Admin Web Application更为简单的用户界面,执行一些简单的Web应用任务。Manager Web Application被被定义在一个自动部署文件中:
  
  CATALINA_BASE/webapps/manager.xml
  
  你必须编辑这个文件,以确保context的docBase参数是绝对路径,也就是说CATALINA_HOME/server/webapps/manager的绝对路径。(译者注:CATALINA_HOME即tomcat安装目录)
  
  如果你使用的是UserDatabaseRealm,那么你需要添加一个角色和一个用户到CATALINA_BASE/conf/tomcat-users.xml文件中。接下来,编辑这个文件,添加一个名为“manager”的角色到该文件中:
  
  <role name=”manager”>
  
  你同样需要有一个角色为“manager”的用户。像已经存在的用户那样,添加一个新用户(改变密码使其更加安全):
  
  <user name="manager"
  password="deep_dark_secret"
  roles="manager"/>
  
  然后重新启动Tomcat,访问http://localhost/manager/list,将看到一个很朴素的文本型管理界面,或者访问http://localhost/manager/html/list,将看到一个HMTL的管理界面。不管是哪种方式都说明你的Manager Web Application现在已经启动了。
  
  Manager application让你可以在没有系统管理特权的基础上,安装新的Web应用,以用于测试。如果我们有一个新的web应用位于/home/user/hello下在,并且想把它安装到/hello下,为了测试这个应用,我们可以这么做,在第一个文件框中输入“/hello”(作为访问时的path),在第二个文本框中输入“file:/home/user/hello”(作为Config URL)。
  
  Manager application还允许你停止、重新启动、移除以及重新部署一个web应用。停止一个应用使其无法被访问,当有用户尝试访问这个被停止的应用时,将看到一个503的错误??“503 - This application is not currently available”。
  
  移除一个web应用,只是指从Tomcat的运行拷贝中删除了该应用,如果你重新启动Tomcat,被删除的应用将再次出现(也就是说,移除并不是指从硬盘上删除)。
  
  3、部署一个web应用
  
  有两个办法可以在系统中部署web服务。
  
  1. 拷贝你的WAR文件或者你的web应用文件夹(包括该web的所有内容)到$CATALINA_BASE/webapps目录下。
  
  2. 为你的web服务建立一个只包括context内容的XML片断文件,并把该文件放到$CATALINA_BASE/webapps目录下。这个web应用本身可以存储在硬盘上的任何地方。
  
  如果你有一个WAR文件,你若想部署它,则只需要把该文件简单的拷贝到CATALINA_BASE/webapps目录下即可,文件必须以“.war”作为扩展名。一旦Tomcat监听到这个文件,它将(缺省的)解开该文件包作为一个子目录,并以WAR文件的文件名作为子目录的名字。
  
  接下来,Tomcat将在内存中建立一个context,就好象你在server.xml文件里建立一样。当然,其他必需的内容,将从server.xml中的DefaultContext获得。
  
  部署web应用的另一种方式是写一个Context XML片断文件,然后把该文件拷贝到CATALINA_BASE/webapps目录下。一个Context片断并非一个完整的XML文件,而只是一个context元素,以及对该应用的相应描述。
  
  这种片断文件就像是从server.xml中切取出来的context元素一样,所以这种片断被命名为“context片断”。
  
  举个例子,如果我们想部署一个名叫MyWebApp.war的应用,该应用使用realm作为访问控制方式,我们可以使用下面这个片断:
  
  <!--
  Context fragment for deploying MyWebApp.war
  -->
  <Context path="/demo"
  docBase="webapps/MyWebApp.war"
  debug="0" privileged="true">
  <Realm className=
  "org.apache.catalina.realm.UserDatabaseRealm"
  resourceName="UserDatabase"/>
  </Context>
  
  把该片断命名为“MyWebApp.xml”,然后拷贝到CATALINA_BASE/webapps目录下。
  
  这种context片断提供了一种便利的方法来部署web应用,你不需要编辑server.xml,除非你想改变缺省的部署特性,安装一个新的web应用时不需要重启动Tomcat。
  
  4、配置虚拟主机(Virtual Hosts)
  
  关于server.xml中“Host”这个元素,只有在你设置虚拟主机的才需要修改。虚拟主机是一种在一个web服务器上服务多个域名的机制,对每个域名而言,都好象独享了整个主机。实际上,大多数的小型商务网站都是采用虚拟主机实现的,这主要是因为虚拟主机能直接连接到Internet并提供相应的带宽,以保障合理的访问响应速度,另外虚拟主机还能提供一个稳定的固定IP。
  
  基于名字的虚拟主机可以被建立在任何web服务器上,建立的方法就是通过在域名服务器(DNS)上建立IP地址的别名,并且告诉web服务器把去往不同域名的请求分发到相应的网页目录。因为这篇文章主要是讲Tomcat,我们不准备介绍在各种操作系统上设置DNS的方法,如果你在这方面需要帮助,请参考《DNS and Bind》一书,作者是Paul Albitz and Cricket Liu (O'Reilly)。为了示范方便,我将使用一个静态的主机文件,因为这是测试别名最简单的方法。
  
  在Tomcat中使用虚拟主机,你需要设置DNS或主机数据。为了测试,为本地IP设置一个IP别名就足够了,接下来,你需要在server.xml中添加几行内容,如下:
  
  <Server port="8005"
  shutdown="SHUTDOWN" debug="0">
  <Service name="Tomcat-Standalone">
  <Connector className=
  "org.apache.coyote.tomcat4.CoyoteConnector"
  port="8080"
  minProcessors="5" maxProcessors="75"
  enableLookups="true"
  redirectPort="8443"/>
  <Connector className=
  "org.apache.coyote.tomcat4.CoyoteConnector"
  port="8443" minProcessors="5"
  maxProcessors="75"
  acceptCount="10" debug="0"
  scheme="https" secure="true"/>
  <Factory className="org.apache.coyote.
  tomcat4.CoyoteServerSocketFactory"
  clientAuth="false" protocol="TLS" />
  </Connector>
  <Engine name="Standalone"
  defaultHost="localhost" debug="0">
  <!-- This Host is the default Host -->
  <Host name="localhost"
  debug="0" appBase="webapps"
  unpackWARs="true" autoDeploy="true">
  <Context path="" docBase="ROOT" debug="0"/>
  <Context path="/orders"
  docBase="/home/ian/orders" debug="0"
  reloadable="true" crossContext="true">
  </Context>
  </Host>
  
  <!-- This Host is the first
  "Virtual Host": http://www.example.com/ -->
  <Host name="www.example.com"
  appBase="/home/example/webapp">
  <Context path="" docBase="."/>
  </Host>
  
  </Engine>
  </Service>
  </Server>
  
  Tomcat的server.xml文件,在初始状态下,只包括一个虚拟主机,但是它容易被扩充到支持多个虚拟主机。在前面的例子中展示的是一个简单的server.xml版本,其中粗体部分就是用于添加一个虚拟主机。每一个Host元素必须包括一个或多个context元素,所包含的context元素中必须有一个是默认的context,这个默认的context的显示路径应该为空(例如,path=””)。
  
  5、配置基础验证(Basic Authentication)
  
  容器管理验证方法控制着当用户访问受保护的web应用资源时,如何进行用户的身份鉴别。当一个web应用使用了Basic Authentication(BASIC参数在web.xml文件中auto-method元素中设置),而有用户访问受保护的web应用时,Tomcat将通过HTTP Basic Authentication方式,弹出一个对话框,要求用户输入用户名和密码。在这种验证方法中,所有密码将被以64位的编码方式在网络上传输。
  
  注意:使用Basic Authentication通过被认为是不安全的,因为它没有强健的加密方法,除非在客户端和服务器端都使用HTTPS或者其他密码加密码方式(比如,在一个虚拟私人网络中)。若没有额外的加密方法,网络管理员将能够截获(或滥用)用户的密码。
  
  但是,如果你是刚开始使用Tomcat,或者你想在你的web应用中测试一下基于容器的安全管理,Basic Authentication还是非常易于设置和使用的。只需要添加<security-constraint>和<login-config>两个元素到你的web应用的web.xml文件中,并且在CATALINA_BASE/conf/tomcat-users.xml文件中添加适当的<role>和<user>即可,然后重新启动Tomcat。
  
  下面例子中的web.xml摘自一个俱乐部会员网站系统,该系统中只有member目录被保护起来,并使用Basic Authentication进行身份验证。请注意,这种方式将有效的代替Apache web服务器中的.htaccess文件。
  
  <!--
  Define the
  Members-only area,
  by defining
  a "Security Constraint"
  on this Application, and
  mapping it to the
  subdirectory (URL) that we want
  to restrict.
  -->
  <security-constraint>
  <web-resource-collection>
  <web-resource-name>
  Entire Application
  </web-resource-name>
  <url-pattern>/members/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
  <role-name>member</role-name>
  </auth-constraint>
  </security-constraint>
  <!-- Define the Login
  Configuration for
  this Application -->
  <login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>My Club
  Members-only Area</realm-name>
  </login-config>
  
  6、配置单点登录(Single Sign-On)
  
  一旦你设置了realm和验证的方法,你就需要进行实际的用户登录处理。一般说来,对用户而言登录系统是一件很麻烦的事情,你必须尽量减少用户登录验证的次数。作为缺省的情况,当用户第一次请求受保护的资源时,每一个web应用都会要求用户登录。
  
  如果你运行了多个web应用,并且每个应用都需要进行单独的用户验证,那这看起来就有点像你在与你的用户搏斗。用户们不知道怎样才能把多个分离的应用整合成一个单独的系统,所有他们也就不知道他们需要访问多少个不同的应用,只是很迷惑,为什么总要不停的登录。
  
  Tomcat 4的“single sign-on”特性允许用户在访问同一虚拟主机下所有web应用时,只需登录一次。为了使用这个功能,你只需要在Host上添加一个SingleSignOn Valve元素即可,如下所示:
  
  <Valve className=
  "org.apache.catalina.
  authenticator.SingleSignOn"
  debug="0"/>
  
  在Tomcat初始安装后,server.xml的注释里面包括SingleSignOn Valve配置的例子,你只需要去掉注释,即可使用。那么,任何用户只要登录过一个应用,则对于同一虚拟主机下的所有应用同样有效。使用single sign-on valve有一些重要的限制:
  
  1> value必须被配置和嵌套在相同的Host元素里,并且所有需要进行单点验证的web应用(必须通过context元素定义)都位于该Host下。
  
  2> 包括共享用户信息的realm必须被设置在同一级Host中或者嵌套之外。
  
  3> 不能被context中的realm覆盖。
  
  4> 使用单点登录的web应用最好使用一个Tomcat的内置的验证方式(被定义在web.xml中的<auth-method>中),这比自定义的验证方式强,Tomcat内置的的验证方式包括basic、digest、form和client-cert。
  
  5> 如果你使用单点登录,还希望集成一个第三方的web应用到你的网站中来,并且这个新的web应用使用它自己的验证方式,而不使用容器管理安全,那你基本上就没招了。你的用户每次登录原来所有应用时需要登录一次,并且在请求新的第三方应用时还得再登录一次。
  
  当然,如果你拥有这个第三方web应用的源码,而你又是一个程序员,你可以修改它,但那恐怕也不容易做。
  
  6> 单点登录需要使用cookies。
  
  7、配置用户定制目录(Customized User Directores)
  
  一些站点允许个别用户在服务器上发布网页。例如,一所大学的学院可能想给每一位学生一个公共区域,或者是一个ISP希望给一些web空间给他的客户,但这又不是虚拟主机。在这种情况下,一个典型的方法就是在用户名前面加一个特殊字符(~),作为每位用户的网站,比如:
  
  http://www.cs.myuniversity.edu/~username
  http://members.mybigisp.com/~username
  
  Tomcat提供两种方法在主机上映射这些个人网站,主要使用一对特殊的Listener元素。Listener的className属性应该是org.apache.catalina.startup.UserConfig,userClass属性应该是几个映射类之一。
  
  如果你的系统是Unix,它将有一个标准的/etc/passwd文件,该文件中的帐号能够被运行中的Tomcat很容易的读取,该文件指定了用户的主目录,使用PasswdUserDatabase 映射类。
  
  <Listener className=
  "org.apache.catalina.startup.UserConfig"
  directoryName="public_html"
  userClass="org.apache.catalina.
  startup.PasswdUserDatabase"/>
  
  web文件需要放置在像/home/users/ian/public_html或者/users/jbrittain/public_html一样的目录下面。当然你也可以改变public_html 到其他任何子目录下。
  
  实际上,这个用户目录根本不一定需要位于用户主目录下里面。如果你没有一个密码文件,但你又想把一个用户名映射到公共的像/home一样目录的子目录里面,则可以使用HomesUserDatabase类。
  
  <Listener className=
  "org.apache.catalina.startup.UserConfig"
  directoryName="public_html"
  homeBase="/home"
  userClass="org.apache.catalina.
  startup.HomesUserDatabase"/>
  
  这样一来,web文件就可以位于像/home/ian/public_html或者/home/jasonb/public_html一样的目录下。这种形式对Windows而言更加有利,你可以使用一个像c:\home这样的目录。
  
  这些Listener元素,如果出现,则必须在Host元素里面,而不能在context元素里面,因为它们都用应用于Host本身。
  
  8、在Tomcat中使用CGI脚本
  
  Tomcat主要是作为Servlet/JSP容器,但它也有许多传统web服务器的性能。支持通用网关接口(Common Gateway Interface,即CGI)就是其中之一,CGI提供一组方法在响应浏览器请求时运行一些扩展程序。
  
  CGI之所以被称为通用,是因为它能在大多数程序或脚本中被调用,包括:Perl,Python,awk,Unix shell scripting等,甚至包括Java。
  
  当然,你大概不会把一个Java应用程序当作CGI来运行,毕竟这样太过原始。一般而言,开发Servlet总要比CGI具有更好的效率,因为当用户点击一个链接或一个按钮时,你不需要从操作系统层开始进行处理。
  
  Tomcat包括一个可选的CGI Servlet,允许你运行遗留下来的CGI脚本。
  
  为了使Tomcat能够运行CGI,你必须做如下几件事:
  
  1. 把servlets-cgi.renametojar (在CATALINA_HOME/server/lib/目录下)改名为servlets-cgi.jar。处理CGI的servlet应该位于Tomcat的CLASSPATH下。
  
  2. 在Tomcat的CATALINA_BASE/conf/web.xml 文件中,把关于<servlet-name> CGI的那段的注释去掉(默认情况下,该段位于第241行)。
  
  3. 同样,在Tomcat的CATALINA_BASE/conf/web.xml文件中,把关于对CGI进行映射的那段的注释去掉(默认情况下,该段位于第299行)。注意,这段内容指定了HTML链接到CGI脚本的访问方式。
  
  4. 你可以把CGI脚本放置在WEB-INF/cgi 目录下(注意,WEB-INF是一个安全的地方,你可以把一些不想被用户看见或基于安全考虑不想暴露的文件放在此处),或者你也可以把CGI脚本放置在context下的其他目录下,并为CGI Servlet调整cgiPathPrefix初始化参数。这就指定的CGI Servlet的实际位置,且不能与上一步指定的URL重名。
  
  5. 重新启动Tomcat,你的CGI就可以运行了。
  
  在Tomcat中,CGI程序缺省放置在WEB-INF/cgi目录下,正如前面所提示的那样,WEB-INF目录受保护的,通过客户端的浏览器无法窥探到其中内容,所以对于放置含有密码或其他敏感信息的CGI脚本而言,这是一个非常好的地方。
  
  为了兼容其他服务器,尽管你也可以把CGI脚本保存在传统的/cgi-bin目录,但要知道,在这些目录中的文件有可能被网上好奇的冲浪者看到。另外,在Unix中,请确定运行Tomcat的用户有执行CGI脚本的权限。
  
  9、改变Tomcat中的JSP编译器(JSP Compiler)
  
  在Tomcat 4.1(或更高版本,大概),JSP的编译由包含在Tomcat里面的Ant程序控制器直接执行。这听起来有一点点奇怪,但这正是Ant有意为之的一部分,有一个API文档指导开发者在没有启动一个新的JVM的情况下,使用Ant。
  
  这是使用Ant进行Java开发的一大优势。另外,这也意味着你现在能够在Ant中使用任何javac支持的编译方式,这里有一个关于Apache Ant使用手册的javac page列表。
  
  使用起来是容易的,因为你只需要在<init-param> 元素中定义一个名字叫“compiler”,并且在value中有一个支持编译的编译器名字,示例如下:
  
  <servlet>
  <servlet-name>jsp</servlet-name>
  <servlet-class>
  org.apache.jasper.servlet.JspServlet
  </servlet-class>
  <init-param>
  <param-name>logVerbosityLevel
  </param-name>
  <param-value>WARNING</param-value>
  </init-param>
  <init-param>
  <param-name>compiler</param-name>
  <param-value>jikes</param-value>
  </init-param>
  <load-on-startup>3</load-on-startup>
  </servlet>
  
  当然,给出的编译器必须已经安装在你的系统中,并且CLASSPATH可能需要设置,那处决于你选择的是何种编译器。
  
  10、限制特定主机访问(Restricting Access to Specific Hosts)
  
  有时,你可能想限制对Tomcat web应用的访问,比如,你希望只有你指定的主机或IP地址可以访问你的应用。这样一来,就只有那些指定的的客户端可以访问服务的内容了。为了实现这种效果,Tomcat提供了两个参数供你配置:RemoteHostValve 和RemoteAddrValve。
  
  通过配置这两个参数,可以让你过滤来自请求的主机或IP地址,并允许或拒绝哪些主机/IP。与之类似的,在Apache的httpd文件里有对每个目录的允许/拒绝指定。例如你可以把Admin Web application设置成只允许本地访问,设置如下:
  
  <Context path=
  "/path/to/secret_files" ...>
  <Valve className="org.apache.
  catalina.valves.RemoteAddrValve"
  allow="127.0.0.1" deny=""/>
  </Context>
  
  如果没有给出允许主机的指定,那么与拒绝主机匹配的主机就会被拒绝,除此之外的都是允许的。与之类似,如果没有给出拒绝主机的指定,那么与允许主机匹配的主机就会被允许,除此之外的都是拒绝的。

posted @ 2006-09-27 13:42 xyang 阅读(150) | 评论 (0)编辑 收藏


1.将数据库驱动程序的JAR文件放在Tomcat的 common/lib 中;

2.在server.xml中设置数据源,以MySQL数据库为例,如下:
在<GlobalNamingResources> </GlobalNamingResources>节点中加入,
      <Resource
      name="jdbc/DBPool"
      type="javax.sql.DataSource"
      password="root"
      driverClassName="com.mysql.jdbc.Driver"
      maxIdle="2"
      maxWait="5000"
      username="root"
      url="jdbc:mysql://127.0.0.1:3306/test"
      maxActive="4"/>
   属性说明:name,数据源名称,通常取”jdbc/XXX”的格式;
            type,”javax.sql.DataSource”;
            password,数据库用户密码;
            driveClassName,数据库驱动;
            maxIdle,最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连
                     接将被标记为不可用,然后被释放。设为0表示无限制。
            MaxActive,连接池的最大数据库连接数。设为0表示无限制。
            maxWait ,最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示
                     无限制。

3.在你的web应用程序的web.xml中设置数据源参考,如下:
  在<web-app></web-app>节点中加入,
  <resource-ref>
    <description>MySQL DB Connection Pool</description>
    <res-ref-name>jdbc/DBPool</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
 </resource-ref>
  子节点说明: description,描述信息;
               res-ref-name,参考数据源名字,同上一步的属性name;
               res-type,资源类型,”javax.sql.DataSource”;
               res-auth,”Container”;
               res-sharing-scope,”Shareable”;

4.在web应用程序的context.xml中设置数据源链接,如下:
  在<Context></Context>节点中加入,
  <ResourceLink
   name="jdbc/DBPool" 
   type="javax.sql.DataSource" 
   global="jdbc/DBPool"/>
   属性说明:name,同第2步和第3步的属性name值,和子节点res-ref-name值;
             type,同样取”javax.sql.DataSource”;
             global,同name值。
 
至此,设置完成,下面是如何使用数据库连接池。
1.建立一个连接池类,DBPool.java,用来创建连接池,代码如下:
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class DBPool {
    private static DataSource pool;
    static {
         Context env = null;
          try {
              env = (Context) new InitialContext().lookup("java:comp/env");
              pool = (DataSource)env.lookup("jdbc/DBPool");
              if(pool==null) 
                  System.err.println("'DBPool' is an unknown DataSource");
               } catch(NamingException ne) {
                  ne.printStackTrace();
          }
      }
    public static DataSource getPool() {
        return pool;
    }
}

2.在要用到数据库操作的类或jsp页面中,用DBPool.getPool().getConnection(),获得一个Connection对象,就可以进行数据库操作,最后别忘了对Connection对象调用close()方法,注意:这里不会关闭这个Connection,而是将这个Connection放回数据库连接池。

posted @ 2006-09-27 13:41 xyang 阅读(150) | 评论 (0)编辑 收藏

JNDI是J2EE中一个很重要的标准,通常我们是在J2EE编程中用到,Tomcat中提供了在JSP和Servelt中直接使用JNDI的方法,主要是通过dbcp连接池,下面谈一下我在Tomcat5.5中配置和使用JNDI的方法。本文的对象是对j2ee编程有所了解的读者,或者已经看过了我的Blog:tomcat的基本配置说明
  
  一、先在自己应用程序WEB-INF目录下的web.xml添加以下语句:
  <resource-ref>
  <descrtiption>引用资源说明</descrtiption>
  <res-ref-name>引用资源的JNDI名</res-ref-name>
  <res-type>引用资源的类名</res-type>
  <res-auth>管理者(Container)</res-auth><!--Container-容器管理 Application-Web应用管理-->
  </resource-ref>
  
  然后在tomcat目录/conf/server.xml文件里相应的<Context>元素,看我的Blog:tomcat的基本配置说明
  
  添加如下子元素:
  
  <Resource name="引用资源的JNDI名" auth="Container" type="javax.sql.DataSource"
  driverClassName="com.pointbase.jdbc.jdbcUniversalDriver(自己的jdbc驱动)"
  url="jdbc:pointbase:server://localhost/acme(数据库连接url)"
  username="root(用户名)" password="root(密码)" maxActive="20(连接池dbcp的相关配置)" maxIdle="10" maxWait="10000"/>
  
  注意,要把你的驱动拷到common/lib下,我用的是pointbase因此我拷的是pbclient44.jar到了common/lib下(对pointbase感兴趣的读者可以看我的另一篇文章pointbase数据库学习,里面也提到了我为什么是用pointbase数据库作为讲解)。
  
  二、例子:以下是我的假设的项目ACMEWeb:
  在相应程序的web.xml里添加
  <web-app ....>
  .....
  <resource-ref>
  <res-ref-name>jdbc/AcmeDB</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
  </resource-ref>
  </web-app>
  然后再server.xml里修改:
  <Context path="/ACMEWeb" reloadable="true" docBase="E:\eclipseproject\ACMEWeb" workDir="E:\eclipseproject\ACMEWeb\work">
  <Resource name="jdbc/AcmeDB" auth="Container" type="javax.sql.DataSource" driverClassName="com.pointbase.jdbc.jdbcUniversalDriver" url="jdbc:pointbase:server://localhost/acme" username="root" password="root" maxActive="20" maxIdle="10" maxWait="10000"/>
  </Context>
  建议你把上面的内容编写成为一个xml文件,拷到conf/Catalina/<主机名>/文件夹下,若有不懂的地方可以参考我的Blog:tomcat的基本配置说明 和tomcat的文档。

posted @ 2006-09-27 13:39 xyang 阅读(169) | 评论 (0)编辑 收藏

tomcat下有9个目录,分别是bin,common,conf,logs,server,shared,temp,webapps,work 目录,现在对每一目录做介绍。

  tomcat根目录在tomcat中叫<CATALINA_HOME>,文章中把tomcat解压后在c:/下。


  1.<CATALINA_HOME>/bin: 存放各种平台下启动和关闭Tomcat的脚本文件。其中有个档是catalina.bat,打开这个windos配置文件,在非注释行加入JDK路径,例如 : SET  JAVA_HOME=C:\j2sdk1.4.2_06 保存后,就配置好tomcat环境了。 startup.bat是windows下启动tomcat的文件,shutdown.bat是关闭tomcat的文件。


  2.<CATALINA_HOME>/common: 在common目录下的lib目录,存放Tomcat服务器和所有web应用都能访问的JAR?。


  3.<CATALINA_HOME>/shared: 在shared目录下的lib目录,存放所有web应用能访问的,但Tomcat不能访问的JAR?。


  4.<CATALINA_HOME>/server: 在server/webapps目录中,存放Tomcat自带的两个APP-admin和manager应用,使用来管理Tomcat-web服务用的。在server/lib目录中,存放tomcat服务器所需要的各,web应用不能访问种jar?。


  5.<CATALINA_HOME>/work : Tomcat把各种由jsp生成的servlet文件放在这个目录下。


  6.<CATALINA_HOME>/temp : 临时活页夹,Tomcat运行时候存放临时文件用的。


  7.<CATALINA_HOME>/logs : 存放Tomcat的日志文件


  8.<CATALINA_HOME>/conf : Tomcat的各种配置文件,最重要的是 server.xml;配置tomcat组件的XML文件server.XML其中包括


  I.顶层类元素[Top Level Elements]: 位于整个配置文件的顶层, 包括<Server>和<Service>;


  II.连接器类元素[Connectors ]: 客户和服务(容器类元素)间的通讯接口。接受客户请求,返回响应结果;<Connector>


  II.容器类元素[Containers]: 处理客户请求并且生成响应结果,包含3个:<Engine> <Host> <Context>


  IV.嵌套类元素[Nested Components]: 可以加入到容器中的元素,包括:<logger> <Valve><Realm>等


  一个<Server>包含一个或多个<Service>,一个<Service>包含唯一一个<Engine>和一个或多个<Connector>,多个 <Connector>共享一个<Engine>;一个<Engine>包含多个<Host>,每个<Host>定义一个虚拟主机,包含一个或多个web应用<Context>; <Context>元素是代表一个在虚拟主机上运行的Web应用。<Context>标签的描述


  Please note that for tomcat 5.x, unlike tomcat 4.x, it is NOT recommended to place <Context> elements directly in the server.xml file. Instead, put them in the META-INF/context.xml directory of your WAR file or the conf directory as described above.


  9.<CATALINA_HOME>/webapps: web应用的发布目录,把 java开发的web站点或war文件放入这个目录下就可以通过tomcat服务器访问了。

posted @ 2006-09-27 13:38 xyang 阅读(175) | 评论 (0)编辑 收藏

仅列出标题
共2页: 上一页 1 2