最近,在这里看到了几篇关于在applet中使用jdbc访问数据库的帖子,觉得大侠们有的回复很绝对,说applet不能访问数据库,不敢苟同,于是参照sun的网上教程"[url=http://cn.sun.com/developers/onlinetraining/programming/basicjava1/data.html]java程序设计语言基础: 实践指南,第1部分[/url]",做了一些实验,总结出来与大家分享,也请多多指教。
实验环境
db server #1: solairs 8 + oracle 8.1.7 + apache
db server #2: solairs 8 + oracle 8.1.7
client: windows2000 sp4 + j2se1.4.1 + oracle jdbc driver
实验中使用的数据表的结构
table dba (
text varchar2(100),
primary key (text)
)
applet的源代码
import java.awt.color;
import java.awt.borderlayout;
import java.awt.event.*;
import java.applet.applet;
import javax.swing.*;
import java.sql.*;
import java.net.*;
import java.io.*;
public class dbaappl extends applet implements actionlistener {
jlabel text, clicked;
jbutton button, clickbutton;
jtextfield textfield;
private boolean _clickmemode = true;
private connection c;
final static private string _driver = "oracle.jdbc.driver.oracledriver";
final static private string _url = "jdbc:oracle:thin:username/password@(description=(address_list=(address=(protocol=tcp)(host=developer)(port=1521)))(source_route=yes)(connect_data=(sid=ansid)))";
public void init(){
setbackground(color.white);
text = new jlabel("text to save to file:");
clicked = new jlabel("text retrieved from file:");
button = new jbutton("click me");
button.addactionlistener(this);
clickbutton = new jbutton("click again");
clickbutton.addactionlistener(this);
textfield = new jtextfield(20);
setlayout(new borderlayout());
setbackground(color.white);
add(borderlayout.north, text);
add(borderlayout.center, textfield);
add(borderlayout.south, button);
}
public void start(){
system.out.println("applet starting.");
}
public void stop(){
system.out.println("applet stopping.");
}
public void destroy(){
system.out.println("destroy method called.");
}
public void actionperformed(actionevent event){
try{
class.forname (_driver);
c = drivermanager.getconnection(_url);
}catch (java.lang.classnotfoundexception e){
system.out.println("cannot find driver");
system.out.println(e.getmessage());
}catch (java.sql.sqlexception e){
system.out.println("cannot get connection");
system.out.println(e.getmessage());
}
object source = event.getsource();
if(source == button){
if(_clickmemode){
jtextarea displaytext = new jtextarea();
try{
//write to database
string thetext = textfield.gettext();
statement stmt = c.createstatement();
string updatestring = "insert into dba values ('" + thetext + "')";
int count = stmt.executeupdate(updatestring);
//read from database
resultset results = stmt.executequery("select text from dba ");
while(results.next()){
string s = results.getstring("text");
displaytext.append(s + "/n");
}
stmt.close();
}catch(java.sql.sqlexception e){
system.out.println("cannot create sql statement");
system.out.println(e.getmessage());
}
//display text read from database
text.settext("text retrieved from file:");
button.settext("click again");
_clickmemode = false;
//display text read from database
} else {
text.settext("text to save to file:");
textfield.settext("");
button.settext("click me");
_clickmemode = true;
}
}
}
}
运行此applet的html文件dbaappl.html
<html>
<body>
<applet code=dbaappl.class
width=200
height=100>
</applet>
</body>
</html>
首先,dbaappl.java中_url串指定的是与web server在同一台主机上(server1)的oracle,编译后把dbaappl.class和dbaappl.html
一起放在web server的同一目录下,在客户机的浏览器里访问dbaappl.html,查看java控制台,得到如下信息
cannot find driver
oracle.jdbc.driver.oracledriver
java.lang.nullpointerexception
这一出错信息的意思是,drivermanager 已在 applet html和类文件所在的目录以及当前jre使用的本地classpath中没有找到 jdbc 驱动程序。
解决办法,将jdbc 驱动程序oracle-jdbc-driver.jar文件放在客户机当前使用的jre的${jre_home}/lib/ext目录下,或者用jar工具将oracle-jdbc-driver.jar解压,把解压后得到的oracle目录也放在web server上applet所在
的目录中。
更正后,重新访问dbaappl.html,查看java控制台,得到如下信息
java.security.accesscontrolexception: access denied(java.net.socketpermission server1 resolve)
这个错误的通知你访问被拒绝。这就是说,由于 applet 程序试 图在没有获得正确的权限的情况下访问系统资源,括号中代码表示,若要纠正这种情况,您需要一个向数据库所在计算机(主机名为server1) 授予 applet 访问权限的 socketpermission。
解决办法,利用 policy 工具生成你所需要的策略文件,或者用一个 ascii 编辑 器生成该策略文件。
下面的代码是名为 dbaapplpol 的、获得上述权限的策略文件的内容
grant {
permission java.net.socketpermission "server1", "resolve";
};
创建了策略文件后,还要修改${jre_home}/lib/security/java.security文件
在
policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy
下添加一行
policy.url.3=file:/path/to/dbaapplpol
再次访问dbaappl.html,成功运行。
再将dbaappl.java中_url串改为指定另一台主机(server2)上的oracle,编译,上传,访问得到如下错误信息
java.security.accesscontrolexception: access denied(java.net.socketpermission 10.6.1.16:1521 connect,resolve)
这回的意思是需要一个允许在数据库所在的server2上访问ip地址和端口的socketpermission。在前面生成的策略文件中加入
permission java.net.socketpermission "10.6.1.16:1521", "connect, resolve";
后,成功运行。
总结一下,通过applet访问数据库不是不可以的,但确实不太方便,某些特殊环境下可能值得使用。
客户端要有jre支持,可以在客户机访问applet所在页面是提示安装java plug-in,这样的页面可以通过htmlconvert工具生成
jdbc驱动要么放在客户机jre的classpath下,要么与applet放在一起,注意如果驱动是jar文件的话,要解开
通过设置正确的策略文件,applet不仅可以访问与自己在同一台机器上的数据库,也可以访问其他远程数据库。不过,需要每个想要成功运行applet的客户机修改其本地jre的java.security文件
闽公网安备 35060202000074号