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