JDBCapplet
假设Coffee Break的老板想在Web页上的applet中显示当前的咖啡价格。让applet直接从数据库提取价格,他就可以确信显示的是最新价格。 为此需要创建两个代码文件,一个保存applet代码,一个保存HTML代码。applet代码包含一般程序都有的JDBC代码以及运行applet和显示数据库查询结果的附加代码。本例中applet代码保存在OutputApplet.java文件中。为在HTML页中显示applet,文件OutputApplet.html会告诉浏览器要显示的内容及显示的位置。 本节其余部分讲述applet代码中的各种元素,它们在独立应用程序中是不会出现的。其中某些元素包括了Java程序设计语言的一些高级特性。这里给出了一些基本原理和基本解释,但对它们的完全解释超出了本教程范围。为完成该示例applet,只需掌握一般的思想,因此不用担心没有完全了解。您可用该applet代码作模板,将查询替代为自己的即可。 编写applet代码 编写代码前,applet导入独立应用程序没有用到的一些类。applet导入了applet特有的两个类:Applet类(java.applet包的一部分)和Graphics类(java.awt包的一部分)。applet还导入了通用的java.util.Vector类以便访问类似于数组、大小可修改的容器。这些代码使用Vector对象保存查询结果以在后面显示。 所有的applet扩展了Applet类;换言之,它们是Applet的子类。因此每个appplet定义必须包含extends Applet字样,如下所示: public class MyAppletName extends Applet { . . . } 在applet例子OutputApplet中,这行代码也包括implements Runnable字样,实际代码如下: public class OutputApplet extends Applet implements Runnable { . . . } Runnable是一个接口,它允许一次运行多个线程。线程是连续的控制流,程序可以是多线程的,换言之,很多线程并发地处理不同事情。OutputApplet类通过定义run方法——Runnable中的惟一方法来实现Runnable接口。本例中run方法包含有如下用途的JDBC代码:打开连接、执行查询及从结果集中检索结果。由于数据库连接可能较慢,有时需几秒钟,通常好的想法是构建一个applet以使用不同线程处理数据库工作。 与独立应用程序(需要一个main方法)类似,一个applet至少要实现一个init、start或paint方法。示例applet定义了一个start方法和一个paint方法。每次调用start时就会创建一个新线程(名为worker)以重估数据库查询。每次调用paint时要么显示查询结果,要么显示描述当前applet状态的字符串。 如前所述,OutputApplet中定义的run方法包含了JDBC代码。当线程worker调用start方法时就会自动调用run方法执行线程worker中的JDBC代码。run方法中的代码与其他示例代码中看到的带有3个异常的代码非常相似。首先它使用Vector类保存查询结果。第二它没有输出结果,而是把结果添加到Vector results中以在后面显示。第三它同样没有输出异常,而是记录错误消息以在后面显示。 applet使用各种方式描绘/显示内容。该applet是一个仅有文本的简单applet,使用drawString方法(Graphics类的一部分)显示文本。drawString方法带有3个参数:(1) 要显示的字符串;(2) x坐标——指出显示字符串的横向起点;(3) y坐标——指出显示字符串的纵向起点(这在文本下面)。 OutputApplet.java中的paint方法调用drawString方法在屏幕上实际显示内容。drawString主要显示Vector results中的数据(存储的查询结果)。当没有查询结果时,drawString将显示String message的当前内容。这个字符串将以“Initializing”开始。当调用start方法时,这个字符串设为“Connecting to database”;当碰到一个异常时,setError方法就将它设为错误消息。因此,如果数据库连接要开销一定时间,applet浏览者将会看到消息“Connecting to database”,这就是message那时的内容(当AWT要applet在屏幕上显示它的当前状态时,AWT就会调用paint方法)。 OutputApplet类中定义的最后两个方法setError和setResults是专用的,这表明它们只可让OutputApplet使用。这两个方法都调用了repaint方法以清除屏幕和调用paint。因此如果setResults调用repaint,将显示查询结果;如果setError调用repaint,将显示错误消息。 最后,OutputApplet中定义的所有方法(除run方法外)都是同步的(synchronized)。关键字synchronized表明当一个方法访问一个对象时,其他的同步方法将不可再访问那个对象。方法run没有声明为同步,因此applet仍可以在处理数据库连接时在屏幕上描绘自己。如果数据库访问方法是同步的,那么在执行期间会阻止重画applet,这就可能导致延迟,且不会显示任何相关的状态消息。 总之,好的编程习惯是在applet中做一些独立应用程序不需做的事情: 将JDBC代码放入独立的线程。 延迟期间在屏幕上显示状态消息(如在连接数据库时开销较长时间)。 在屏幕上显示错误消息,而不是将它们输出到System.out或System.err。 运行Applet 在运行示例applet前需要编译文件OutputApplet.java。编译创建了可在OutputApplet.html文件中引用的OutputApplet.class文件。 运行applet最容易的方式是使用applet查看器(JDK的一部分)。只要使用下面各种平台下的指令就可以编译和运行OutputApplet.java: UNIX javac OutputApplet.java appletviewer OutputApplet.html Windows 95/NT javac OutputApplet.java appletviewer OutputApplet.html 在网上加载applet有着安全方面的限制。尽管这会显得麻烦,但对于网络安全是绝对必要的,安全是Java程序设计语言的一个主要优点。除非浏览器允许网络连接,否则applet只可对它的源主机进行网络连接。一台主机是否认为本地安装的applet是“信任的”,这取决于浏览器上设置的安全限制。applet通常不能读/写在执行它的主机上存放的文件,也不可加载库和定义本地方法。 通常applet可对它们的源主机进行网络连接,因此它们可在Intranet上很好地运行。 JDBC-ODBC Bridge驱动程序有点例外。它可以非常成功地用于Intranet访问,但它要求在每个客户端上安装ODBC、桥、桥本地库和JDBC。使用这种配置就可在Java程序和信任的applet中进行Intranet访问。由于桥要求特殊的客户端配置,所以在使用JDBC-ODBC Bridge驱动器的Internet上运行applet很不实际。这是JDBC-ODBC Bridge而不是JDBC的一个局限。如果使用纯Java JDBC驱动程序,不必做任何特殊配置就可在Internet上运行applet。 |