用JDK1.4开发数字签名的Swing Applet
1) 写代码
我们准备开发一个既是APPLET又是APPLICATION的程序,使得程序既能在浏览器中运行,直接双击JAR文件也可以运行。
程序界面采用了SWING控件,使用JInternalFrame来展示通过文件选择框指定的GIF或JPG图片。
程序文件:Jtest.java, ExampleFileFilter.java。
程序编译完成后,假定所有的class文件位于d:\myapplet下面。2)生成jar文件
创建一个manifest.mf文件位于d:\myapplet下面,文件内容:
Manifest-Version: 1.0
Main-Class: Jtest
Created-By: 1.4.0-beta2 (Sun Microsystems Inc.)
执行命令:jar cvfm manifest.mf Jtest.jar *.class
则生成Jtest.jar文件,此时双击该文件即能以application的形式运行。3)准备HTML文件
创建一个HTML文件Jtest.htm, 位于d:\myapplet下面,文件内容:
<HTML>
<HEAD>
</HEAD>
<BODY >
<CENTER>
<APPLET code= "Jtest.class" codebase= "." archive ="Jtest.jar" width= 0 height="0">
</APPLET>
</CENTER>
</BODY>
</HTML>
然后需要使用JDK1.4附带的HtmlConverter.exe转换Jtest.htm,使得浏览器能自动下载SUN的JRE1.4。
执行命令:htmlconverter Jtest.htm,生成的Jtest.htm自动包含了下载插件的代码。4) 数字签名
首先是生成公/私密钥对:
keytool –genkey –alias yourname –keypass yourpassword
其中的yourname为密钥的别名,yourpassword为密码,按照提示输入签名信息。然后执行:如果需要导出证书,则执行命令:
keytool –export –alias yourname –file yourname.cer
生成的yourname.cer即为证书文件。不过签名APPLET可以不需要这一步。然后就是对JAR文件进行签名:
jarsigner Jtest.jar yourname
需要输入你在上面步骤中提供的密码。至此签名已经成功。无论是直接打开Jtest.htm文件还是通过服务器下载Jtest.htm和Jtest.jar执行applet,首先会弹出一个提示框,如果用户点接受,则APPLET可以访问本地文件系统以及做其它事情,如果点拒绝则不能访问本地文件系统。当然,如果点总是接受,则以后运行同一个APPLET的时候不会出现提示,自动拥有权限。
1) 写代码
我们准备开发一个既是APPLET又是APPLICATION的程序,使得程序既能在浏览器中运行,直接双击JAR文件也可以运行。
程序界面采用了SWING控件,使用JInternalFrame来展示通过文件选择框指定的GIF或JPG图片。
程序文件:Jtest.java, ExampleFileFilter.java。
程序编译完成后,假定所有的class文件位于d:\myapplet下面。2)生成jar文件
创建一个manifest.mf文件位于d:\myapplet下面,文件内容:
Manifest-Version: 1.0
Main-Class: Jtest
Created-By: 1.4.0-beta2 (Sun Microsystems Inc.)
执行命令:jar cvfm manifest.mf Jtest.jar *.class
则生成Jtest.jar文件,此时双击该文件即能以application的形式运行。3)准备HTML文件
创建一个HTML文件Jtest.htm, 位于d:\myapplet下面,文件内容:
<HTML>
<HEAD>
</HEAD>
<BODY >
<CENTER>
<APPLET code= "Jtest.class" codebase= "." archive ="Jtest.jar" width= 0 height="0">
</APPLET>
</CENTER>
</BODY>
</HTML>
然后需要使用JDK1.4附带的HtmlConverter.exe转换Jtest.htm,使得浏览器能自动下载SUN的JRE1.4。
执行命令:htmlconverter Jtest.htm,生成的Jtest.htm自动包含了下载插件的代码。4) 数字签名
首先是生成公/私密钥对:
keytool –genkey –alias yourname –keypass yourpassword
其中的yourname为密钥的别名,yourpassword为密码,按照提示输入签名信息。然后执行:如果需要导出证书,则执行命令:
keytool –export –alias yourname –file yourname.cer
生成的yourname.cer即为证书文件。不过签名APPLET可以不需要这一步。然后就是对JAR文件进行签名:
jarsigner Jtest.jar yourname
需要输入你在上面步骤中提供的密码。至此签名已经成功。无论是直接打开Jtest.htm文件还是通过服务器下载Jtest.htm和Jtest.jar执行applet,首先会弹出一个提示框,如果用户点接受,则APPLET可以访问本地文件系统以及做其它事情,如果点拒绝则不能访问本地文件系统。当然,如果点总是接受,则以后运行同一个APPLET的时候不会出现提示,自动拥有权限。
Url url = new Url(getCodeBase()+"xxx"); //得到文件xxx的url
InputStream ins = url.openStream();
//如果xxx是txt、html等纯文本文件,最好加上下面代码来读取,
//不然可能会丢失某些字节
InputStreamReader isr = new InputStreamReader(ins);
BufferedReader reader = new BufferedReader(isr);
String line;
StringBuffer sb = new StringBuffer();
while ( (line = reader.readLine()) != null) { //每次读取一行
sb.append(line + "\n"); //readLine()方法不读取回车符"\n",所以要加上
}
这里用getCodeBase()方法取得的url是指向applet所在的服务器的,所以可以读取到文件xxx,如果你用别的服务器url替代,系统会认为applet想访问别的主机,超出了安全限制,抛出安全异常。
不同的测试方法中,用的工具不同,getCodeBase()得到的值也会不同,例如如果在本地测试,用appletviewer会得到"X:\tomcat\webapps\myApp\xxx",如果用jsp调用applet,会得到"http://localhost:8080/myApp/xxx"
import java.awt.*;
import java.io.*;
import java.net.*;public class ReadTxt extends Applet{
StringBuffer sb=new StringBuffer();
public void run(){
URL url=null;
try{
url = new URL(getCodeBase()+"xxx.txt"); //得到文件xxx的url
}
catch(MalformedURLException e){
e.printStackTrace();
}
try{
InputStream ins = url.openStream();
//如果xxx是txt、html等纯文本文件,最好加上下面代码来读取,
//不然可能会丢失某些字节
InputStreamReader isr = new InputStreamReader(ins);
BufferedReader reader = new BufferedReader(isr);
//StringBuffer sb = new StringBuffer();
String line;
while ( (line = reader.readLine()) != null) { //每次读取一行
sb.append(line + "\n"); //readLine()方法不读取回车符"\n",所以要加上
}
}
catch(IOException e){
e.printStackTrace();
}
}
public void paint(Graphics g){
g.drawString(sb.toString(),20,20);
}}
//ReadTxt.java代码:
import javax.swing.*;
import java.awt.*;
import java.net.*;
import java.io.*;public class ReadTxt extends JApplet{
private Color stringColor = new Color(255,204,102);
private String lastTime = "";
StringBuffer sb = new StringBuffer(); public void init(){
getTxt();
setBackground(Color.black);
} private void getTxt(){
URL url = null;
try {
url = new URL(getCodeBase() + "xxx.txt"); //得到文件xxx的url
}
catch (MalformedURLException e) {
e.printStackTrace();
}
try {
InputStream ins = url.openStream();
//如果xxx是txt、html等纯文本文件,最好加上下面代码来读取,
//不然可能会丢失某些字节
InputStreamReader isr = new InputStreamReader(ins);
BufferedReader reader = new BufferedReader(isr);
System.out.println("读取前sb的长度:"+sb.length());
String line;
while ( (line = reader.readLine()) != null) { //每次读取一行
sb.append(line + "\n"); //readLine()方法不读取回车符"\n",所以要加上
}
System.out.println("读取后sb的长度:"+sb.length());
}
catch (IOException e) {
e.printStackTrace();
} }
public void paint (Graphics screen){
Graphics2D screen2D = (Graphics2D)screen;
screen2D.setColor(stringColor);
screen2D.drawString(sb.toString(), 20, 50);//由于是画出来的,所以会显示成一行
}
}ReadTxt.html代码:
<html>
<head>
<title>
HTML Test Page
</title>
</head>
<body>
看结果<br><applet codebase = "." code = "ReadTxt.class" name = "TestApplet" width = "750"
height = "500"
hspace = "0"
vspace = "0"
align = "middle"
>
</applet>
</body>
</html>把ReadTxt.java、ReadTxt.html和xxx.txt放在同一目录下测试
你编的那段程序思路是对的,但public void run()应该改为public void init()
这样才能初始化啊。
ReadTxt.html和xxx.txt必须放在同一目录下,因为getCodeBase()取得的是ReadTxt.html的路径,这个路径不一定和ReadTxt.class所在的路径相同,因为ReadTxt.class可以放在包里。
别的小节上你自己慢慢调吧,语法不懂就查资料,我也是都是这样一步一步摸索过来的。
把run改成init就可以读了。