Tomcat5中的Embeded版本,為應(yīng)用中集成完整的Web服務(wù)提供了盡可能大的空間,不僅使開發(fā)者容易獲得對(duì)標(biāo)準(zhǔn)HTTP的處理,還有SSL的通訊處理,使開發(fā)者很容易就可以對(duì)原有非Web系統(tǒng)進(jìn)行擴(kuò)展以支持瘦客戶端應(yīng)用,通向Web大門的鑰匙已經(jīng)放在這里,剩下的就是看你怎樣來(lái)發(fā)揮了。

Tomcat嚴(yán)格意義上不是一個(gè)真正的AppServer,只是支持運(yùn)行Servlet和Jsp的Web容器,此外擴(kuò)展了一些AppServer的功能,如數(shù)據(jù)庫(kù)連接池,JNDI等,如何提煉,或者說(shuō)把Tomcat整理成一個(gè)最小的集合成為Tomcat嵌入版本的關(guān)鍵,從Tomcat5.0開始提供和支持Embeded版本,即最簡(jiǎn)化Tomcat Server,下面就針對(duì)Tomcat Server的Embeded版本進(jìn)行介紹,怎樣把Tomcat集成到Java應(yīng)用中。

首先可以在http://apache.mirrors.versehost.com/jakarta/tomcat-5/v5.0.28/bin/jakarta-tomcat-5.0.28-embed.tar.gz下載Tomcat的Embeded版本,下載解壓后把最里層的jakarta-tomcat-5.0.28-embed目錄copy到容易查找的目錄,為簡(jiǎn)易需要更名為tomcat-embed,作為嵌入Tomcat的工作目錄。

首先我們需要了解Tomcat在工作時(shí)的層次情況,它按照:

上面是Tomcat實(shí)現(xiàn)的內(nèi)部工作結(jié)構(gòu):

一個(gè)Server含有幾個(gè)Connector,比如non-SSL HTTP/1.1 Connector on port 8080,SSL HTTP/1.1 Connector on port 8443和AJP 1.3 Connector on port 8009。連接器就是接受客戶端情況然后封裝成request和response對(duì)象交給容器處理。

通常是一個(gè)Engine,其中Engine里含有1個(gè)Host,1個(gè)Host 內(nèi)可以含有多個(gè)Context,Context代表Web應(yīng)用,即1個(gè)Host里可以包含多個(gè)Web應(yīng)用,tomcat的webapps目錄里面防止的就是一個(gè)個(gè)web應(yīng)用。Engine接收Service發(fā)過(guò)來(lái)的請(qǐng)求(通過(guò)Connector),交給相應(yīng)的Host進(jìn)行處理,然后Host交給具體的Context。

下面是非常簡(jiǎn)單的創(chuàng)建Embeded tomcat的例子,示意其使用

把tomcat-embed目錄下的lib內(nèi)的所有jar包引入到項(xiàng)目的環(huán)境中,即完成了項(xiàng)目的環(huán)境搭建。在應(yīng)用里開發(fā)嵌入式Tomcat,需要根據(jù)以下步驟:
1)創(chuàng)建org.apache.catalina.startup.Embedded實(shí)例,其代表嵌入式Tomcat Server的實(shí)例;
2)創(chuàng)建org.apache.catalina.Engine 實(shí)例,代表上面XML結(jié)構(gòu)示例中的Engine,作為容器用來(lái)包含Host節(jié)點(diǎn);
3)創(chuàng)建org.apache.catalina.Host實(shí)例,代表虛擬主機(jī)服務(wù),把它加入到2)中產(chǎn)生的Engine;
4)創(chuàng)建一個(gè)或多個(gè)org.apache.catalina.Context實(shí)例,代表Web應(yīng)用,每個(gè)Web應(yīng)用都需要加入到3)產(chǎn)生的Host中;
5)最后創(chuàng)建org.apache.catalina.Connector實(shí)例,把它加入1)創(chuàng)建的tomcat實(shí)例中,它用來(lái)接收客戶發(fā)出的請(qǐng)求。

具體和完整的代碼如下:
import java.io.File;
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.Logger;
import org.apache.catalina.startup.Embedded;


public class TomcatService {
public static void main(String[] args) {
   //設(shè)置Tomcat的工作目錄,并啟動(dòng)Tomcat Server
   String path = "/usr/local/tomcat-embed";
   Embedded tc = createTomcat(path);
   try {
    tc.start();
    System.out.println("---------- Tomcat Server start over. ------------");
   } catch (Exception e) {
    e.printStackTrace();
   }  
}

private static Embedded createTomcat(String path) {
     //創(chuàng)建嵌入式Tomcat Server的實(shí)例
   Embedded tomcat = new Embedded();
        //設(shè)置Tomcat的工作目錄
   tomcat.setCatalinaHome(path);
        //產(chǎn)生Tomcat引擎
   Engine engine = tomcat.createEngine();
   engine.setName("EmbededServer");
   //創(chuàng)建Host,設(shè)置Host的工作目錄
   Host host = tomcat.createHost("localhost", tomcat.getCatalinaHome()
     + "/webapps");
        //把Host加入Engine
   engine.addChild(host);
   engine.setDefaultHost(host.getName());
  
   String path = host.getAppBase() + "/instance1";
   if (!new File(path).exists()) {
    System.err.println("請(qǐng)檢查instance1應(yīng)用的目錄以及相關(guān)資源是否存在.");
    return null;
   }
   //創(chuàng)建instance1的Context,并加入Host中
   Context ctxt = tomcat.createContext("/instance1", path);
   host.addChild(ctxt);
  
   tomcat.addEngine(engine);
   tomcat.setDebug(Logger.WARNING);
   try {
      //Tomcat加入Connector,監(jiān)聽本地(127.0.0.1)的訪問(wèn)
    tomcat.addConnector(tomcat.createConnector(InetAddress
      .getByName("127.0.0.1"), 8080, false));
   } catch (UnknownHostException e) {
    System.err.println("綁定Tomcat Server到127.0.0.1:8080失敗,請(qǐng)檢查端口是否被占用.");
    e.printStackTrace();
    tomcat = null;
   }
   return tomcat;
}
}

在這里需要注意,由于嵌入式版本Tomcat沒(méi)有common/lib目錄,一些需要的Jar包可以復(fù)制到JDK的/jre/lib/endorsed目錄下進(jìn)行使用。


在OFBiz中默認(rèn)使用的embeded tomcat,具體的可以參考里面對(duì)于嵌入式啟動(dòng)相關(guān)的內(nèi)容。