9 h# h0 i6 [; Z0 m6 \6 v& Ajsp->temp file->class->browser,os console,db8 a0 r) \; ?9 q7 u5 U, i
7 K! j' r) K8 J, F) s4 eapp,servlet->class->browser,os console,db / x& D" T6 u! |+ m7 I8 E! g0 X0 m8 J8 c' o. Y/ _! U, S: n2 t3 D. a
这个图就更明白了。Jsp文件先生成中间的Java文件,再生成Class。而Servlet和普通App则直接编译生成Class。然后,从Class再输出到浏览器、控制台或数据库等。( _( G) ~- t; D
; `, Z! u( m8 R8 s$ P: b- d& p JSP:从源文件到Class的过程$ d' X7 H7 @8 c" T% U$ H
6 r6 g) A+ M e0 e) l, Q Jsp的源文件是以“.jsp”结尾的文本文件。在本节中,将阐述JSP文件的解释和编译过程,并跟踪其中的中文变化。 + E" m N: S1 V% N / x2 G# O6 f' G* F" C' \! N4 B 1、JSP/Servlet引擎提供的JSP转换工具(jspc)搜索JSP文件中用<%@ page contentType ="text/html; charset=<Jsp-charset>"%>中指定的charset。如果在JSP文件中未指定<Jsp-charset>,则取JVM中的默认设置file.encoding,一般情况下,这个值是ISO8859-1; 9 F* [) `/ d. v& x' b- N1 Y# b4 V5 i! b9 k2 k+ T) D
2、jspc用相当于“javac –encoding <Jsp-charset>”的命令解释JSP文件中出现的所有字符,包括中文字符和ASCII字符,然后把这些字符转换成Unicode字符,再转化成UTF格式,存为JAVA文件。ASCII码字符转化为Unicode字符时只是简单地在前面加“00”,如“A”,转化为“\u0041”(不需要理由,Unicode的码表就是这么编的)。然后,经过到UTF的转换,又变回“41”了!这也就是可以使用普通文本编辑器查看由JSP生成的JAVA文件的原因; 9 f% ?0 {4 {8 o5 [2 T6 O 6 H) d" d2 [ Z 3、引擎用相当于“javac –encoding UNICODE”的命令,把JAVA文件编译成CLASS文件;. g: ]9 T" n+ l4 ^9 q
' r% p6 E& p) N( \: g 先看一下这些过程中中文字符的转换情况。有如下源代码:" n k5 _8 m- Z/ u5 P3 S: X
4 K7 J" ]& u, s( f<%@ page contentType="text/html; charset=gb2312"%>! `9 E" I6 J2 W2 u) L2 g& G
<html><body>2 P3 q8 B! Q2 Q* g' k' z) r' g
<% 6 z: k; g( H( Z1 }8 ] String a="中文"; # P+ S$ N# m1 \4 F8 S6 ] G out.println(a); ; u) W( B. [' W9 i% \1 A4 o7 h) c%> , E7 W% f/ j5 s& G</body></html> % \5 {8 D' U. r0 s 这段代码是在UltraEdit for Windows上编写的。保存后,“中文”两个字的16进制编码为“D6 D0 CE C4”(GB2312编码)。经查表,“中文”两字的Unicode编码为“\u4E2D\u6587”,用 UTF表示就是“E4 B8 AD E6 96 87”。打开引擎生成的由JSP文件转变而成的JAVA文件,发现其中的“中文”两个字确实被“E4 B8 AD E6 96 87”替代了,再查看由JAVA文件编译生成的CLASS文件,发现结果与JAVA文件中的完全一样。6 q% t/ `$ ^* x" P, Q) n
3 N3 |6 T5 B+ F- _* {
再看JSP中指定的CharSet为ISO-8859-1的情况。 $ Q7 V8 `1 u! z/ p 8 A" l: r) N! N9 X1 p9 h 8 H1 k G, {# f- T6 B6 o<%@ page contentType="text/html; charset=ISO-8859-1"%>0 f, e6 s$ V. p# T! `
<html><body>/ i& r( m6 ~& j. M# k/ k9 d" k
<% ' O; \3 Z! G/ L. _1 d4 D# r String a="中文"; . V0 p* S# ~( S) c% m out.println(a); 3 t# _ V: E% ` I%>$ v3 b9 U5 |- s* a4 `- e
</body></html> 9 ~! V2 n' [- e( x- K7 v' @) n( E; } 同样,该文件是用UltraEdit编写的,“中文”这两个字也是存为GB2312编码“D6 D0 CE C4”。先模拟一下生成的JAVA文件和CLASS文件的过程:jspc用ISO-8859-1来解释“中文”,并把它映射到Unicode。由于ISO-8859-1是8位的,且是拉丁语系,其映射规则就是在每个字节前加“00”,所以,映射后的Unicode编码应为“\u00D6\u00D0\u00CE\u00C4”,转化成UTF后应该是“C3 96 C3 90 C3 8E C3 84”。好,打开文件看一下,JAVA文件和CLASS文件中,“中文”果然都表示为“C3 96 C3 90 C3 8E C3 84”。* [- ?* }' X- Y' p4 K, q; Q
0 p6 e. a! h/ ]8 p, V8 x; D 如果上述代码中不指定<Jsp-charset>,即把第一行写成“<%@ page contentType="text/html" %>”,JSPC会使用file.encoding的设置来解释JSP文件。在RedHat 6.2上,其处理结果与指定为ISO-8859-1是完全相同的。 0 P/ [, W: e+ l8 T+ F) ~1 _3 D' ^( v& k- ^+ V V/ O) x
到现在为止,已经解释了从JSP文件到CLASS文件的转变过程中中文字符的映射过程。一句话:从“JspCharSet到Unicode再到UTF”。下表总结了这个过程:, K' o B f. g3 d6 I/ N
' y- ]7 s6 e. Y7 X& Y3 c 表2 “中文”从JSP到CLASS的转化过程 Z; P6 Z+ z+ C! W" F
4 ~) y, F% P% g4 S1 Z5 P; O3 d. h+ @6 W+ Z% p- X1 b
Jsp-CharSetJSP文件中JAVA文件中CLASS文件中GB2312D6 D0 CE C4(GB2312)从\u4E2D\u6587(Unicode)到E4 B8 AD E6 96 87 (UTF)E4 B8 AD E6 96 87 (UTF)ISO-8859-1D6 D0 CE C4 0 X/ F" v9 f6 }7 S. c" j(GB2312)从\u00D6\u00D0\u00CE\u00C4 (Unicode)到C3 96 C3 90 C3 8E C3 84 (UTF)C3 96 C3 90 C3 8E C3 84 (UTF)无(默认=file.encoding)同ISO-8859-1同ISO-8859-1同ISO-8859-1 # Q3 W" o' Z3 Q 下节先讨论Servlet从JAVA文件到CLASS文件的转化过程,然后再解释从CLASS文件如何输出到客户端。之所以这样安排,是因为JSP和Servlet在输出时处理方法是一样的。