https://www.iflym.com/index.php/code/use-embeded-tomcat-to-javaee-start-tomcat.html
昨天在網(wǎng)上研究了下關(guān)于將tomcat嵌入到主程序中進(jìn)行運(yùn)行,而不是像以前將一個(gè)web項(xiàng)目copy到tomcat中進(jìn)行運(yùn)行。之所以這樣做的原 因,即是因?yàn)轫?xiàng)目部署到客戶方,在進(jìn)行更新的時(shí)候,需要手動(dòng)地進(jìn)行更新,再把相應(yīng)代碼copy到tomcat,然后再運(yùn)行。運(yùn)用embeded tomcat就可以將項(xiàng)目與tomcat分開(kāi),在進(jìn)行更新時(shí),先使用自定義的程序進(jìn)行自動(dòng)化更新,待更新完畢之后,再啟動(dòng)tomcat(或其它 javaee容器)進(jìn)行項(xiàng)目運(yùn)行。
這樣做的最終效果就是修改了項(xiàng)目的運(yùn)行方式。原先的運(yùn)行方式是以tomcat為中心,由tomcat來(lái)啟動(dòng)和終止項(xiàng)目,現(xiàn)在是由我們的啟動(dòng)程序 為中心,由啟動(dòng)程序來(lái)負(fù)責(zé)啟動(dòng)和終止項(xiàng)目。就相當(dāng)于現(xiàn)在流行的cs程序一樣,有單獨(dú)的啟動(dòng)腳本,在啟動(dòng)時(shí)進(jìn)行環(huán)境預(yù)初始化,更新程序以及其它操作,待完成 之后再進(jìn)行最終的項(xiàng)目啟動(dòng)。
這篇主要講解如何使用embeded tomcat在代碼中進(jìn)行啟動(dòng)和終止。網(wǎng)上的一般文章均為tomca5.x來(lái)做,這里使用了最新的tomcat7,因?yàn)閠omcat7為embeded開(kāi) 發(fā),單獨(dú)發(fā)布了org.apache.tomcat.embed包,以進(jìn)行獨(dú)立的embed開(kāi)發(fā)。以下是相應(yīng)的maven包
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 | < dependency >
< groupId >org.apache.tomcat.embed</ groupId >
< artifactId >tomcat-embed-core</ artifactId >
< version >7.0.2</ version >
</ dependency >
< dependency >
< groupId >org.apache.tomcat</ groupId >
< artifactId >tomcat-util</ artifactId >
< version >7.0.2</ version >
</ dependency >
< dependency >
< groupId >org.apache.tomcat.embed</ groupId >
< artifactId >tomcat-embed-jasper</ artifactId >
< version >7.0.2</ version >
</ dependency >
< dependency >
< groupId >org.apache.tomcat.embed</ groupId >
< artifactId >tomcat-embed-logging-juli</ artifactId >
< version >7.0.2</ version >
</ dependency >
|
使用了embed包中的core包,以及用于編譯jsp的jasper包,然后是工具類以及進(jìn)行上場(chǎng)記錄的logging-juli包。開(kāi)始寫(xiě)代碼:
1 2 3 4 5 6 7 | //設(shè)置工作目錄
String catalina_home = "d:/" ;
Tomcat tomcat = new Tomcat();
tomcat.setHostname( "localhost" );
tomcat.setPort(startPort);
//設(shè)置工作目錄,其實(shí)沒(méi)什么用,tomcat需要使用這個(gè)目錄進(jìn)行寫(xiě)一些東西
tomcat.setBaseDir(catalina_home);
|
上面使用了Tomcat類來(lái)進(jìn)行啟動(dòng)類,在tomcat7以前均是使用一個(gè)叫Embed類來(lái)進(jìn)行啟動(dòng),在tomcat7之后,embed類被不建 議使用,而建議使用新的Tomcat類來(lái)進(jìn)行啟動(dòng)了。然后設(shè)置主機(jī)名,端口,再設(shè)置一個(gè)工作目錄。這個(gè)工作目錄可以是任意目錄,主要是tomcat需要這 個(gè)目錄來(lái)記錄一些東西,比如記錄word信息,日志信息(如果配置了日志的話),以及臨時(shí)文件存儲(chǔ)等。
1 2 3 4 5 6 7 8 | //設(shè)置程序的目錄信息
tomcat.getHost().setAppBase( "e:/" );
// Add AprLifecycleListener
StandardServer server = (StandardServer) tomcat.getServer();
AprLifecycleListener listener = new AprLifecycleListener();
server.addLifecycleListener(listener);
//注冊(cè)關(guān)閉端口以進(jìn)行關(guān)閉
tomcat.getServer().setPort(shutdownPort);
|
上面的代碼,首先設(shè)置我們的項(xiàng)目程序所在的appbase,即放項(xiàng)目代碼的地方。在通常的tomcat配置中,這個(gè)目錄一般是webapps。接 著設(shè)置一個(gè)listener,這個(gè)listener主要是負(fù)責(zé)啟動(dòng)一些比如html native支持程序以及ipv6等信息配置(可以忽略)。接著是配置一個(gè)關(guān)閉的注冊(cè)端口,當(dāng)向這個(gè)端口發(fā)送信息時(shí),就可以達(dá)到關(guān)閉tomcat的目的 (后面會(huì)講)。
1 2 3 4 5 6 7 8 9 | //加載上下文
StandardContext standardContext = new StandardContext();
standardContext.setPath( "/aa" ); //contextPath
standardContext.setDocBase( "aa" ); //文件目錄位置
standardContext.addLifecycleListener( new Tomcat.DefaultWebXmlListener());
//保證已經(jīng)配置好了。
standardContext.addLifecycleListener( new Tomcat.FixContextListener());
standardContext.setSessionCookieName( "t-session" );
tomcat.getHost().addChild(standardContext);
|
我們單獨(dú)使用了一個(gè)Context來(lái)為這個(gè)host添加上下文,tomcat本身提供一個(gè)方法tomcat.addWeb方法來(lái)添加項(xiàng)目包,不過(guò) 由于這里需要單獨(dú)設(shè)置一個(gè)tomcat的sessionName,所以使用與與tomcat.addWeb實(shí)現(xiàn)類似的方法來(lái)添加一個(gè)項(xiàng)目包。
以上代碼中有兩個(gè)需要注意的listener,一個(gè)是DefaultWebXmlListener,這個(gè)是由tomcat加載一些默認(rèn)的配置信 息,比如jspServlet,以及一些繁復(fù)的mime/type信息;加上這個(gè),就不需要我們自己去寫(xiě)這么多的配置,因?yàn)槊總€(gè)項(xiàng)目都需要這些。這個(gè)配置 與tomcat目錄下的conf/web.xml中的配置一樣,只不過(guò)這里是代碼化了。第二個(gè)是FixContextListener,這個(gè)主要是在項(xiàng)目 部署完后,將這個(gè)上下文設(shè)置為configured,表示已經(jīng)配置好了(不然,tomcat啟動(dòng)時(shí)會(huì)報(bào)錯(cuò),即相應(yīng)上下文還未配置好)。
配置OK了之后,就是啟動(dòng)tomcat了:
1 2 | tomcat.start();
tomcat.getServer().await();
|
啟動(dòng)tomcat,并讓tomcat在關(guān)閉端口上監(jiān)聽(tīng)。如果沒(méi)有最后一句,程序?qū)⒅苯咏Y(jié)束,保證監(jiān)聽(tīng)之后,tomcat將一直監(jiān)聽(tīng)關(guān)閉事件,待有關(guān)閉事件之后才結(jié)束當(dāng)前程序。所以如果想要關(guān)閉當(dāng)前的tomcat,只需要向關(guān)閉端口發(fā)送一些信息即可:
1 2 3 4 5 6 7 8 9 | private static void shutdown() throws Exception {
Socket socket = new Socket( "localhost" , shutdownPort);
OutputStream stream = socket.getOutputStream();
for ( int i = 0 ;i < shutdown.length();i++)
stream.write(shutdown.charAt(i));
stream.flush();
stream.close();
socket.close();
}
|
這樣即可達(dá)到關(guān)閉tomcat的目的。
實(shí)際上看整個(gè)項(xiàng)目代碼,項(xiàng)目代碼的運(yùn)行,就是一個(gè)配置一個(gè)基礎(chǔ)的server.xml(即tomcat目錄下的 conf/server.xml),先配置運(yùn)行端口,關(guān)閉監(jiān)聽(tīng)端口;然后配置運(yùn)行的host以及添加一個(gè)上下文context,最后就開(kāi)始運(yùn)行并開(kāi)始監(jiān) 聽(tīng)。對(duì)照這個(gè)程序,再看一下server.xml中的配置信息,就很容易明白以上這段代碼了。
posted on 2016-07-18 14:42
SIMONE 閱讀(4535)
評(píng)論(0) 編輯 收藏 所屬分類:
JAVA 、
tomcat