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