在线时间 0 小时 最后登录 2007-11-12 注册时间 2004-12-24 听众数 2 收听数 0 能力 0 分 体力 2467 点 威望 0 点 阅读权限 50 积分 882 相册 0 日志 0 记录 0 帖子 205 主题 206 精华 2 分享 0 好友 0
升级 70.5%
该用户从未签到
问: 如何设置Java 2(JDK1.2)的环境变量? ; d+ {* y \" q# N! ^& W! q
5 v! a( {- e( N* y9 ? b
答: Java 2安装后,需要设置PATH和JAVA_HOME环境变量.与JDK1.1不同的是:设置好JAVA_HOME环境变量后,JVM将自动搜索系统类库以及用户的当前路径. ) U* l' K9 A0 P2 `: a$ ~) g8 o0 D
Java 2环境变量的设置如下例所示: 4 v5 T% f6 n2 V( m! @. x8 @
Solaris平台: setenv JAVA_HOME Java2的安装路径 i; X$ i3 D/ m/ l
setenv PATH $JAVA_HOME/bin {PATH}
/ l" h' p3 ~8 y! B7 x a Windows平台: set JAVA_HOME=Java2的安装路径 * ]. P( Y X. c1 O, K- f, h
set PATH=$JAVA_HOMEbin;%PATH% + [5 D5 d$ f0 E& P8 R" @
% W( ~- E. @! V' N8 o8 J, {+ [ 问: 哪些Java集成开发工具支持Java 2? ) c8 |/ ~$ v3 R! J
$ D$ K; |0 b b8 b4 V5 T v6 }% w w 答: 目前流行的Java集成开发环境,如Inprise的JBuilder,Symantec的Visual Cafe, Sybase的PowerJ,都支持Java 2.
/ b$ I9 l/ D5 M
/ ]1 a) q) I% e' ` 问: 如果在Netscape或IE浏览器中运行Java applet时出现了错误,如何确定错误范围? - ]$ }: {4 ^' h3 f& {. c
9 I3 ~" C3 a' a1 E; p5 \, p
答: 当java applet在浏览器中运行时,使用的是浏览器本身的缺省JVM.而不同浏览器对JDK的支持程度也不尽相同. 因此,在Netscape或IE浏览器中运行Java applet出现了错误,建议使用JDK提供的工具appletviewer或Sun公司的Hotjava浏览器来测试该applet,以确定错误的产生是与浏览器相关.
- b3 B$ Q) j4 m% G 如果applet在appletviewer或Hotjava中运行一切正常,则错误的产生是由于浏览 器不完全兼容JDK而引起的. 此时,解决方法可以是使用Hotjava浏览器或者安装 Sun公司的Java Plugin. & `6 a) Z4 D6 U( B3 ~! u7 o# b' F
如果applet在Hotjava浏览器或appletviewer中运行即发生错误,则应当根据错误 提示检查applet程序. 3 T4 Q' w9 L i3 A
3 p- s3 Z: o) ?+ q' P" f
问: 当用JDBC向数据库中插入数据或从数据库中提取数据时,为何有时中文字符会显示为乱码?
5 g0 |9 r! q( i& ?, i8 ?
2 \; t# g) u- Z) }3 _7 g4 ?" h 答: 这个问题的实现通常与各个JDBC driver的实现有关. 目前大多数JDBC driver采用本地编码格式来传输中文字符,例如中文字符"0x4175"会被转成"0x41"和"0x75"进行传输. 因此我们需要对JDBC driver返回的字符以及要发给JDBC driver的字符进行转换. 5 I4 \& s2 u3 W% h) j- q+ Q
" R& I4 U6 F5 i% Z( i
当用JDBC driver向数据库中插入数据时,需要先将Unicode转成native code; 当 JDBC driver从数据库中查询数据时,则需要将native code转换成Unicode. 下面给出了这两种转换的实现: : ~% M: A- \) n% x* |* ?
. @ o+ I+ H7 K9 P5 Y# Z+ o& F
2 ~; `! l" g0 \ String native2Unicode(String s) {
# |4 G# L6 }' [: ]+ s; x; G y
" I( e1 P* N+ R; E5 t if (s == null || s.length() == 0) { + f8 Z/ p# F' |3 @& W" r3 J
# s- Z- l3 K) J) { return null;
; E- `; a0 D+ h* n
8 z; N5 W& R) f7 u; n }
4 y/ O8 N* d( k' \4 e ~
) i! I% b2 P# O0 h, w. n0 ~; T& H byte[] buffer = new byte[s.length()]; " W+ j. R$ i, N" h! d5 |) i! ?/ h2 G
1 b D$ v B! t3 f+ U* K
for (int i = 0; i s.length(); i++) { if (s.charAt(i)>= 0x100) {
/ S1 ?1 V+ g& W3 \5 g3 I
/ \3 M; T- }5 L c = s.charAt(i);
! z% j5 ]1 }; o S! s
$ v% J. w+ \" j byte []buf = (""+c).getBytes(); / G, s n [- C% P+ \, o- ?
# m" k5 |. k' a5 z, M buffer[j++] = (char)buf[0]; 7 A' n) ]: @* D6 v$ H
5 y6 u/ P/ b2 I$ c! N2 _
buffer[j++] = (char)buf[1]; ) {2 b2 z) P0 [3 K& x X
$ D$ P9 F' w; S" Y& A, h
}
; O( n# G/ l" l% ?6 w1 x
) D' l3 y. `8 ~$ r' ?8 y else { ! Q/ {1 I7 f3 b$ ?7 W/ T
* ^ W" d% ?0 l1 ^- i5 F buffer[j++] = s.charAt(i);
3 `2 f$ O. p0 L' E1 d& k& M4 | & B1 C* J0 c; {$ Z- X& u
} 5 I2 N8 v0 M' d6 {. q& I- t
4 s8 O. c9 D/ M3 H( l& c
}
. ~4 [0 K$ A6 `& y 1 z7 j1 p' L h* |! }8 N, N8 H
return new String(buffer, 0, j);
0 ~5 g7 L( R) @- V9 d& v' H* c, | 5 Z' l- Q4 Z/ O& e- g
}
% U; P' N9 U! U% D1 f8 Q! ? 1 l0 h& _4 J- f' |- i
除使用以上两个方法之外,有些JDBC driver如果对jdbc driver Manager设置了正确 的字符集属性,以上2个方法就不需要了.
& H7 C! v, G" n5 n+ @ F $ t2 K p) `6 P$ e
& g' Y4 g0 d2 a( ~1 N1 [ 问:
1 d+ R% O" J" @9 P7 w) Q% Y& m 当用Servlet来处理http请求并产生返回的HTML页面时,如何使HTML页面中的中文字符能够正常显示?
% k( z1 Y. L F1 q7 E. d / c* ^' w$ ]8 `( \8 ?7 F
答:
: H( a% |3 l* g b; m4 }, I javax.servlet.http.HttpResponse类用于产生返回页面.通过HttpResponse定义的方法getOutputStream()可以获得ServletOutputStream的实例,这样用户就可以利用ServletOutputStream.write方法向输出流中写入返回页面的内容. 但是ServletOutputStream使用的是缺省的编码方式,如果要使返回页面中的中文字 符能够正常显示,最好显示地指定所用的字符编码方式. 通常需要构造一个 OutputStreamWriter , 例程如下:
+ \ p9 r/ T1 M3 @7 C
& A* e/ i$ S' M! G; x& G
5 {- P$ h( F/ e4 L3 c$ B public void doGet (HttpServletRequest req, HttpServletResponse res) 2 C2 M7 t* `! N( Y
: R5 v z) `0 D$ Q* ], F" i8 @
throws ServletException, IOException
* t1 W# T9 {1 `2 [& c; Z
4 F4 O9 p+ D1 j1 ~3 V' S: i { 2 e" o& k$ `5 l1 A! u: d/ T
8 g/ ]& c9 k! R res.setContentType("text/html");
$ U+ m/ `5 z* F % @4 F: u" M* P: a6 {2 }
ServletOutputStream out = res.getOutputStream(); . W6 W* s. e( o
7 N# A# c, B9 h3 |7 Z3 D OutputStreamWriter ow = new OutputStreamWriter(out,"GB2312");
$ r% Z4 F* t3 ] . x5 T! x# r' b0 z- b/ \. e% ]
ow.write("这是测试");
+ H% [; z" U8 Y- i
# e/ e$ M v' T) I+ d& {- ~! X- J% I ow.flush(); 4 _2 c- V5 ^1 C; k% y( i( K# `
* n: B$ k% `7 O& P( q/ _
ow.close();
1 E6 W7 ]1 |) B7 o9 b4 V$ [ % e$ K" }2 I/ d+ j( O
}
1 g2 x$ l% Y2 r& G6 |% @7 G
5 P. x8 y: F. S; G. Q
+ f- b6 U- T) L" d 问: ; X3 Y `6 b' |2 x- J- ~
如何设置Java WebServer的CLASSPATH,以包含用户的class文件?
% `" ~1 C5 h* @; K
) j9 l7 v$ \0 T+ d( `/ Q 答: - x* b( z2 i; q+ ~- U \
有两种方法可以设置Java WebServer的CLASSPATH环境变量,以使用户编写的Servlet能够调用用户的class文件. 7 |3 v! Z& I& [
将用户的class文件放到 JavaWebServer_Dir/classes目录下,在Java WebServer 启动时,classes目录被自动加入到CLASSPATH环境变量中了. ) Y; q) ~: F7 n& x' |4 v J
修改httpd.nojre文件,将用户class文件所在的路径名加到CLASSPATH环境变量中. & q Z0 C( l8 O: G
; _, F# t5 h4 N. a' ]2 q7 Q
- {/ a! p w) B* N; B 问:
! p; ]" `* `& `" b, |8 e, X" m 为什么在Windows平台上用Naming.lookup来获取远程RMI对象时会很慢? 2 K+ x2 o( j* F5 G
' m8 ~/ B0 S2 v3 Z+ k$ x 答:
1 p: Z1 j& b# Q! z 机器的网络设置不正确很可能会引起该问题的发生.
# C" O2 v, X8 X. S% N$ h' `8 W+ ? RMI使用了Java网络类,特别是java.net.InetAddress类,它将查询TCP/IP的主机名, 包括IP地址到主机名的映射和主机名到IP地址的映射.在Windows平台,这种查询功能 是由本地的Windows Socket库来实现的. 因此延时是发生在Windows库中,而非RMI中.
' p/ \- s! a: |9 x+ J' Z5 { 9 @- }5 {; P! I& |6 J
如果你的机器设置成使用DNS,问题通常是DNS服务器查不到主机名,你所发现的延时 是DNS查询的延时. 请尝试将RMI通信中涉及到的所有主机名/IP地址加到本地文件 winntsystem32driversetchosts或windowshosts中. 格式如下:
5 ^& v" y5 ?) W3 b
+ x! R2 k; @% j( S: { IP地址 主机名
8 {, h# \5 |9 F0 ?$ g1 k6 F' q* g* ? 1 F& u ^5 s; V" L0 e, a$ U7 l* U
如此设置应当可以明显地减少查询所花的时间. 1 E! p% Q! x1 g8 e
' W% L# S4 c) N 问: 编写Java application时,如何设置proxy的信息,以便访问外部网站? ! u$ f/ |3 S) E1 n3 L3 S. l
! g. l. [3 g9 B; i
答: 5 t/ F# S H u ~" \
若在java application中访问外部网站,首先应设置proxy信息,样例代码如下: : l0 E% l. u% W6 q) A& L+ X. R
( z1 M( J; K8 q/ E& e 4 N4 F8 M" X7 f) a
import java.util.properties;
8 w- ^$ A: h' }7 z) j7 R1 y 9 ?* ~3 K* u0 j. F2 f3 G
..... : D8 c# C) t& i4 I3 M! w0 n
: z2 @) G! F# ?2 o7 M Properties sys = System.getProperties(); ) U: S( R; _0 r7 ~" s
: x, m2 Y% E/ ^) G# ~! N( k& p" E sys.put("proxySet","true"); % r5 B' A$ k4 h) S+ H
6 g1 J, Q: k; q5 o! S; e+ u' Q
sys.put("proxyHost","myHTTP.proxyserver.com");
4 M9 e8 W9 x( B/ R' Q2 x' `# R
6 M2 E6 H/ D' N2 I- q sys.put("proxyPort","80");
* j. y2 S2 o" t8 Z
4 G5 H( v( I* _/ E( N: d) k System.setProperties(sys); ) }" T, {! U% W
: H( G u+ } C/ Z" S* K, ]- F9 p
1 i: D5 h; Z/ h W 2 A) Y R/ e- _4 K
u = new URL(website); 9 g( N1 [9 @+ o) u5 D7 l# J
9 d8 Y2 G$ L! E9 j8 J! H" U4 f* _8 e connect = (HttpURLConnection)u.openConnection(); & c# W: W8 {3 c" T
* z. v/ \9 R% B7 G4 d" V! I
..... j2 i7 j; g" p. h& k# G% y
5 Q- Y0 w4 O7 u- A" j6 w. m 问: Swing组件JList的列表数据修改了,如何通知JList改变显示?
& r# k/ @6 S, j& V " Q; @- g0 b" g
答: ; g) H2 q+ x# i: w0 u
JList组件有一个单独的显示模式ListModel来表示JList的显示数据. / _$ N2 c9 J% l
JList创建以后,JList数据元素的值及数据元素的数量可以动态地改变. ' Z9 t0 W% f2 D8 B, \
JList在它的数据模式ListModel中观察数据的改变.因此,一个ListModel 的正确实现应当在每次数据发生改变时,通知事件的监听者.
6 R. F3 r# d. H+ ]1 j 当使用构造函数JList(Object[])创建一个JList的实例时,系统将自动 创建一个DefaultListModel的实例来存储JList的显示数据, 可以调用 DefaultListModel中定义的简便方法来动态地修改JList的数据,如 removeElementAt(index),addElement(Object)等. DefaultListModel 在修改数据的同时,将通知JList关于数据的改变.
# H4 `$ I* N. a, ` 7 M- k! y) E+ \! D1 ^7 @6 t* U
问: / F4 m* w) C# C/ v0 ]- z# _
在Java applet中如何实现一个模式对话框? . R( W% s+ U! V6 _ b
* _6 x/ H& M7 z& {' n+ P( h
答:
- o' B5 E; x+ o9 F" l7 ^# S( Q5 {5 N$ X 在Java applet中实现模式对话框的关键就是在创建一个对话框的时候 要为该对话框指定一个正确的父窗口.因为Applet是Panel类的子类,不 可以作为对话框的父窗口,所以首先要获得applet所在的窗口,作为模式 对话框的父窗口. 样例代码如下: 4 }4 c: B7 @+ S! i: \1 V
# ^0 @* I' ~8 [- x4 w
" `8 E6 Z8 f( ]6 n. O$ J1 q ..... ' }9 v/ k$ E; m, r
' C {- |3 f* I/ c' G
Dialog d = new Dialog( getParentWindow(comp),title);
8 T z* b1 h% O; T* ]: X Q
' L1 |1 K# L& f0 }4 z& x: z0 F // comp为applet上的任意一个组件
% |, Q# h8 g3 v3 T7 F ~ 6 y# ?% b l& @, e9 h/ Q7 w$ B
.... 2 M6 h9 H7 I1 ~1 ^# v' w: e
+ m1 M0 P7 D1 B$ a ^& Y1 u/ f% L
; ] w/ d" H0 d$ w: B% s: ~. R! y2 E public void getParentWindow(Component compOnApplet,String title){ ( m5 j$ A: @& e. P8 }: E
; s5 S: ]. W+ h# K7 r/ K Container c = compOnApplet.getParent(); % A. }- Z" A" q
- Z9 _' D+ [+ r- D: K7 N
while (c != null) { 0 N8 O7 ~3 l5 T! f' n& t
/ z8 t2 X/ Y1 V/ q! y. ]
if (c instanceof Frame)
+ o8 B" U+ C; W4 _ # i$ E* J, @" a) Q' v9 e
return (Frame) c; ! O* W5 t/ q; l/ e
; E2 L0 ]% ]+ h: \0 E c = c.getParent(); 2 N0 K: O+ A5 F Z
) j. r% Y( I! {9 A' S% l# F0 z }
1 S* F5 E0 Y/ s* o2 u+ q5 r: D
: L# j% S" a- `9 q return null; $ m: r1 b* A6 v* O& @, J
7 u' O' \2 z7 y! G+ J9 Q
} 5 ]( \9 M' d1 P5 K- T
5 j5 S9 J) X" B6 q$ q
问: 在Java applet中如何显示另外一个HTML页面?
+ @7 i! ] D4 }/ ?
5 b' v) a7 p) s1 m# F 答:
8 Q" y. P" b" {( m( C 通过java.applet.Applet.getAppletContext()方法可以获得与该applet相关的AppletContext, AppletContext.showDocument(URL)方法就可以使applet所在的浏览器显示另外一个网页.
( R6 k& Q5 @, S& i f# m0 ` 3 ]/ H% D. l3 L
问:
, K9 H3 O& t# B6 J3 D4 ] 用JDK实现的签名applet,可否在Netscape或IE中运行?
$ | f3 Y; S5 k. m& A) W
1 Y! j1 x6 {/ g1 J1 c' R" I 答:
3 o, w/ s* `" Z0 Q+ C" M: w 用JDK实现的签名applet,不可以在Netscape或IE中运行,但是可以在Hotjava浏览器中运行.
x9 O5 z4 ^) |( A' Y7 |$ V8 C
3 o8 |1 H/ Z! W& j: u" P 不同的浏览器提供了不同的签名applet机制,如Netscape提供了zigbert工具和 Capability API, 而IE则需要使用CAB文件. 但是,无论是Netscape工具产生的 签名applet,还是用IE产生的签名applet,都不可以在其它的浏览器中运行. ' g R8 V' D+ p2 o' A$ {$ C
0 _5 y3 c: `* d
如果要使JDK产生的签名applet能够在Netscape或IE中运行,解决方法是在 Netscape或IE中安装Java Plugin,则用JDK实现的签名applet就可以在这两种 浏览器中运行. $ W' m% ?8 n+ |3 k9 d) _
9 V. q; z3 B% e, @' O' w
问: 3 q2 O( r( w, |, B
用JNI技术可以从Java应用中调用C程序库,但是如何使该C程序库可以调用另外的C程序库?
) M! Y( E$ q3 {' h& }$ e0 a) m
$ E t7 r) p- [4 B" W 答:
3 K: u+ _" a+ m4 N 如果一个被Java调用的C程序库C1仍需要调用另外一个C程序库C2,那么在编译C1的时候应当联接程序库C2,步骤如下(Solaris平台): 6 l* a5 [" O5 w0 ~% y/ T
编写调用C库的Java文件,并编译.
6 }; h, t x9 E8 @7 e javac java文件名 Y& [' N( Y( D
+ M: E4 s# X8 o) h) R/ F
. C$ ^7 R3 t, T8 t2 f) Y9 E! b# z
产生C程序头文件 4 q6 O9 ~" U& s6 n. n1 y) g! V/ r
javah -jni java文件名(不带后缀.java) . |' r9 N5 J. l* z/ ?8 D9 P* }
5 @7 ?. {* Q8 ?" w4 u3 y
3 A5 b" G: M; ~2 A3 H; }7 O7 e
编写被Java调用的C程序C1.c,以及被C1调用的C2.c,并编译.
$ m+ f0 I# K9 J) ^8 T" k: [ cc -G -Iinclude路径名 C2.c -o libC2.so
! ~! q% ]1 A& F cc -G -Iinclude路径名 -lC2 C1.c -o libC1.so
) v, S. _# G Y6 p0 \' l
) g$ H2 s8 A8 D- p, F( K. X
' x3 x2 R( W! H4 p! O8 w) d 设置环境变量
2 J7 c9 H; I7 N4 {' X setenv LD_LIBRARY_PATH libC1.so,libC2.so所在路径 c) p. N( E# b( X
{LD_LIBRARY_PATH}
3 W3 M$ t6 Q& Y" }3 L2 Z1 K + ^2 D1 G2 h/ E$ }9 i/ l% d
1 i* ~0 S% l: `0 C- h f8 R4 | 运行java应用
* W7 l& ?' \8 E7 O& o
( S- M- A! ]0 i1 H8 W3 `1 Z2 I
( e# t. R4 U) s6 L% ]# k 问: 1 ~( T0 j A! x
在Java语言中,如何列出PC机文件系统中的所有驱动器名?
: V# [8 K0 Q. \8 S* j' h7 z
0 G0 Y0 i7 s1 { 答: + {) [3 X/ s! b( L* d
在Java 2版本中,java.io包中的File类新增加了方法listRoots()可以实现这一功能. & u+ f T0 d" g! ]0 H; f
. \" i3 s) X3 N/ I U: j
问: ' o' w9 a, d( S) U9 v: `
为什么Runtime.exec("ls")没有任何输出?
/ \, R0 r( V0 C 4 c( N8 _: a; V( J4 K
答:
. G! R& m1 D2 S 调用Runtime.exec方法将产生一个本地的进程,并返回一个Process子类的实例,该实例可用于控制进程或取得进程的相关信息. 由于调用Runtime.exec方法所创建的子进程没有自己的终端或控制台,因此该子进程的标准IO(如stdin,stdou,stderr)都通过Process.getOutputStream(),Process.getInputStream(), Process.getErrorStream()方法重定向给它的父进程了.用户需要用这些stream来向 子进程输入数据或获取子进程的输出. 所以正确执行Runtime.exec("ls")的例程如下:
: `8 E( D W p/ p# Y7 `) f - H. T6 u$ T \( |/ u% q" A
# {- R) Z+ H& ]+ d8 K: L try
/ R& K$ ^4 [+ P, j. J3 O
2 e3 ]9 K' Z* B k$ c { 5 j; P" z( \0 Z4 i
7 Q- J4 A. I9 u/ b2 _+ c process = Runtime.getRuntime().exec (command); ' j: H8 C& j; U
1 V& ]$ s0 v/ |7 o( _5 a" f4 R InputStreamReader ir=newInputStreamReader(process.getInputStream()); 7 C( j* T& \5 F7 Z! J& g& [5 w3 H
: U7 c; Q( r! r! G" M w8 D2 S( C
LineNumberReader input = new LineNumberReader (ir); 1 `( P, c( C6 _$ v. ?
4 J$ i( ^( X7 }6 J" g n0 L
String line; $ ?3 \3 j- _. [! C5 t+ N' Y4 ]) |
' v% E0 Z* w* T3 X
while ((line = input.readLine ()) != null) & }% v# c. Q. @( {
3 u7 H1 \3 Q- h* z6 D0 \* N9 f
System.out.println(line); / t' Y \' a" X+ P7 s5 W. ]
. p1 l3 o) h( D! x1 ?8 B$ N0 t } + s0 M% e F9 W0 j4 S F
3 {! V1 [5 Z4 e; ~& j! m; E5 N
catch (java.io.IOException e){ W+ F; T" I$ ^( S: X
% ?* q9 W" Y. C( S System.err.println ("IOException " + e.getMessage()); & D/ U8 d. R% Z' ?$ B2 q
8 L$ R$ u( f0 N1 w } / F# Y5 D) ?+ d$ i
0 z: L1 A0 H7 k# t- f 8 k" z2 R) P; s, J- N; C
问:
5 ^* M+ {9 ]+ c4 J 如何产生签名applet,以使applet能够访问本地资源? ( z- V6 n8 {. d! y$ [1 g
, [# A5 P: l1 C" Z0 Q- ]$ T! ?, q 答: 1 [9 m# H" [# z* A- N+ [% J; A) p
在jdk1.1中,可以使用javakey命令来产生公钥,私钥,证书和签名的jar文件,详细资料 请参考: http://java.sun.com/security/usingJavakey.html而java 2对签名机制做了比较大的改进,允许用户更灵活地设置安全权限.Java 2提供了三个工具:keytool,policytool和jarsigner来实现签名applet.例如,Joe编写了一个签名applet:SignedApplet.java,那么产生一个简单的签名applet的过程如下:
+ b/ V* ^' D4 I
- A- r. I7 d% h+ Z3 N9 H$ J* b # D( |- g2 A" l& y- n
//产生密钥,密钥别名为joe,口令为sign12,存放在密钥库joestore中 5 F8 o3 ^1 `* c0 D
3 e: G' d$ H1 J# Z, {. r% l keytool -genkey -alias joe -keypass sign12 -keystore joestore
, Q( T& j/ G2 T* F4 f8 ?
- r& E$ J; [( ]- z //将SignedApplet.class及相关文件打包成jar文件 " q. z" K8 f: ?7 H4 G# |4 B4 }3 [! `
" b4 W! h8 n* }$ l9 v& n jar cvf SignedAppletDemo.jar
' {3 S1 C1 Y( {" x$ u$ h6 r
8 Q) e4 R% ]; Q- L) y( H //利用keytool生成的自签名的证书产生签名applet(jar文件)
* i) U5 Q0 Z9 z l& ^8 u
# h9 U$ k* h" o* r$ C+ B* e jarsigner -keystore joestore -signedjar joe.jar SignedAppletDemo.jar joe 8 N7 P% c/ @3 M; H5 w) p. l7 _
3 ?2 C6 C' a! W0 ~
//将自签名证书从keystore中输出到文件 $ Z& e8 G' b& s' Z
\6 ^5 \- ^) m
keytool -export -keystore joestore -alias joe -file joe.cer
" I0 B) X1 P' X) r6 u
s: p |0 J7 a1 G7 x1 H
( B: A- A+ ?) D& r1 }* b
6 s5 a/ D( S( K0 r7 ~ 而对于签名applet的接受方Susan,需要通过如下步骤来安全地执行
0 R" q( W; K1 D- ]' b# q1 q 6 Q7 a1 J7 z w& g" E9 p7 V
Joe编写的签名applet: $ D' o3 p4 u/ T. n
7 @& p4 }" P$ Z% n6 Q0 P8 ~% f( ^: b# `; g
//得到Joe的证书并将之读入到密钥库中susanstore中 * i" N8 i# C+ Y6 N3 O! E/ n
( H0 d4 Y8 ^$ s! K: Z keytool -import -alias joe -file joe.cer -keystore susanstore
" w5 w" }) I: b$ Y, C- J& F ( X) e2 g* C' [
//运行policytool产生满足Susan要求的policy文件
% M4 H1 W0 l' A6 v8 b2 |
0 u( N. T# Y. ^! j policytool 1 Y" N, G; E$ _* V, B9 v9 z
+ p5 r1 T3 b$ l- ~
//用appletviewer运行之,或在浏览器中安装java plugin来运行之. @$ E( g( h9 r* g9 `; G( B. o8 i
( X- B! j+ f/ O3 D0 ^
$ y% [. M `+ g& Z' u# f: e
% y$ Q: t& o3 g 关于签名applet在Java Plugin中的部署请参考以下网页:
" G4 Y+ G& V1 l' T5 U2 U+ Q* A/ ~
) _7 @4 [' v4 l. l# w4 ` http://java.sun.com/security/signExample12/ / ?. b9 d3 C, k; Z
! @- L G* a( W4 z1 o
& V# `4 ^1 B" d) S/ ]2 L/ c / d+ i6 \* c1 h9 k+ r
注:以上的例子为简单起见,使用了keytool产生的自签名证书.其实,用户也可以
- m9 N" U ]8 \5 z0 V
. Z8 ~$ B( j7 d0 n7 d 使用keytool -certreq向商业CA中心申请电子证书.
- Y- o1 f% J# y7 W ! Q5 q$ K2 k* S" N; w
1 N* j5 b# L: v
D, P- G+ C. \* s0 p a
0 M7 }" l; m+ U' v+ ^ 问:
- m6 S& k; ?8 \ 若通过ObjectOutputStream向一个文件中多次以追加方式写入object,为什么用ObjectInputStream读取这些object时会产生StreamCorruptedException?
# U: y" |# u, f5 d. a4 l& _ 5 L+ a8 [: J2 z" Z' w. w7 T
答:
" J# d+ V0 ]) y 使用缺省的serializetion的实现时,一个ObjectOutputStream的构造和一个ObjectInputStream的构造必须一一对应.ObjectOutputStream的构造函数会向输出流中写入一个标识头,而ObjectInputStream会首先读入这个标识头.因此,多次以追加方式向一个文件中写入object时,该文件将会包含多个标识头.所以用ObjectInputStream来deserialize这个ObjectOutputStream时,将产生StreamCorruptedException.一种解决方法是可以构造一个ObjectOutputStream的子类,并覆盖writeStreamHeader()方法.被覆盖后的writeStreamHeader()方法应判断是否为首次向文件中写入object,羰?则调用super.writeStreamHeader();若否,即以追加方式写入object时,则应调用ObjectOutputStream.reset()方法.
- z% ~5 W, @ B# s( `9 Y; E
: c' Z6 ?) _7 K- I, D$ D2 }* d8 w5 ` 问: , g1 R2 q0 U: k
对象的序列化(serialization)类是面向流的,应如何将对象写入到随机存取文件中?
- P* i. O4 k2 P3 x& g/ n2 I 4 `7 ?3 {9 o2 E/ r5 O+ f
答: 0 E! e1 {3 o" ]! x) @5 g
目前,没有直接的方法可以将对象写入到随机存取文件中.
" H k( R) E* R0 f) C6 I 但是可以使用ByteArray输入/输出流作为中介,来向随机存取文件中写入或从随机存取文件中读出字节,并且可以利用字节流来创建对象输入/输出流,以用于读写对象.需要注意的是在字节流中要包含一个完整的对象,否则读写对象时将发生错误. 例如,java.io.ByteArrayOutputStream可用于获取ObjectOutputStream的字节流,从中可得到byte数组并可将之写入到随机存取文件中.相反,我们可以从随机存取文件中读出字节数组,利用它可构造ByteArrayInputStream,进而构造出ObjectInputStream,以读取对象. / K' F7 s' O6 L5 I5 ]4 R* B) ^
n% g. G5 `( b; \+ F: I+ b
问: " E: }' c5 u* m2 d; C
运行RMI应用时,可不可以不手工启动名字服务rmiregistry,而是从程序中启动之? # T) K M6 f9 Z- G
# [7 J8 r- Y/ E) ]( Y- y: G- L3 X 答: & U3 _, A# G7 B: \
可以. java.rmi包中提供了类java.rmi.registry.LocateRegistry,用于获取名字服务或创建名字服务.调用LocateRegistry.createRegistry(int port)方法可以在某一特定端口创建名字服务,从而用户无需再手工启动rmiregistry.此外,LocateRegistry.getRegistry(String host,int port)方法可用于获取名字服务. ; I" K" b6 C9 w4 P* C1 t2 i
/ i" Q5 q8 k" u7 X
问: ! H+ F6 l. N; d& ]" ]# ]9 @
使用类PrintJob进行打印操作时,应如何设置打印机名等打印属性? 0 a7 K" C4 t9 l7 n
) g+ P- Z3 F1 ] V6 o
答: 1 ?; C' s) O- h! C
使用如下方法可以获得PrintJob的实例用于控制打印操作:
3 I" d& x( \! P . ? @7 e$ ?5 e; w, ~" i- U+ A
/ q- Z, L" \" ]5 F } Toolkit.getPrintJob(Frame f, String jobtitle, Properties prop)
4 C3 _0 H3 z7 O p1 v 7 ]9 O% D$ w' F6 z s9 c
那么对于打印属性的设置可以通过对prop的属性设置来实现,打印属性包括: A9 k0 }% a% }+ t& }) W+ D
/ w. ^6 x3 W/ n* ^ r4 ]) m
awt.print.destination: 可以是"printer"或"file"
5 @0 E- |! H/ P- d
. X9 C' m1 D' R D) Y# E awt.print.printer: 打印机名
% A+ S* N1 J9 X/ H& E/ C3 {( K" f% `: p
: Y. r* }, L; N4 z* V6 V* ^ awt.print.fileName: 打印文件名
5 H$ c, h# y6 t9 Z3 r& F & |5 C8 P, m3 R$ p1 I2 P
awt.print.numCopies: 打印份数 . I% Y* o( d2 E. B5 ]
6 A0 [. }4 H' D, z8 W awt.print.options: 打印命令的打印选项
# Q2 n, A0 F; h$ {
' I1 ^. Y' s4 S1 L- D+ C awt.print.orientation: 打印方向,可以是"portrait"或"landscape"
; }, V. B6 R& Q% W, p5 \, k 2 g* a" u8 `* ]. s
awt.print.paperSize: 纸张大小,可以是"letter","legal","executive"或"a4"
1 j* p ?$ h' e% u( E4 z& W. K % Y6 u. e' {6 \) k& Y
# k; p% V4 m& Z$ ~- O7 T+ }6 d
. D. g& ?8 }* m z
: Q* u- f' S3 H5 Z; Z! u
8 w' G! p$ ~9 L$ I" q( G5 f
% p' ]; W* E5 _, `- h: _, x! d 问: ( Z, Q" @( N" ~% _: Y) d3 Y
在JDK1.1中Thread类定义了suspend()和resume()方法,但是在JDK1.2中已经过时,应使用什么方法来替代之?
# {6 o* o5 I$ x% Q% i - k& v3 N' I" T0 T0 u% ?* n
答: : U" [0 n; C6 B1 d6 _$ Z
Thread.suspend本身易于产生死锁.如果一个目标线程对某一关键系统资源进行了加锁操作,然后该线程被suspend,那么除非该线程被resume,否则其它线程都将无法访问该系统资源.如果另外一个线程将调用resume,使该线程继续运行,而在此之前,它也需要访问这一系统资源,则将产生死锁.
( {& O& _9 G! u, o5 F) O; p5 T8 L 5 n Z* H% ^( p% \# p
因此,在Java 2中,比较流行的方式是定义线程的状态变量,并使目标线程轮询该状态变量,当状态为悬挂状态时,可以使用wait()方法使之处于等待状态.一旦需要该线程继续运行,其它线程会调用notify()方法来通知它. ; s0 P: e' ?% o$ B; w
" Z: ?$ @) O. N* A/ f) x3 r 问: 4 c, b( g' T e9 t5 a B* i
使用JDBC编程,应如何控制结果集ResultSet的指针,使之能够上下移动,以及移动到结果集的第一行和最后一行?
/ S2 O1 c( U y U6 ~) @* M + v! u& {2 ?+ h& {# t$ w
答:
2 B6 R7 ^9 ^7 d* i! W" O& Q 在JDK1.1中,ResultSet类中只定义了next()方法支持数据指针的下移.但在Java 2中,ResultSet类增加了如下方法支持数据指针的移动,包括:
7 H$ S4 y# R. {% ?$ k
' b7 u1 x6 q( {& r) ?
8 x7 w6 [. ~) w ResultSet.first():将数据指针移到结果集的第一行
: a. W; ]; ^) G+ [) Q* N
5 r# J. x8 \, P# j! Q7 T ResultSet.last(): 将数据指针移到结果集的最后一行 6 d- @+ @1 y' n# B
8 _: I. \+ E% S) G4 ^ ResultSet.previous(): 将数据指针上移一行
$ ^& G( D$ w! t) h9 y' k6 b
8 L9 r9 C. C, L& b3 k' |. ?2 c% T 7 l c* F- A# V. L) e
以上的方法定义在JDBC2.0的规范中,所有支持JDBC 2.0的JDBC驱动程序都可以支持上述方法.目前Intersolv和OpenLink等JDBC驱动程序厂商均有产品支持JDBC 2.0 . 4 h% X$ }. g9 ^ `% ]; s
- V% }# Z6 w, o. M1 n( `- C4 V
* {' [1 x) W9 o, D% p( F 问:
. H3 v+ x: L) F' D 哪几种Web Server支持Servlet?如何使IIS支持Servlet?
; d" t6 K. z5 N$ b. X* v 6 F# X0 `$ k% b3 S
答: 1 n4 P: Z- I: c3 t2 H9 _
目前,支持Servlet的服务器端产品主要有: Sun公司的Java WebServer,Lotus DominoGo WebServer,BEA weblogic Tengah Server,Jigsaw,NetForge,AcmeServer和Mot Bays Jetty等.
) b( Y" p6 k% v6 C( D. c6 ]+ c/ T+ X - n- n0 e. Y0 G. E
此外,一些第三方厂商也开发了Servlet engine,以使其它WebServer(如Netscape Web Server,IIS等)能够运行Servlet,如LiveSoftware的Jrun(http://www.livesoftware.com/ products/jrun/)等.
2 a, p% G+ |, q% { 0 |$ @- j, Z9 o$ p5 b- t
问:
5 H6 k* m, c% Y 如何在Java应用中将图像存储到图像文件中? 0 s6 \; s0 P' C6 K
: j( t" h! f2 d' S8 D) q* Q 答: ( k/ E/ K" x. S; P; } B
Java Advanced Imaging API(包含在Java Media API中)允许在Java应用中执行复杂的,高性能的图像处理.JAI API提供了存储图像的能力.目前,JAI API支持以下几种图像文件格式:BMP,JEPG,PNG,PNM,TIFF.下面给出了将图像存储到BMP文件的一段代码: 6 {9 ]5 u5 J G. W+ |( F
& [1 @- j8 m0 I9 c q , q3 P& [ l* ~. m$ _$ t
OutputStream os = new FileOutputStream(fileToWriteTo); - Y$ z6 _5 d1 \/ J4 x
! p. k- g0 I, W9 z2 S8 m9 X' G6 J
BMPEncodeParam param = new BMPEncodeParam();
& `- p- E4 y1 r) X Y3 i/ f 6 K a/ A* J3 R9 {# h' b" Q1 J
ImageEncoder enc = ImageCodec.createImageEncoder("BMP", os, param); ' f: W) J2 A! I. v# {& R
( a5 q/ c, m: X2 [ enc.encode(img); ; G8 g7 m; t6 o
4 [+ V+ |/ z2 ]8 ^& V7 l! z- I7 p' c7 }
os.close(); " t7 b- n G* Y) |8 h3 O: y, l
2 m' `' I v: E7 B3 o: |2 x& }$ ?) C
有关存储图像文件的编程指南请参考以下网页:
; T. u( a% w% T4 ` * d) r* F5 @. A2 D2 l; q% V
http://java.sun.com/products/java-media/jai/forDevelopers/jai-guide/ s, @( e) B1 r4 p& b Y
$ K$ ^& S: t; ~) j3 l9 _( m
4 D6 R6 H' g8 ? ; _3 L, U7 i: q; }( }
. X( W. w. H* V, D" x5 T, K3 X 问:
$ V5 H) X! h/ D/ z+ N, H 如何用Java语言向串口读写数据? font>
; s# ` O; I5 s; A& @
4 l5 q2 ~* Q' J6 ^ 答:
+ N7 U6 W4 v8 a2 r& F Sun公司的Java Communication API2.0可用于读写串口,它支持RS232串口和IEEE 1284 并口,提供了一种与平台无关的串/并口通信机制.
S, Z5 U! k3 `
$ Q3 ]! \4 N v! s& Z% u5 y# Y 详细文档,请访问:<a href="http://java.sun.com/products/javacomm/" target="_blank" >http://java.sun.com/products/javacomm/</A>
zan