Original Source: http://blog.terac.com/andy/e_329.html
对于普通用户来说,使用传统的桌面应用程序(可能采用不同语言和工具开发的)可能存在这样那样的限制,比如界面风格千变万化、操作习惯不统一、学习难度大、无法或很难和外部应用通信等。而传统的服务器端应用程序或网站也存在许多限制,比如网络连通可能出现问题、响应速度慢、不能保证服务器端始终可用、担心数据安全和个人隐私问题、不够灵活、使用不方便等。
而基于浏览器的桌面应用程序正是综合桌面应用程序和服务器端应用程序的功能产生的。它包含以下优点:
- 跨平台的、统一的、简单易用的操作界面(基于浏览器,比如IE或FireFox,用户只须要熟悉浏览器,而不必关心是机器运行的Windows、Mac OS X还是Linux,甚至不要OS,只要能运行Browser和JVM的硬件)
- 真正的去中心化应用(Decentralized application),每个应用即可以当成桌面应用程序,又可以当成服务器端应用程序(只要联网并开放端口就可以允许其他人远程运行)。这是Web 3.0吗?
- 应用XML进行通信,不用考虑本地服务(Local service)还是远程服务(Remote service)之间的区别
- 轻量级、易开发
- 。。。
基于浏览器的桌面应用程序(Browser-based desktop application)的定义:一个包含嵌入式网站服务器(Embedded web server)的能够在浏览器内的客户端的独立运行(Stand alone)的应用程序。
我把基于浏览器的桌面应用程序(Browser-based desktop application)简称为BBDA。其实BBDA和AJAX技术一样,也是一个buzzword,而不是什么新技术,只不过把几种通用的软件或技术组合在一起而已。和传统的重量级的Portal系统不同的是,BBDA是轻量级网络应用(Light weight web application),XML(Feed / RSS / XML-RPC / SOAP)是联系各个服务或应用的纽带。
其实,BBDA很符合目前热炒的WebOS(基于网络浏览器的操作系统)的特性,这方面Google做了个最好的Demo:Google Desktop, 在GD中,一切内容的表现都是网页(虽然隐藏了浏览器),并且很容易和Google网站进行通信(比如同时搜索本地和搜索Web,利用Feed(RSS)或XML-PRC或SOAP之类的协议读新闻、邮件、天气预报、股票行情等,微软该称RSS为Feed好像很有道理吧?)。现在GDS(Google Desktop Search)只是GD的一个模块而已,百度的桌面搜索只是单纯地模仿了GDS,却没有猜到原来Google是要做GD,好傻的百度。Google这几年的收购和挖人活动(Google Net, Google Browser等),看来一切都是为了WebOS而努力。这里顺便说一下Yahoo刚收购的Konfabulator,Konfabulator和GD有很大不同,我觉得它只是包含许多小软件或和网站交互的工具,只是个玩具箱而已,要做WebOS靠这个可以吗?看来Yahoo的眼光似乎始终不如Google。找到这篇文章:GoogleOS? YahooOS? MozillaOS? WebOS? 居然和我的想法如此相似(写这个之前我绝对没看过这篇文章)!
由于我主要做Java开发,所以只列出可能涉及的Java软件包:Browser(IE/FireFox), JDK, Tomcat/Jetty, HSQLDB/Apache Derby, Hibernate, Spring, Groovy, DOM4J,Apache Http Client, Lucene, Struts/WebWork/JSF/Tapestry/Wicket, DWR(AJAX), Apache Web Services(SOAP/XML-RPC), Apache POI(Word/Excel/ PDF), MP3 ID TAG 3 lib ,JPEG EXIF lib...
我的目的是组合几种通用的JAVA软件,用来进行快速的BBDA开发。对于开发者而言,只要选好合适的软件,并合理组合起来,完全可以达到或超过Ruby on rails的功能和开发效率。同时,对于普通用户而言,只要打开浏览器输入http://localhost就会进入Dashboard(ProtoPage是个很好的Prototype^_^,Start也不错),然后就可以管理日记(blog)、日历、通讯录、照片(flickr?)、音乐(itunes?)、文件、网摘(delicious?)、阅读订阅的RSS(bloglines?)、查看邮件(web mail)、新闻之类等,并可以进行搜索、共享、发布、与外部应用或网站同步等,构成一个完整的个人门户系统(Personal portal),XML(Feed / RSS / XML-RPC / SOAP)是联系各个服务或应用的纽带。
画了个草图(持续完善中):
关于嵌入式网站服务器(Embedded web server):
我这几天试用了Jetty和Tomcat。总以为Jetty很小呢,最适合做BBDA呢,结果发现软件包也很大了,另外很多功能不如Tomcat,Tomcat Embed 5.5由于使用Ecipse JDT,现在已经很小了(3M左右),而且标准,所以选了Tomcat Embed(这里下载)。下面的代码是Tomcat Embed的启动程序。
Start.java:
package com.terac.tomcat;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.apache.catalina.Context;
import org.apache.catalina.Engine;
import org.apache.catalina.Host;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Embedded;public class Start {
public static void main(String[] args) {
try {
String path = System.getProperty("SERVER_HOME");
if(path!=null&&!"".equals(path)){
int port = Integer.parseInt(System.getProperty("SERVER_PORT","8080"));
startTomcat(path,port);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void startTomcat(String path,int port) throws UnknownHostException,
LifecycleException {
System.setProperty("catalina.home", path);
Embedded embedded = new Embedded();
Engine engine = embedded.createEngine();
engine.setName("Engine");
Host host = embedded.createHost("localhost", "web");
Context rootContext = embedded.createContext("", "");
rootContext.setPrivileged(true);
host.addChild(rootContext);
engine.addChild(host);
engine.setDefaultHost("localhost");
embedded.addEngine(engine);
Connector connector = embedded.createConnector((InetAddress) null,port, false);
embedded.addConnector(connector);
embedded.start();
}
}start.bat:
@set classpath=./lib/所有的jar文件
@java -DSERVER_HOME=%cd% -DSERVER_PORT=80 -classpath %classpath% com.terac.tomcat.Start
关于嵌入式数据库(Embeded database):
Apache Derby虽然比HSQLDB强大,但还是太大了,尤其是当用到IBM的JDBC Driver时。所以只好选HSQLDB。下面的代码是利用ServerContextListener在Web应用程序启动时启动HSQLDB服务器。
HSQLDBServletContextListener.java:
package com.terac.hsqldb;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;public class HSQLDBServletContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent evt) {
try {
ServletContext context = evt.getServletContext();
String params = "port=9001;silent=true;trace=false;database.0=" +
context.getRealPath("/") + "/WEB-INF/hsqldb/terac";
org.hsqldb.Server server = new org.hsqldb.Server();
server.putPropertiesFromString(params);
server.setLogWriter(null);
server.setErrWriter(null);
server.start();
} catch (Exception e) {
System.err.println(e);
}
}
public void contextDestroyed(ServletContextEvent evt) {
Connection conn = null;
try {
Class.forName("org.hsqldb.jdbcDriver");
conn = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost:9001",
"sa", "123456");
Statement stmt = conn.createStatement();
stmt.executeUpdate("SHUTDOWN;");
} catch (Exception e) {
//
}
}
}web.xml中需要加入listener:
com.terac.hsqldb.HSQLDBServletContextListener
关于全文检索引擎(Full text search engine):
Apache Lucene应用广泛,也足够强大,高亮显示(Highlighting)需要自己实现,自动摘要(autosummarize)需要Classifier4j 。下面是常用类的封装代码:
Indexer.java:
还未整理好
Searcher.java:
还未整理好
关于Shell:
有些时候,用户不满足已经有的服务,需要更灵活的、或者定制的功能,一个简单的、易学的、解释性的、交互式的Shell就显得很必要,比如Windows提供的cmd或Linux里的bash。研究了一下,发现Groovy正好能满足需要,“for (ch in "Hello world!") {println ch}”,这个稍微复杂点儿的Hello world很好懂吧?
关于时间服务(Time Service):
Windows里有计划任务(Schedule task),Linux里有Cron job,这个对于WebOS也是必须的,比如定时检查邮件,定时抓新闻等等都需要定时器(Timer),Spring framework封装了好几种Time service,足够了。
关于对象关系映射工具(OR mapping tools):
Hibernate是最常用最强大的工具。下面是Hibernate Session的封装代码(也可以利用Spring framework来管理):
HibernateUtil.java:
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Session;
import net.sf.hibernate.cfg.Configuration;
import org.apache.log4j.Logger;public class HibernateUtil {
private static Log log = LogFactory.getLog(HibernateUtil.class);
public static final ThreadLocal threadSession = new ThreadLocal();
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// We have to catch Throwable, otherwise we will miss
// NoClassDefFoundError and other subclasses of Error
log.error("Building SessionFactory failed.", ex);
throw new ExceptionInInitializerError(ex);
}
}
public static Session currentSession() throws HibernateException {
Session s = (Session) threadSession.get();
if (s == null) {
s = sessionFactory.openSession();
threadSession.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
}
关于模型-视图-控制框架(MVC framework):
现在的MVC framework太多了,传统的有Struts/WebWork,新的有JSF/Tapestry/Wicket/Flex&Laszlo(Flash RIA) ,Wicket网站列出了55种之多!我试过JSF,始终不能另我满意,正在研究Wicket和RIFE(这两个都支持AJAX),新加一个Stripes(采用Java 5 Annotations,所以不需要XML配置文件,非常简单)。
关于文件系统(File system):
Apache Commons Virtual File System - Commons VFS provides a single API for accessing various different file systems. It presents a uniform view of the files from various different sources, such as the files on local disk, on an HTTP server, or inside a Zip archive. 越来越好玩了:)
另外,发现在Windows系统下PHP5也可以在Tomcat下运行(Running php 5.x on windows using tomcat 4.x or 5.x - Simple Thoughts - Java and Web Software)。BBDA with PHP:),不知道PHP的基于文本的数据库都有哪些?我试了一下,phpinfo和一个简单的基于文本的PHP留言本可以使用,phpMyAdmin和几个PHP的blog不能运行,Tomcat直接Crash。
我已经把BBDA框架和以前写的一个非常简单的Struts/Hibernate单用户相册程序打包了,这里下载,下载后解压缩就能用(需要安装好JDK,并设置好path)。login.do是管理界面登陆入口,秘密是:111111。