X-Spirit的陋室铭

生活有的时候面临许多选择,这些选择让人困惑。 生活有的时候没有任何选择,这个时候让人压抑。 但无论生活有没有给你选择,你只能做一件事情: 排除困难,勇往直前!

2007年6月9日星期六

用JSP实现基于Web的RSS阅读器

一: RSS介绍

根据维基百科(http://zh.wikipedia.org/wiki/RSS)的定义,"RSS是一种用于共享新闻和其他Web内容的数据交换规范 ",它是一系列的规范的组合,采用Xml格式。目前国内RSS应用最多的是在新闻网站和博客网站上。

许多网站可以用RSS阅读器来个性化自己的网页,比如显示最新的新浪新闻,显示自己好朋友最新的博客文章,显示最新的Google论坛内容。除此之外,利用RSS阅读器还可以实现其它用途,比如:

获得天气预报

接收邮件,比如Gmail就提供RSS feed

获取最新股票行情

获取音乐,电台节目和视频剪辑等等

二:Rome介绍

这篇文章采用Rome这个开源工具来实现RSS阅读器。Rome支持的格式很多,有RSS 0.90, RSS 0.91.Netscape, RSS 0.91 Userland, RSS 0.92, RSS 0.93, RSS 0.94, RSS 1.0, RSS 2.0, Atom 0.3, Atom 1.0 等等,几乎囊括了目前所有的RSS 和atom版本。最新的Rome版本可以从 http://wiki.Java.Net/bin/view/JavawsXml/Rome上得到。


实现RSS阅读器,主要采用Rome的解析功能,就是从Xml文件中读出相应的内容。我用一些简单代码来说明如何使用Rome中的类和方法。


URL feedUrl = new URL("http://rss.sina.com.cn/news/marquee/ddt.Xml");

SyndFeedInput input = new SyndFeedInput();

SyndFeed feed = input.build(new XmlReader(feedUrl));
 

表一: 得到RSS Feed


"http://rss.sina.com.cn/news/marquee/ddt.Xml"是新浪新闻的一个RSS 地址。通过三行代码,就可以得到一个对应这个地址的RSS Feed对象。这个对象包含我们所需要的所有RSS内容。如果用System.out.println(feed),会得到表二中的结果。从中可以清楚地看到 SyndFeed类的结构。


SyndFeedImpl.contributors=null

SyndFeedImpl.title=新闻中心-新闻要闻

SyndFeedImpl.categories[0].name=

SyndFeedImpl.categories[0].taxonomyUri=null

SyndFeedImpl.link=http://news.sina.com.cn/iframe/o/allnews/input/index.htm

SyndFeedImpl.publishedDate=Thu Jun 22 13:20:01 CST 2006

SyndFeedImpl.entries[0].updatedDate=null

SyndFeedImpl.entries[0].contributors=null

SyndFeedImpl.entries[0].title=扎瓦赫里在录像带中呼吁阿富汗人抵抗外国侵略

SyndFeedImpl.entries[0].categories[0].name=

SyndFeedImpl.entries[0].categories[0].taxonomyUri=null

SyndFeedImpl.entries[0].link=http://news.sina.com.cn/w/2006-06-22/11569270955s.shtml

SyndFeedImpl.entries[0].publishedDate=Thu Jun 22 11:56:00 CST 2006

SyndFeedImpl.entries[0].authors=null

SyndFeedImpl.entries[0].modules[0].descriptions=[]

SyndFeedImpl.entries[0].modules[0].creators[0]=WWW.SINA.COM.CN

SyndFeedImpl.entries[0].modules[0].contributors=[]

......

SyndFeedImpl.author=null

SyndFeedImpl.copyright=Copyright 1996 - 2005 SINA Inc. All Rights Reserved
 

表二: SyndFeed数据结构


从上述输出结果可以看出,每个新闻条目是由entry代表的。下列代码从feed中得到entry

List list = feed.getEntries();

for (int i=0; i< list.size(); i++) {

SyndEntry entry = (SyndEntry)list.get(i);

}
 

表三:从SyndFeed中得到SyndEntry


如果程序位于防火墙后面,就需要在程序中加上一些Proxy设置。例如采用下面的http proxy:

Properties systemSettings = System.getProperties();

systemSettings.put("http.proxyHost", "myproxyserver.com");

systemSettings.put("http.proxyPort", "80");

System.setProperties(systemSettings);
 

表四:Proxy设置

有时候,可能会遇到"Java.io.IOException: Server returned HTTP response code: 403 for URL"的错误信息。通常是因为服务器的安全设置不接受Java程序作为客户端访问,解决方案是设置客户端的User Agent, 示例代码如下:

URLConnection feedUrl = new jURL(urlStr).openConnection();

feedUrl.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

SyndFeedInput input = new SyndFeedInput();

SyndFeed feed = input.build(new XmlReader(feedUrl));
 

表五:设置User-Agent


ROME 提供的功能很多,除了可以解析Feed 外,还可以生成Feed。用Rome来为自己的网站内容创建RSS Feed,这样别人就可以通过RSS 阅读器来随时了解你网站内容的更新了。


使用ROME需要两个条件:

Java SE 1.4以上的版本,下载地址: http://Java.sun.com/

开源软件JDOM,下载地址:http://www.jdom.org/


三:.NetBeans快速开发一个简单实例

下面用一个简单的实例原型开发步骤来显示如何快速地利用Rome.NetBeans来构建一个基于Web的RSS阅读器。

.NetBeans是一个开源的Java IDE软件,下载地址:http://www.Netbeans.org。选.NetBeans是因为它内置Tomcat,可以节省很多配置和运行的时间。而且功能强大,可以高效完成Java SE, Java EE 以及Java ME等各种应用程序的开发。


.NetBeans 5.0 创建 Web Project。

打.NetBeans, 选择菜单"文件->新建项目",在新建项目窗口中,"类别"选择"Web",项目选择"Web应用程序",点击"下一步"。在"新建Web应用程序"窗口中,输入项目名称,比如"webrssreader"和项目位置,其余采用缺省,点击"完成"。

.Net/XrssFile/2006-7/1/200671102111235.jpg" width=618 align=left border=0 name=graphics1>
图一: 创建.NetBeans的Web项目

在新建立的"webrssreader"项目中,加入两个jar文件:

jdom.jar:JDOM开源项目中(http://www.jdom.org/

rome.jar : ROME开源项目中(Java.Net/bin/view/JavawsXml/Rome">http://wiki.Java.Net/bin/view/JavawsXml/Rome

.Net/XrssFile/2006-7/1/200671102111550.jpg" width=618 align=left border=0 name=graphics2>
图二:添加库文件

在index.jsp中加入代码

<%@page contentType="text/html"%>

<%@page pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Sina News</title>

</head>

<body>

<%

Java.util.Properties systemSettings = System.getProperties();

systemSettings.put("http.proxyHost", "mywebcache.com");

systemSettings.put("http.proxyPort", "8080");

System.setProperties(systemSettings);

String urlStr = "http://rss.sina.com.cn/news/marquee/ddt.Xml";

Java.Net.URLConnection feedUrl = new Java.Net.URL(urlStr).openConnection();

feedUrl.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

com.sun.syndication.io.SyndFeedInput input = new com.sun.syndication.io.SyndFeedInput();

com.sun.syndication.feed.synd.SyndFeed feed = input.build(new com.sun.syndication.io.XmlReader(feedUrl));

%>

<div align="center">

<h1><%=feed.getTitle()%></h1>

<table border=1 cellpadding=3 width="700">

<tr>

<th>Number</th>

<th>Title</th>

<th>Time</th>

</tr>

<%

Java.util.List list = feed.getEntries();

for (int i=0; i< list.size(); i++) {

com.sun.syndication.feed.synd.SyndEntry entry = (com.sun.syndication.feed.synd.SyndEntry)list.get(i);

%>

<tr>

<td><%=i+1%></td>

<td><a href="<%=entry.getLink()%>"><%=entry.getTitle()%></a></td>

<td><%=entry.getPublishedDate()%></td>

</tr>

<%}%>

</table>

</div>

<br>

</body>

</html>
 


表六: index.jsp全部源代码

运行项目。鼠标右键点击"webrssreader"项目,选择"运行项目"。

.Net/XrssFile/2006-7/1/200671102112482.jpg" width=618 align=left border=0 name=graphics3>
图三: 运行程序

运行结果如下。

.Net/images/p_blog_csdn.Net/软件更是"人人为我,我为人人"精神的一种体现。很多时候,我们不需要自己从头开发一些工具,站在前人的肩膀上,开发出一些更好的应用也许是程序员们更应该考虑的事情。


作者介绍:

李力目前在Sun Microsystems任高级软件工程师,有近十年软件开发经验,曾就职于AIG,CA等公司,任软件工程师及系统分析员等职位,在J2EE领域有丰富的实际开发经验。联系方式:Ada.Li@Sun.com



--
X-Spirit

毕业设计中。。。

毕业设计真忙碌啊。
 
 
大学时光就这样在忙碌中走到了尽头,就连回味和总结的时间都没有了。。。
 
看看镜中的自己,哪里还找得到一点大学生的样子?完全像个社会上混了好几年的老头。。。
青春就这样消逝了。无声无息。。。
 
然而社会告诉自己:生活却刚刚开始。
是的,生活刚刚开始,可是我已经老了。。。
--
X-Spirit

2007年6月7日星期四

J2SE 6 GUI新特性


Java是一种非常强大的编程语言,但Java的GUI能力一直是它的软肋。虽然Java提供2种图形解决方案,AWT和Swing。但这2种图形库的功能十分有限,使用它们并不能带来更多的用户体验。而且AWT和Swing的更新速度很慢。一直到Java SE 5也没什么明显的变化。幸好Java SE 6终于为它们增加了更强大的功能。有了这些功能,使用AWT和Swing设计的用户界面可以更贴近用户。为了使读者能够更早地体验Java SE 6 GUI的美丽,本文将就Java SE 6 GUI提供的主要功能进行讨论。    显示启动界面

  当我们在设计软件时可能也需要这样一个界面。当然,这在Java SE的早期版本中也可以做到,但比较费劲,基本的实现是将一个图形放到窗体上,然后先显示这个,这需要编写一定的代码,而Java SE 6提供了一个更简单的方法,可以不添加一行代码。  让界面更加绚丽 Java SE 6.0 GUI体验(图二)   系统托盘

  在以前版本(Java SE 5以前)的Java SE中Sun并未提供访问系统托盘的类,在那时使用Java访问系统托盘的唯一方法就是使用JNI直接调用系统API,但这种方法实现比较复杂,而且如果这样做,就破坏了Java的跨平台特性(除非你为每一个操作系统平台都做一个这样的类)。Java的这个缺陷缓和终于在Java SE 6中得到弥补。 让界面更加绚丽 Java SE 6.0 GUI体验(图三)   交互对话框

  在一般的程序语言或开发工具中都有一些标准的对话框以方便和用户交互,如Delphi中有InputBox对话框用来采集用户的输入信息。在Java SE 6中也提供了类似的标准对话框来满足这些需求。     让界面更加绚丽 Java SE 6.0 GUI体验(图四)   图象转换

  Java在图象处理上是比较强大的,但是以前的Java SE版本对于GIF图只能读,不能写。这并不是因为技术原因,而是因为GIF专利的原因。但最近这个专利到期了,因此,在Java SE 6中提供了读写GIF的功能。  

QQRead.com 推出数据恢复指南教程 数据恢复指南教程 数据恢复故障解析 常用数据恢复方案 硬盘数据恢复教程 数据保护方法 数据恢复软件 专业数据恢复服务指南
  显示启动界面

  现在很多商业和非商业软件在启动时都必须初始化,有时初始化的时间会很长,如photoshop、flash等,为了让用户有耐心继续等待,不要误以为死器了,这些软件在初始化之前总是显示一个图形界面来告诉用户软件正在做什么。如图1是Flash8在启动时的初始化界面。

让界面更加绚丽 Java SE 6.0 GUI体验(图五)
图1 Flash8的启动界面
  当我们在设计软件时可能也需要这样一个界面。当然,这在Java SE的早期版本中也可以做到,但比较费劲,基本的实现是将一个图形放到窗体上,然后先显示这个,这需要编写一定的代码,而Java SE 6提供了一个更简单的方法,可以不添加一行代码,而且在界面要改变时还不需要重新编译源程序。让我们先看一个简单的例子。

import javax.swing.*;
import java.awt.*;

public class TestSplash
{
 public static void main(String args[])
 {
  try
  {
   // 为了让启动界面多显示3秒,
   // 如果是正常的程序,这里应该时初始化代码
   Thread.sleep (3000);
   JFrame frame = new JFrame("Java SE 6 启动界面演示");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   JLabel label = new JLabel("我的标签", JLabel.CENTER);
   frame.add(label, BorderLayout.CENTER);
   frame.setSize(300, 95);
   frame.setVisible(true);
  }
  catch (InterruptedException e)
  {}
 }
}
  上面的程序是一个非常简单的界面演示程序,它的界面如图2所示。

让界面更加绚丽 Java SE 6.0 GUI体验(图二)
图2
  如果使用java TestSplash直接运行上面的程序,将立刻显示如图2的界面。Java SE 6在java命令上提供了一个选项,可以在显示程序主界面之前先显示一幅图。

java -splash:splash.gif TestSplash
  如果运行以上的命令,在出现图2所示的界面之前会先显示splash.gif,然后再过几秒钟splash.gif自动关闭,然后会显示主界面。在上面程序中的Thread.sleep (3000); 是为了使splash.gif显示的时间长一些,可以将这句改为直正的初始化代码。splash.gif文件如图3所示。

让界面更加绚丽 Java SE 6.0 GUI体验(图六)
图3 splash.gif
  在发布时一般将程序所用到的.class文件打包成一个或几个.jar文件,如果是这样,可以将splash.gif一同打包在.jar文件中。然后在manifest.mf文件中使用SplashScreen-Image指定启动界面图象。

  在打包之前,先建一个文本文件manifest.mf,内容如下:

Manifest-Version: 1.0
Main-Class: TestSplash
SplashScreen-Image: splash.gif
  然后通过以下命令进行打包:

jar -mcvf manifest.mf Splash.jar TestSplash.class splash.gif
  然后通过如下命令运行程序:

java -jar Splash.jar
  现在我们已经可以显示一个启动界面了,但这只是一幅静态的图,而在大多数时还需要在这幅图上显示一些信息,如正在初始化什么。在Java SE 6也提供了可以操作这幅图的功能。下面的代码演示了如何操作启动界面。

import javax.swing.*;
import java.awt.*;
public class TestSplash
{
 public static void main(String args[])
 {
  try
  {
   String[] info = new String[]
   { "正在初始化API...", "正在初始化网络...", "正在初始化数据库..." };
   SplashScreen splash = SplashScreen.getSplashScreen();
   Graphics g = splash.createGraphics();
   if (splash != null)
   {
    for (int i = 0; i < 3; i++)
    {
     g.setColor(Color.BLACK);
     g.drawString(info[i], 350, 170 + i * 15);
     splash.update();
     Thread.sleep((i + 1)*1000);
    }
   }
   JFrame frame = new JFrame("Java SE 6 启动界面演示");
   frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
   JLabel label = new JLabel("我的标签", JLabel.CENTER);
   frame.add(label, BorderLayout.CENTER);
   frame.setSize(300, 95);
   frame.setVisible(true);
  }
  catch (Exception e)
  {}
 }
}
  上面的代码SplashSreen获得启动界面,然后再通过createGraphics得到一个图形句柄。本例将在启动界面显示按一定时间间隔显示三个字符串,这三个字符串保存在info数组中。启动界面如图4所示。

让界面更加绚丽 Java SE 6.0 GUI体验(图七)
图4 在启动界面上显示三个字符串
  另外需要提一点,在SplashScreen类中有一个close方法用于关闭启动界面,但这个方法一般不需要调用,因为在主窗口显示时这个方法自动被调用。当然,要想在初始化过程中关闭这启动界面,如发生初始化错误后,就不能再往下初始化了,因此,就要关闭这个界面,然后或退出程序,或直接进入主界面。

QQRead.com 推出数据恢复指南教程 数据恢复指南教程 数据恢复故障解析 常用数据恢复方案 硬盘数据恢复教程 数据保护方法 数据恢复软件 专业数据恢复服务指南 系统托盘

  现在有很多程序除了提供了一个完整的主界面外,在它最小化或者启动后在右下角的系统托盘区总是有一个小图标,如金山词霸、QQ和MSN等。图5显示了一台计算机的系统托盘里的图标。

让界面更加绚丽 Java SE 6.0 GUI体验(图三)
图5 系统托盘
  如果使用C++、Delphi(Pascal)等语言实现这个功能非常简单,只要调用一下系统API即可,但在以前版本(Java SE 5以前)的Java SE中Sun并未提供访问系统托盘的类,在那时使用Java访问系统托盘的唯一方法就是使用JNI直接调用系统API,但这种方法实现比较复杂,而且如果这样做,就破坏了Java的跨平台特性(除非你为每一个操作系统平台都做一个这样的类)。Java的这个缺陷缓和终于在Java SE 6中得到弥补。 在java.awt包中提供了一个SystemTray类可以直接访问系统托盘。下面的代码演示了一个简单的实现。

import javax.swing.*;
import java.awt.*;

public class MyTray
{
 public static void main(String args[])
 {
  // 判断当前操作系统是否支持系统托盘
  // 最好加上这个判断,否则这个程序可能在其它操作系统上无法正常工作
  if (SystemTray.isSupported())
  {
   // 通过静态方法getSystemTray()得到系统托盘
   SystemTray tray = SystemTray.getSystemTray();
   // 装载托盘图象
   Image image = Toolkit.getDefaultToolkit().getImage("tray.gif ");
   // 为这个托盘加一个弹出菜单
   PopupMenu popup = new PopupMenu();
   MenuItem item = new MenuItem("我的菜单");
   popup.add(item);
   // 为这个托盘加一个提示信息
   TrayIcon trayIcon = new TrayIcon(image, "提示信息", popup);
   try
   {
    tray.add(trayIcon);
   }
   catch (AWTException e)
   {
    System.err.println("无法向这个托盘添加新项: " + e);
   }
  }
  else
  {
   System.err.println("无法使用系统托盘!");
  }
 }
}
  在运行上面的程序之前,tray.gif一定要放到当前目录,如果放到其它的目录,要在程序中指明。图6是程序运行结果。最左侧的五彩光盘图标就是本程序加入了。

让界面更加绚丽 Java SE 6.0 GUI体验(图八)
 
图6 运行结果
  如果多次调用tray.add(trayIcon),可以在一个程序中向系统托盘添加多个图标。但要注意,图象可以使用一个Image对象,但弹出菜单要为每一个图标建一个,如果不建,就设为null。如:

TrayIcon trayIcon1 = new TrayIcon(image, "提示信息1", null);
TrayIcon trayIcon2 = new TrayIcon(image, "提示信息2", null);
TrayIcon trayIcon3 = new TrayIcon(image, "提示信息3", null);
tray.add(trayIcon1);
tray.add(trayIcon2);
tray.add(trayIcon3);
  图7为显示界面图

让界面更加绚丽 Java SE 6.0 GUI体验(图九)
图7
  Java SE 6还为我们提供了3种提示信息,它们是警告、错误和信息。如使用如下语句添加提示信息。

  添加警告提示:

trayIcon.displayMessage("警告", "这是一个警告提示!", TrayIcon.MessageType.WARNING);
让界面更加绚丽 Java SE 6.0 GUI体验(图十)
图8 警告提示
  添加错误提示:

trayIcon.displayMessage("错误", "这是一个错误提示!", TrayIcon.MessageType.ERROR);
让界面更加绚丽 Java SE 6.0 GUI体验(图十)
图9 错误提示
  添加信息提示:

trayIcon.displayMessage("信息", "这是一个信息提示!", TrayIcon.MessageType.INFO);
让界面更加绚丽 Java SE 6.0 GUI体验(图十二)
图10 信息提示

QQRead.com 推出数据恢复指南教程 数据恢复指南教程 数据恢复故障解析 常用数据恢复方案 硬盘数据恢复教程 数据保护方法 数据恢复软件 专业数据恢复服务指南 交互对话框

  在一般的程序语言或开发工具中都有一些标准的对话框以方便和用户交互,如Delphi中有InputBox对话框用来采集用户的输入信息。在Java SE 6中也提供了类似的标准对话框来满足这些需求。

  在Java SE 6中提供了一种输入对话框,下面是一个使用这个对话框的简单例子。

JOptionPane pane = new JOptionPane("文本", JOptionPane.INFORMATION_MESSAGE);
pane.setWantsInput(true);
JDialog dialog = pane.createDialog(parent, "请输入文本");
dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
dialog.setVisible(true);
String msg = pane.getInputValue();
  上面的代码使用JoptionPane对象的createDialog方法来建立一个输入对话框。上面的代码有几点需要注意一下。

  1. 如果将pane.setWantsInput (true)改为pane.setWantsInput(false),那么输入对话框将消失。

  2. 这个对话框使用的是APPLICATION_MODAL模式,Java SE 6还提供了一个DOCUMENT_MODAL模式,这两种模式最大的区别是第一种模式是对整个应用程序的,也就是说,使用这种模式弹出对话框后,整个程序都不访问,而使用第二种模式,只有弹出对话框的窗体不可访问,其它的窗体并不受影响。图11为以上代码的程序界面。

让界面更加绚丽 Java SE 6.0 GUI体验(图四)
图11
  图象转换

  Java在图象处理上是比较强大的,但是以前的Java SE版本对于GIF图只能读,不能写。这并不是因为技术原因,而是因为GIF专利的原因。但最近这个专利到期了,因此,在Java SE 6中提供了读写GIF的功能。下面的代码演示了如何通过Java来将其它格式的图象转换为gif格式。

import javax.imageio.*;
import java.io.*;
import java.awt.image.*;
import java.util.*;

public class ToGIF
{
 public static void main(String args[]) throws IOException
 {
  // 可以将abc.bmp换成其它格式的图象
  File inputFile = new File("abc.bmp");
  BufferedImage input = ImageIO.read(inputFile);
  File outputFile = new File("abc.gif");
  ImageIO.write(input, "GIF", outputFile);
 }
}
  如果你想知道在Java SE 6支持什么图象格式,可以使用如下语句进行查看。

System.out.println(Arrays.toString(ImageIO.getWriterFormatNames()));
  显示结果:

[BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]

--
X-Spirit

2007年6月5日星期二

TOMCAT遇上Derby


        一直以来在写程序的时候觉得有许多数据是运行这个程序本身需要的,和用户的数据没有什么关系,都放在一个库里有点不合适。分开放要同时连接两个以上的大型数据库(客户的数据一般都放在大型的数据库里面)好象也不太合适。
       在网上一查发现Derby这个东西不错,人家说了:),查资料,做DEMO。最后发现它不能够和TOMCAT一块起来,还得单独起动它的网络服务。这怎么能行呢?
       最后在 http://www-128.ibm.com/developerworks/cn/db2/library/techarticles/dm-0508bader/index.html查到一篇文章。但它写得很麻烦,可能是我没有用到那么多功能。我整理如下步骤:
       1、修改TOMCAT_HOME\conf\catalina.properties文件,在common.loader键最后面加入DERBY的JAR,这是TOMCAT启动时加载的类的路径,这个不改也可以,需要把DERBY的JAR放到TOMCAT_HOME/common/lib下。这样更简单一些。
       2、修改TOMCAT_HOME\conf\server.xml文件,在 <Server> 元素的开头添加下列元素:   
<Listener className="org.apache.derby.tomcat.ServerLifecycleListenerWithNetworkServer" debug="0" />
这个类的源代码如下 :

package org.apache.derby.tomcat;

import org.apache.derby.tomcat.ServerLifecycleListener ;

public class ServerLifecycleListenerWithNetworkServer
    
extends ServerLifecycleListener
{
    
public static final String START_NETWORK_SERVER  =
        
"derby.drda.startNetworkServer";

    
public  static final String HOST =
        
"derby.drda.host ";

    
public static final  String PORT_NUMBER =
        
"derby.drda.portNumber";

    
protected void initializeCloudscape() {
        System.setProperty(
            START_NETWORK_SERVER,
            
" true"
        );
        
super.initializeCloudscape();
    }



}

package org.apache.derby.tomcat;

import  java.sql.DriverManager;
import  java.sql.SQLException;

import  org.apache.catalina.Lifecycle;
import  org.apache.catalina.LifecycleEvent;
import  org.apache.catalina.LifecycleListener;

public class ServerLifecycleListener  implements LifecycleListener {

    
public static final  String DRIVER_CLASSNAME =
        
"org.apache.derby.jdbc.EmbeddedDriver";

    
public  static final String SHUTDOWN_URL =
        
"jdbc:derby:;shutdown=true ";

    
public static final  String SHUTDOWN_MESSAGE =
        
"Cloudscape system shutdown.";

    
public  static final String MSG_INIT_SUCCESS =
        
"Cloudscape JDBC driver loaded successfully ";

    
public static final  String MSG_INIT_CLASS_NOT_FOUND =
        
"The Cloudscape JDBC driver ("  +
        DRIVER_CLASSNAME 
+
        
") could not be found.  Make sure the appropriate JAR " +
        
" files are available.";

    
public  static final String MSG_TERM_SUCCESS =
        
"Cloudscape shutdown was successful. ";

    
public static final  String MSG_TERM_FAILURE =
        
"Unexpected Exception was caught from the Cloudscape shutdown." ;


    
public void lifecycleEvent(LifecycleEvent argEvent)  {
        
if (argEvent.getType().equals(Lifecycle.START_EVENT)) {
            
this.initializeCloudscape();
        }
 else if  (argEvent.getType().equals(Lifecycle.STOP_EVENT)) {
            
this.shutdownCloudscape();
        }

    }


    
protected void initializeCloudscape() {
        
try {
            Class.forName(DRIVER_CLASSNAME);
            System.out.println(MSG_INIT_SUCCESS);
        }
 catch (ClassNotFoundException varException) {
            System.out.println(MSG_INIT_CLASS_NOT_FOUND);
            varException.printStackTrace();
        }

    }


    
protected void shutdownCloudscape() {
        
try {
            DriverManager.getConnection (SHUTDOWN_URL);
        }
 catch (SQLException varException) {
            
if (varException.getMessage().equals(SHUTDOWN_MESSAGE)) {
                System.out.println(MSG_TERM_SUCCESS);
            }
 else {
                System.out.println(MSG_TERM_FAILURE);
                varException.printStackTrace();
            }

        }

    }

}


怎么找不到上传附件的地方呢???
把这两个文件编译好后放到TOMCAT_HOME\server\classes目录下。

现在重启TOMCAT就可以发现DERBY会一块启来了!
至于DERBY的连接池这些和其他的没有什么区别了。以后有时间再记吧。
--
X-Spirit