# W; M! O1 w: q& K/ qbuffer[j++] = (char)buf[1]; " e# L: h- h' ~( ` F0 n7 [# O [. H7 \! p1 _2 H
} " c/ f+ F; ]9 M1 i2 l( {+ N
$ ^6 P+ d- Q# d% g4 }
else { ' e2 ]5 D+ R9 ^% g3 `: K
" w; V: z* B8 X: e
buffer[j++] = s.charAt(i); 2 O3 P' o7 J; j3 Y $ n& C6 X7 O3 Y: S, O+ v7 y3 c} 4 i0 M- D/ d2 l5 H7 b2 @, g
3 s3 P9 K" E. F6 [
} % _# g7 n2 H- k+ M( B8 s" b2 v) g# _7 ^$ `5 Z g( o
return new String(buffer, 0, j); & R+ _ O. K- [8 ~ 3 o$ g1 y) t7 `} & k- ?) w' L, B $ H) k# a1 U# i* N# m( o" D除使用以上两个方法之外,有些JDBC driver如果对jdbc driver Manager设置了正确 的字符集属性,以上2个方法就不需要了. 9 v( F; [) s+ I/ f1 g
L8 A0 I3 v i) T* e
: e3 y/ ^6 F& _) C k& K# l
问: % a! T- Z( ^2 g) @# R
当用Servlet来处理http请求并产生返回的HTML页面时,如何使HTML页面中的中文字符能够正常显示? 3 h6 @ y- g) d" W7 ^$ O
5 K% }; m1 i3 `, t' b) g答: + f) E# p: a3 d" z' K+ c& m P
javax.servlet.http.HttpResponse类用于产生返回页面.通过HttpResponse定义的方法getOutputStream()可以获得ServletOutputStream的实例,这样用户就可以利用ServletOutputStream.write方法向输出流中写入返回页面的内容. 但是ServletOutputStream使用的是缺省的编码方式,如果要使返回页面中的中文字 符能够正常显示,最好显示地指定所用的字符编码方式. 通常需要构造一个 OutputStreamWriter , 例程如下: ) E* i) Q% {; L1 {; U' Y* ^5 A" Z 7 y) _9 e3 \! B5 ?) {, h0 k, }# Y6 n, Q1 Y& N
public void doGet (HttpServletRequest req, HttpServletResponse res) : e! \, P9 k% F. }: q0 P! M( d' j% W' f6 @0 X" J
throws ServletException, IOException ; d$ G& [- v* y W/ O. ` % B: g- g# p9 P{ 1 Q, U2 C* R2 Q7 F
8 v- p: q% B, s% J9 d. G
res.setContentType("text/html"); " D- G9 {* S6 n 9 D3 [0 T$ t5 Q* U. gServletOutputStream out = res.getOutputStream(); & m3 N' @( G8 ^; f/ \; M
8 i& S3 a& j. f+ X; kOutputStreamWriter ow = new OutputStreamWriter(out,"GB2312"); 1 m/ ^: ?! R5 S, O( ~2 d! B$ c4 a* F ! J, o1 j9 }7 ?/ F' cow.write("这是测试"); & y- h( f1 g* Y0 c- Z' f" j* w6 \/ k
; N/ P* ?5 t* R. z* R/ iow.flush(); 6 C, G" ]! I5 m- e5 S1 Z: C
1 ^! _, N0 K/ _" Oow.close(); - C v' W7 a# S
& a- m0 U _. ^
} * ^& t- K2 z* d1 e2 D4 L 9 E" ]$ j7 n1 F7 n7 y " D7 R1 v# w x& [问: " Y4 {" M0 N7 `; I3 d) u/ z' x* r! d
如何设置Java WebServer的CLASSPATH,以包含用户的class文件? + ?, D' ^4 h, k* k / ?& G/ V# l7 @* ]8 p答: : U( w/ ?# A' G' p# K有两种方法可以设置Java WebServer的CLASSPATH环境变量,以使用户编写的Servlet能够调用用户的class文件. " }. O* t+ d0 G% P A, l- ^将用户的class文件放到 JavaWebServer_Dir/classes目录下,在Java WebServer 启动时,classes目录被自动加入到CLASSPATH环境变量中了. . f3 v( w% F9 v. N; t; p$ m. ]
修改httpd.nojre文件,将用户class文件所在的路径名加到CLASSPATH环境变量中. ) c& u, H. Y9 k; t2 g6 F2 D% R9 E# N2 M" c7 o: D
9 ?" l- A- t+ L' T
问: % l. @* q3 u7 m. |为什么在Windows平台上用Naming.lookup来获取远程RMI对象时会很慢? 4 V+ F" y' y1 [# \$ D " V- T8 c9 S2 V! C0 J% w答: ) g, @: M/ c t$ @3 K* C9 J
机器的网络设置不正确很可能会引起该问题的发生. 4 Y! J8 b* X2 `RMI使用了Java网络类,特别是java.net.InetAddress类,它将查询TCP/IP的主机名, 包括IP地址到主机名的映射和主机名到IP地址的映射.在Windows平台,这种查询功能 是由本地的Windows Socket库来实现的. 因此延时是发生在Windows库中,而非RMI中. ( h) n( j: [4 O; c
& P6 j' F6 R) o: l; A如果你的机器设置成使用DNS,问题通常是DNS服务器查不到主机名,你所发现的延时 是DNS查询的延时. 请尝试将RMI通信中涉及到的所有主机名/IP地址加到本地文件 winntsystem32driversetchosts或windowshosts中. 格式如下: . F8 ?& ]3 S0 M! G5 K8 p- _! i2 j2 j n, x
IP地址 主机名 3 s3 h/ g2 `0 x# P - Y8 h8 U; a) Y) r. d; z" r如此设置应当可以明显地减少查询所花的时间. - x1 U# B: w5 G ! ^- D5 C9 F( w! N" W' X问: 编写Java application时,如何设置proxy的信息,以便访问外部网站? % o. k4 n* X+ T/ q* o1 X+ p4 Q9 N/ L% l) W$ _* E0 L4 z
答: * z. B- i. u( l' Q" }* H若在java application中访问外部网站,首先应设置proxy信息,样例代码如下: 2 \6 t1 U/ a: g7 X+ v( j$ ]7 M& W5 b
/ j; u: t0 i1 E" u' A
9 H- x T0 E; @; ]
import java.util.properties; I- U0 ^: B0 L6 Q- {
# g4 R9 [6 ~; }: C" ]
..... 5 u0 h/ S9 O; W$ p+ K8 O
; L( o1 N. J. |0 @% zProperties sys = System.getProperties(); : t1 Y( @1 ]; y5 y6 ], A( z' P/ I1 r& B1 _, O
sys.put("proxySet","true"); 3 f1 X' |5 W4 i% @. e2 ^& I! C' K/ P
$ M* R" q, t y$ j, @sys.put("proxyHost","myHTTP.proxyserver.com"); & W" k1 _0 Y {9 O! |
0 |: |6 X# m) L$ Y* T% S* |1 P
sys.put("proxyPort","80"); 9 J. d8 D' t8 t b' t
+ v7 V$ G; O3 m, v% |
System.setProperties(sys); ) K; i1 p& v6 V
; G( b% c6 p. O
/ f4 W% c7 A9 T/ P/ Q3 U; ?9 `+ @0 o' [
. _6 M$ E# Z* [; B1 K/ o# T* ]+ Wu = new URL(website); : L; R; N2 s7 ?0 q9 O6 l- U$ |7 x) x$ g) C3 w: G
connect = (HttpURLConnection)u.openConnection(); . z: N. j5 n+ K) ?, I
" ~; e d9 v% l* g! K
..... X$ A ^% K4 ?) A: _) s% \$ e ! e% _+ p/ g+ \, ?% i8 k. ~ M/ g' F问: Swing组件JList的列表数据修改了,如何通知JList改变显示? 0 E4 Y& k, D4 }, u
$ F, T% {* ^. X8 p
答: - W" `0 k1 [6 t: P6 j0 B! O, vJList组件有一个单独的显示模式ListModel来表示JList的显示数据. ' N9 l1 e2 _6 P# H" g6 EJList创建以后,JList数据元素的值及数据元素的数量可以动态地改变. / [% @2 ~+ L, h3 VJList在它的数据模式ListModel中观察数据的改变.因此,一个ListModel 的正确实现应当在每次数据发生改变时,通知事件的监听者. , S" U5 m H8 k
当使用构造函数JList(Object[])创建一个JList的实例时,系统将自动 创建一个DefaultListModel的实例来存储JList的显示数据, 可以调用 DefaultListModel中定义的简便方法来动态地修改JList的数据,如 removeElementAt(index),addElement(Object)等. DefaultListModel 在修改数据的同时,将通知JList关于数据的改变. # ~/ T0 n. @4 s% X. w0 u6 X
: ?3 b v F7 r' M8 f 6 h& z, P+ `( F @2 P' x设置环境变量 - C& N+ V2 u) t G! e# m0 V% l
setenv LD_LIBRARY_PATH libC1.so,libC2.so所在路径 Y8 Z- L6 p1 K! r+ ^9 ~9 z {LD_LIBRARY_PATH} ) B) j! V9 O$ x' J" N1 i
) J! W; T X% e( P & B6 P: z/ P8 J9 I运行java应用 8 J2 L- F: O8 Q: T! t# C3 L8 a6 g
' u. Q, R! \; f
问: c! |/ Q, n6 }# ]. y
在Java语言中,如何列出PC机文件系统中的所有驱动器名? * k7 K6 p! D1 z' i, r( d % r& x2 [, W+ L4 [- |答: 1 G4 X7 K, |2 ^5 Y3 J8 F在Java 2版本中,java.io包中的File类新增加了方法listRoots()可以实现这一功能. + o. N: _' B" L$ z& a# n 0 x9 ^6 R# _# m( I; m; a问: 5 l% V$ m3 n) r* K* ~为什么Runtime.exec("ls")没有任何输出? / s* N9 ^! o4 y# o
z& k% K" s8 Z- V7 d: q. p0 W( X答: " s' t7 E: Q" X% s/ P3 v1 N. {调用Runtime.exec方法将产生一个本地的进程,并返回一个Process子类的实例,该实例可用于控制进程或取得进程的相关信息. 由于调用Runtime.exec方法所创建的子进程没有自己的终端或控制台,因此该子进程的标准IO(如stdin,stdou,stderr)都通过Process.getOutputStream(),Process.getInputStream(), Process.getErrorStream()方法重定向给它的父进程了.用户需要用这些stream来向 子进程输入数据或获取子进程的输出. 所以正确执行Runtime.exec("ls")的例程如下: 1 Z4 y& b9 z8 I' ]' Q9 a
5 H2 P5 [4 M4 L! I. b; d
$ \4 ^2 ]9 Y8 S% Otry 3 t3 l6 {0 [7 C& o - V: d0 \: C+ T B q% D) T5 U{ 9 G& b& R# n1 F1 D% G
$ a! V+ P9 Y7 g0 o- |) c' u8 @" K- V2 a1 s8 }) x: ?1 l8 j- x
6 i b" H8 s( @! b2 o5 q0 h: X
问: . F4 v+ Q8 p# J7 a# K( v1 K* D" M若通过ObjectOutputStream向一个文件中多次以追加方式写入object,为什么用ObjectInputStream读取这些object时会产生StreamCorruptedException? / x. P5 C9 H/ I+ T
; R( }! N3 B: O. D% w! e8 t
答: 1 y1 t/ B$ h" q. {使用缺省的serializetion的实现时,一个ObjectOutputStream的构造和一个ObjectInputStream的构造必须一一对应.ObjectOutputStream的构造函数会向输出流中写入一个标识头,而ObjectInputStream会首先读入这个标识头.因此,多次以追加方式向一个文件中写入object时,该文件将会包含多个标识头.所以用ObjectInputStream来deserialize这个ObjectOutputStream时,将产生StreamCorruptedException.一种解决方法是可以构造一个ObjectOutputStream的子类,并覆盖writeStreamHeader()方法.被覆盖后的writeStreamHeader()方法应判断是否为首次向文件中写入object,羰?则调用super.writeStreamHeader();若否,即以追加方式写入object时,则应调用ObjectOutputStream.reset()方法. 3 b7 [# p- }& W9 C5 Q7 t- [" U4 X- ^4 w& D( O# t# U: U
问: ( ^+ D1 v9 ~7 R# H2 w
对象的序列化(serialization)类是面向流的,应如何将对象写入到随机存取文件中? / y; C9 K* X( ^ T! I- H ) }- t9 _3 I6 R+ a答: 6 L9 M' W- M3 n目前,没有直接的方法可以将对象写入到随机存取文件中. 0 ^( l4 E# l1 O, g但是可以使用ByteArray输入/输出流作为中介,来向随机存取文件中写入或从随机存取文件中读出字节,并且可以利用字节流来创建对象输入/输出流,以用于读写对象.需要注意的是在字节流中要包含一个完整的对象,否则读写对象时将发生错误. 例如,java.io.ByteArrayOutputStream可用于获取ObjectOutputStream的字节流,从中可得到byte数组并可将之写入到随机存取文件中.相反,我们可以从随机存取文件中读出字节数组,利用它可构造ByteArrayInputStream,进而构造出ObjectInputStream,以读取对象. * p$ |" C7 f2 H. w & w C' P/ } ~! x& f' R" {6 A3 @问: ' j, d; B0 [" e4 M6 I
运行RMI应用时,可不可以不手工启动名字服务rmiregistry,而是从程序中启动之? 3 x% e% a& B5 O7 J, w7 R, m
Y% @9 ~0 K. P& z/ N. e+ [; Y# q
答: 0 j% f. t% r6 t% m9 L5 L可以. java.rmi包中提供了类java.rmi.registry.LocateRegistry,用于获取名字服务或创建名字服务.调用LocateRegistry.createRegistry(int port)方法可以在某一特定端口创建名字服务,从而用户无需再手工启动rmiregistry.此外,LocateRegistry.getRegistry(String host,int port)方法可用于获取名字服务. ( Q x& m" K, D( ~0 K6 y1 p ' ], `' ^$ m' j* O5 I问: 5 D# a. B8 I; P# i. }( f# |0 b, V% g使用类PrintJob进行打印操作时,应如何设置打印机名等打印属性? & V- i+ @5 f0 a' j- x) {2 ^, F+ @8 D0 F" E L3 e" u: C
答: ; z; m' q. @! H* E
使用如下方法可以获得PrintJob的实例用于控制打印操作: ; C/ ^: o U, I2 w0 M I! x4 D, \
7 [( X2 e$ v! q' ^5 h
5 E3 V: l9 n2 W! }: e n* N. w! Z
Toolkit.getPrintJob(Frame f, String jobtitle, Properties prop) 2 P i7 f, N4 h3 ^8 n/ d# g / m% ~" ?* G- u7 M8 {# p" o那么对于打印属性的设置可以通过对prop的属性设置来实现,打印属性包括: # \. F( u3 u# t: ]
$ T! n% Y% b4 z! ^& C
awt.print.destination: 可以是"printer"或"file" 4 ?- N8 E: r( U4 X: B4 ~6 ? [# Q/ f& n T
awt.print.printer: 打印机名 + s" T1 C9 Y7 X( H8 M4 I) ?2 }8 V/ M, T8 w, M6 N
awt.print.fileName: 打印文件名 ! d4 ?3 w1 U4 s, U
( z' q- x- g$ ]. z* R! O
awt.print.numCopies: 打印份数 5 \+ z- H( J) U! y6 ]4 H; g# `2 D
: z, o* u: d' d, E3 t6 S. \6 oawt.print.options: 打印命令的打印选项 ( I$ Z6 Y( E' _$ v/ a4 t 9 F" D; T; ^! n3 S7 Q' l* ]; e$ Wawt.print.orientation: 打印方向,可以是"portrait"或"landscape" 7 r! S M! @$ M+ E0 C$ L4 w
/ k; p, @" p/ x$ Z
awt.print.paperSize: 纸张大小,可以是"letter","legal","executive"或"a4" : ?- v' f0 k# I" g
6 B& }9 S! {. q* [0 I3 W- X
& M& @ k5 N' t; \3 a* m
' x% Z$ P" i- t4 S9 E 7 e, P+ d5 [' h) Z9 @( u / v6 E( V N7 ~ P- o* n. _) O问: $ n- Q* s7 Z4 f$ n
在JDK1.1中Thread类定义了suspend()和resume()方法,但是在JDK1.2中已经过时,应使用什么方法来替代之? 0 B* l, R! N- c; z
6 B8 U" z& W- l. y; q) u答: / G4 k, @& d% _' M# o, o Y2 b" R u- e7 P
Thread.suspend本身易于产生死锁.如果一个目标线程对某一关键系统资源进行了加锁操作,然后该线程被suspend,那么除非该线程被resume,否则其它线程都将无法访问该系统资源.如果另外一个线程将调用resume,使该线程继续运行,而在此之前,它也需要访问这一系统资源,则将产生死锁. 4 d' e2 j2 u0 D! x " F# U! l- M4 t! _因此,在Java 2中,比较流行的方式是定义线程的状态变量,并使目标线程轮询该状态变量,当状态为悬挂状态时,可以使用wait()方法使之处于等待状态.一旦需要该线程继续运行,其它线程会调用notify()方法来通知它. % S5 b2 ~/ S! [) s M5 @
' w; B. T r' V$ T7 U6 e% H问: 0 L' F; B1 L& z! B( z: H
使用JDBC编程,应如何控制结果集ResultSet的指针,使之能够上下移动,以及移动到结果集的第一行和最后一行? ' ^" Y& G( z2 F. \! L x& I# u7 n, ?3 u; p- n/ {) m: h7 W. ]
答: % ~0 N' h) H B, P* Y
在JDK1.1中,ResultSet类中只定义了next()方法支持数据指针的下移.但在Java 2中,ResultSet类增加了如下方法支持数据指针的移动,包括: , T( W7 k0 a' e* G* T
( n# t# X, o# y
* W0 R8 M3 `4 X3 [% O+ [ResultSet.first():将数据指针移到结果集的第一行 : u" p K' N2 r
8 N0 r0 k# L+ Q+ S2 nResultSet.last(): 将数据指针移到结果集的最后一行 ! n9 G' @) n% P. Z4 W( y" _- p, s1 t/ L7 q [6 U+ e2 q) L
ResultSet.previous(): 将数据指针上移一行 q+ T0 b6 X$ f( L& B8 N8 C. z( n6 n+ K( T% M
8 ` x! q& v, b6 q3 Q$ }/ O4 c
以上的方法定义在JDBC2.0的规范中,所有支持JDBC 2.0的JDBC驱动程序都可以支持上述方法.目前Intersolv和OpenLink等JDBC驱动程序厂商均有产品支持JDBC 2.0 . 6 S, z) X9 X. Y; F3 A9 s0 H
# R4 w( a, `/ [6 t5 r. X7 ?3 R% B3 G
0 n, l% u* @+ [, I' P问: / D2 E' G* M( c7 `) B. i# W
哪几种Web Server支持Servlet?如何使IIS支持Servlet? A6 \- [0 z6 C: ]6 R * u1 f" }* M$ ^6 [" o& o' M+ K! d答: 8 n+ d9 r6 H: I" }目前,支持Servlet的服务器端产品主要有: Sun公司的Java WebServer,Lotus DominoGo WebServer,BEA weblogic Tengah Server,Jigsaw,NetForge,AcmeServer和Mot Bays Jetty等. 3 V1 o; {; |7 L- K8 I% F( B, A) e7 [3 K$ B. ?9 a
此外,一些第三方厂商也开发了Servlet engine,以使其它WebServer(如Netscape Web Server,IIS等)能够运行Servlet,如LiveSoftware的Jrun(http://www.livesoftware.com/ products/jrun/)等. 1 C) a8 V0 U& Z
* Q" `, X( ?, E) {, Y* Y* z8 C/ F问: $ C5 \, V8 T) @3 _5 m4 b* g8 T如何在Java应用中将图像存储到图像文件中? $ X! u1 j6 x% ? \ 0 `$ H6 _8 @: k- w7 T2 M答: 8 n b3 i" k& Q/ X
Java Advanced Imaging API(包含在Java Media API中)允许在Java应用中执行复杂的,高性能的图像处理.JAI API提供了存储图像的能力.目前,JAI API支持以下几种图像文件格式:BMP,JEPG,PNG,PNM,TIFF.下面给出了将图像存储到BMP文件的一段代码: ! c3 A8 q9 Y% X a + x% f# A2 w% q+ a9 S1 T$ [& L. }$ A) y3 G9 F, D
OutputStream os = new FileOutputStream(fileToWriteTo); 9 c+ w5 t8 c) u6 Z* E
9 U& r' u3 g: p2 VBMPEncodeParam param = new BMPEncodeParam(); + \- ? m X% ?9 N$ L3 p1 ~% N& A4 O- T( m+ {7 V
ImageEncoder enc = ImageCodec.createImageEncoder("BMP", os, param); ; J! ~' p( N/ X. E& b) g
8 V2 h4 y- O* ~' R) Z% _, o+ renc.encode(img); 9 V. d: c$ l- ?7 B & A0 x7 `' u+ L. Aos.close(); + ^9 h$ q$ C" g/ P" i; M. p/ E8 B* {, ?' p
有关存储图像文件的编程指南请参考以下网页: - M# j5 |& j" O% `5 D A
% E- @. P4 n/ Z3 l9 _
http://java.sun.com/products/java-media/jai/forDevelopers/jai-guide/ # T9 ?& M. }$ I( ], Q- B' ?- a& W: n- a, Z/ t3 T
2 g' l; M2 S% m" {; m' |& }3 V+ K t! l
0 V/ t( H1 R4 H5 b