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