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