解析Tomcat的啟動(dòng)腳本--catalina.bat
概述
Tomcat 的三個(gè)最重要的啟動(dòng)腳本:
- startup.bat
- catalina.bat
- setclasspath.bat
上一篇咱們分析了 startup.bat 腳本
這一篇咱們來分析 catalina.bat 腳本.
至于 setclasspath.bat 這個(gè)腳本, 相信看完這一篇, 就可以自己看懂這個(gè)腳本了.
可以點(diǎn)擊下載 [ setclasspath.bat 腳本 ]查看附注釋的 setclasspath.bat 腳本
catalina.bat
這個(gè)腳本的代碼有點(diǎn)多, 就單獨(dú)弄了一篇展示 catalina.bat 腳本中的內(nèi)容. 點(diǎn)擊 [catalina.bat 腳本 ]下載查看.
下面咱們就按照腳本中的內(nèi)容一行行的來分析.
@echo off setlocal
這兩個(gè)命令可以參考上一篇的文章(解析Tomcat的啟動(dòng)腳本--startup.bat)的解釋
第一塊腳本代碼
rem Suppress Terminate batch job on CTRL+C if not ""%1"" == ""run"" goto mainEntry if "%TEMP%" == "" goto mainEntry if exist "%TEMP%\%~nx0.run" goto mainEntry echo Y>"%TEMP%\%~nx0.run" if not exist "%TEMP%\%~nx0.run" goto mainEntry echo Y>"%TEMP%\%~nx0.Y" call "%~f0" %* <"%TEMP%\%~nx0.Y" rem Use provided errorlevel set RETVAL=%ERRORLEVEL% del /Q "%TEMP%\%~nx0.Y" >NUL 2>&1 exit /B %RETVAL% :mainEntry del /Q "%TEMP%\%~nx0.run" >NUL 2>&1
腳本的作用
判斷用戶是否使用
catalina.bat run
來啟動(dòng) Tomcat 的.
如果用戶使用 startup.bat 腳本啟動(dòng) Tomcat, 那么這段腳本不會(huì)被執(zhí)行.
這段代碼看起來很亂, 慢慢分析.
第一行:
注釋, 意思就是: 禁止使用 CTRL+C 來終止批處理任務(wù), 也不知道是怎么禁止的.
第二行:
if not ""%1"" == ""run"" goto mainEntry
首先明白這里的這個(gè) "%1" 這個(gè)變量代表的是什么? 正常情況下, 這個(gè)腳本是被 startup.bat 腳本調(diào)用的, 被調(diào)用的同時(shí)傳遞了一個(gè) start 參數(shù)過來(上一篇分析得出的). 在 批處理命令 中 %1 就表示命令之后的第一個(gè)參數(shù), 在這里指的就是 start. 所以 "%1" = start. 如果用戶用 catalina.bat run 命令啟動(dòng) Tomcat 的話, 那么這里的 "%1" = run.
第三行:
if "%TEMP%" == "" goto mainEntry
這里的 %TEMP% 很有可能被認(rèn)為是 空, 其實(shí)這里可以讀取到系統(tǒng)的環(huán)境變量. 所以, 這里的 %TEMP% 就是系統(tǒng)的環(huán)境變量值, 通常裝完 windows 系統(tǒng)的話, 系統(tǒng)會(huì)自動(dòng)配置上這個(gè)環(huán)境變量. 所以這里一般是有值的. 大家可以去系統(tǒng)的環(huán)境變量看一下它指向那個(gè)目錄, 一般就是 C:\Users\用戶名\AppData\Local\Temp. 注意: AppData 是一個(gè)隱藏目錄.
第四行:
if exist "%TEMP%\%~nx0.run" goto mainEntry
這里又出現(xiàn)了一個(gè)新的東西 %~nx0 . 在批處理中, 我們知道 %1 表示的是程序之后的第一個(gè)參數(shù), 那么 %0 呢? %0 表示這個(gè)可執(zhí)行程序的名稱, %~nx0 的話就是程序的名稱+擴(kuò)展名
在這里就是 catalina.bat . 大家可以寫一個(gè)小腳本(test.bat)驗(yàn)證一下: (我的腳本放在 D 盤下)
腳本內(nèi)容:
@echo off echo "%~nx0" echo "%1"
執(zhí)行結(jié)果:
PS D:\> .\test.bat Hello "test.bat" "Hello" PS D:\>
第五行:
echo Y>"%TEMP%\%~nx0.run"
這段代碼很簡單, 就是寫入字符 Y 到 %TEMP%\catalina.bat.run 文件中.
第六行:
if not exist "%TEMP%\%~nx0.run" goto mainEntry
又判斷了一下 %TEMP%\catalina.bat.run 文件是否存在.
第七行:
echo Y>"%TEMP%\%~nx0.Y"
同第五行, 寫入 Y 到 %TEMP%\catalina.bat.Y . 如果文件不存在, 則新建一個(gè).
第八行:
call "%~f0" %* <"%TEMP%\%~nx0.Y"
這一行有點(diǎn)意思. 又出現(xiàn)了兩個(gè)新的東西:
(因?yàn)?markdown 語法限制, 把下面代碼寫到代碼塊里)
- "%~f0" : 簡單說就是表示當(dāng)前命令的絕對(duì)路徑.
- "%*" : 我們知道 %1 表示第一個(gè)參數(shù), 依次類推, %2 表示第二個(gè).... 那么 %* 就很好理解了, 代表所有參數(shù).
驗(yàn)證一下
腳本內(nèi)容:
@echo off echo "%*" echo "%~f0"
執(zhí)行結(jié)果:
PS D:\> .\test.bat Hello World "Hello World" "D:\test.bat" PS D:\>
那么后面的 <"%TEMP%\%~nx0.Y" 意思就是讀取 %TEMP%\catalina.bat.Y 文件中的內(nèi)容.
之后又通過 call 進(jìn)行調(diào)用.
我們自己寫一個(gè)例子, 在 D 盤建立 test.bat 文件, 再建立 catalina.bat.Y 文件
腳本內(nèi)容:
call "%~f0" %* < D:/catalina.bat.Y
catalina.bat.Y 文件內(nèi)容
Y
執(zhí)行結(jié)果:
........ D:\>call "D:\test.bat" Hello World 0<D:/catalina.bat.Y D:\>call "D:\test.bat" Hello World 0<D:/catalina.bat.Y D:\>call "D:\test.bat" Hello World 0<D:/catalina.bat.Y D:\>call "D:\test.bat" Hello World 0<D:/catalina.bat.Y D:\>call "D:\test.bat" Hello World 0<D:/catalina.bat.Y D:\>call "D:\test.bat" Hello World 0<D:/catalina.bat.Y D:\>call "D:\test.bat" Hello World 0<D:/catalina.bat.Y ****** B A T C H R E C U R S I O N exceeds STACK limits ****** Recursion Count=593, Stack Usage=90 percent ****** B A T C H PROCESSING IS A B O R T E D ******
最上面省略了很多重復(fù)代碼, 從這里發(fā)現(xiàn)它不斷地調(diào)用自己本身, 直到超出了堆棧的限制才停止.
我們?nèi)绻由?@echo off 的話
@echo off call "%~f0" %* < D:/catalina.bat.Y
結(jié)果只會(huì)出現(xiàn)
D:\>.\test.bat Hello World ****** B A T C H R E C U R S I O N exceeds STACK limits ****** Recursion Count=593, Stack Usage=90 percent ****** B A T C H PROCESSING IS A B O R T E D ******
我們這里只需要明白這些命令的作用就可以, 稍后我們會(huì)總結(jié) Tomcat 執(zhí)行這些命令的目的.
第十行:
set RETVAL=%ERRORLEVEL%
我們?nèi)绻私?Linux 的話都知道, 每個(gè)命令的執(zhí)行都會(huì)返回一個(gè)執(zhí)行完成之后的退出碼. Linux執(zhí)行完一條命令之后用 echo $? 來查看上一條命令的退出碼. 在 Windows 中也是一樣的, 命令執(zhí)行完之后都有自己的退出碼. 這里的 %ERRORLEVEL% 就是取的上面的 call 命令的退出碼. 賦值給一個(gè)變量 RETVAL
第十一行:
del /Q "%TEMP%\%~nx0.Y" >NUL 2>&1
這里又出現(xiàn)了一個(gè) del 命令, 很容易聯(lián)想到 delete, 那么 /Q 是什么意思呢? 靜默刪除, 不會(huì)給你任何提示, 就比如 Linux 中的 rm -f 一樣, 這里是刪除 %TEMP%\catalina.bat.Y 這個(gè)文件.
后面的 >NUL 2>&1 又是什么意思呢?
于 Linux 中的輸出流的重定向原理是一樣的.
(因?yàn)?markdown 語法限制, 把下面代碼寫到代碼塊里)
- >NUL : 表示將輸出重定向到 NUL 中, 你什么也看不到 - 2>&1 : 2:錯(cuò)誤輸出, &1: 標(biāo)準(zhǔn)輸出, 意思就是將錯(cuò)誤消息輸出到標(biāo)準(zhǔn)輸出中. - >NUL 2>&1 : 就是先將錯(cuò)誤消息輸出到標(biāo)準(zhǔn)輸出中, 然后再輸出到 NUL 中.
第十二行:
exit /B %RETVAL%
退出當(dāng)前批處理, /B 指定退出時(shí)的編號(hào), 把 RETVAL 最為 退出碼, 也就是 call 執(zhí)行的命令 的退出碼.
最后兩行:
:mainEntry del /Q "%TEMP%\%~nx0.run" >NUL 2>&1
定義一個(gè) mainEntry 標(biāo)簽, 然后刪除 臨時(shí)目錄中的 catalina.bat.run 文件.
總結(jié)第一段腳本的功能
簡單說, 這段代碼的作用就是調(diào)用本身, 判斷臨時(shí)目錄中的文件是否存在來避免二次回調(diào)自己. 感覺寫的好復(fù)雜.
下面就進(jìn)入 Tomcat 的正式啟動(dòng)過程, 并沒有開始執(zhí)行 main 方法
第二段腳本代碼
rem Guess CATALINA_HOME if not defined set "CURRENT_DIR=%cd%" if not "%CATALINA_HOME%" == "" goto gotHome set "CATALINA_HOME=%CURRENT_DIR%" if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome cd .. set "CATALINA_HOME=%cd%" cd "%CURRENT_DIR%" :gotHome if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome echo The CATALINA_HOME environment variable is not defined correctly echo This environment variable is needed to run this program goto end :okHome rem Copy CATALINA_BASE from CATALINA_HOME if not defined if not "%CATALINA_BASE%" == "" goto gotBase set "CATALINA_BASE=%CATALINA_HOME%" :gotBase
這段腳本還是比較簡單的, 主要是設(shè)置了兩個(gè)環(huán)境變量 CATALINA_HOME 和 CATALINA_BASE .
如果沒有配置 CATALINA_BASE 環(huán)境變量的話, 直接引用 CATALINA_HOME 的值
靜下心來稍微看一下就懂了.
第三段腳本代碼
rem Ensure that neither CATALINA_HOME nor CATALINA_BASE contains a semi-colon rem as this is used as the separator in the classpath and Java provides no rem mechanism for escaping if the same character appears in the path. Check this rem by replacing all occurrences of ';' with '' and checking that neither rem CATALINA_HOME nor CATALINA_BASE have changed if "%CATALINA_HOME%" == "%CATALINA_HOME:;=%" goto homeNoSemicolon echo Using CATALINA_HOME: "%CATALINA_HOME%" echo Unable to start as CATALINA_HOME contains a semicolon (;) character goto end :homeNoSemicolon if "%CATALINA_BASE%" == "%CATALINA_BASE:;=%" goto baseNoSemicolon echo Using CATALINA_BASE: "%CATALINA_BASE%" echo Unable to start as CATALINA_BASE contains a semicolon (;) character goto end :baseNoSemicolon
這里主要是判斷 CATALINA_HOME 環(huán)境變量的值 和 CATALINA_BASE 環(huán)境變量的值是否以 分號(hào)為結(jié)尾, 如果以 分號(hào)為結(jié)尾的話, 就報(bào)錯(cuò)退出.
第四段腳本代碼
rem Ensure that any user defined CLASSPATH variables are not used on startup, rem but allow them to be specified in setenv.bat, in rare case when it is needed. set CLASSPATH= rem Get standard environment variables if not exist "%CATALINA_BASE%\bin\setenv.bat" goto checkSetenvHome call "%CATALINA_BASE%\bin\setenv.bat" goto setenvDone :checkSetenvHome if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat" :setenvDone rem Get standard Java environment variables if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath echo Cannot find "%CATALINA_HOME%\bin\setclasspath.bat" echo This file is needed to run this program goto end :okSetclasspath call "%CATALINA_HOME%\bin\setclasspath.bat" %1 if errorlevel 1 goto end
設(shè)置一個(gè)臨時(shí)環(huán)境變量: CLASSPATH.
如果 Tomcat 的 bin 目錄下面存在 setnv.bat 腳本的話, 就執(zhí)行它. 通常情況下是沒有的.
繼而又判斷 setclasspath.bat 腳本是否存在, 如果不存在的話, 直接報(bào)錯(cuò), 停止啟動(dòng) Tomcat.
如果存在的話, 就去調(diào)用它, 并把 第一個(gè)參數(shù)傳進(jìn)去.
setclasspath.bat 這個(gè)腳本主要設(shè)置了幾個(gè)環(huán)境變量
- JAVA_HOME
- JRE_HOME
- JAVA_ENDORSED_DIRS = %CATALINA_HOME%\endorsed
- _RUNJAVA = %JRE_HOME%\bin\java.exe
- _RUNJDB = %JAVA_HOME%\bin\jdb.exe
第五段腳本代碼
rem Add on extra jar file to CLASSPATH rem Note that there are no quotes as we do not want to introduce random rem quotes into the CLASSPATH if "%CLASSPATH%" == "" goto emptyClasspath set "CLASSPATH=%CLASSPATH%;" :emptyClasspath set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar" if not "%CATALINA_TMPDIR%" == "" goto gotTmpdir set "CATALINA_TMPDIR=%CATALINA_BASE%\temp" :gotTmpdir rem Add tomcat-juli.jar to classpath rem tomcat-juli.jar can be over-ridden per instance if not exist "%CATALINA_BASE%\bin\tomcat-juli.jar" goto juliClasspathHome set "CLASSPATH=%CLASSPATH%;%CATALINA_BASE%\bin\tomcat-juli.jar" goto juliClasspathDone :juliClasspathHome set "CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\bin\tomcat-juli.jar" :juliClasspathDone
這段代碼主要做了三件事:
- 把 Tomcat bin 目錄下的 bootstrap.jar 加入到環(huán)境變量中
- 設(shè)置 CATALINA_TMPDIR 環(huán)境變量的值為 Tomcat 目錄下的 temp 目錄
- 把 Tomcat bin 目錄下的 tomcat-juli.jar 加入到環(huán)境變量中
第六段腳本代碼
if not "%JSSE_OPTS%" == "" goto gotJsseOpts set JSSE_OPTS="-Djdk.tls.ephemeralDHKeySize=2048" :gotJsseOpts set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS%" rem Register custom URL handlers rem Do this here so custom URL handles (specifically 'war:...') can be used in the security policy set "JAVA_OPTS=%JAVA_OPTS% -Djava.protocol.handler.pkgs=org.apache.catalina.webresources" if not "%LOGGING_CONFIG%" == "" goto noJuliConfig set LOGGING_CONFIG=-Dnop if not exist "%CATALINA_BASE%\conf\logging.properties" goto noJuliConfig set LOGGING_CONFIG=-Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties" :noJuliConfig set "JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%" if not "%LOGGING_MANAGER%" == "" goto noJuliManager set LOGGING_MANAGER=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager :noJuliManager set "JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%"
主要是追加一系列的啟動(dòng)參數(shù)到 JAVA_OPTS 這個(gè)環(huán)境變量中.
第八段腳本代碼
echo Using CATALINA_BASE: "%CATALINA_BASE%" echo Using CATALINA_HOME: "%CATALINA_HOME%" echo Using CATALINA_TMPDIR: "%CATALINA_TMPDIR%" if ""%1"" == ""debug"" goto use_jdk echo Using JRE_HOME: "%JRE_HOME%" goto java_dir_displayed :use_jdk echo Using JAVA_HOME: "%JAVA_HOME%" :java_dir_displayed echo Using CLASSPATH: "%CLASSPATH%"
主要是打印相關(guān)的環(huán)境變量信息.
第九段腳本代碼
set _EXECJAVA=%_RUNJAVA% set MAINCLASS=org.apache.catalina.startup.Bootstrap set ACTION=start set SECURITY_POLICY_FILE= set DEBUG_OPTS= set JPDA=
設(shè)置一些列的環(huán)境變量:
- _RUNJAVA : %JRE_HOME%\bin\java.exe
- MAINCLASS : 指定了 Tomcat 的啟動(dòng)類, 沒錯(cuò) main 方法就是在這個(gè)類里面.
- ACTION : 動(dòng)作: 就是啟動(dòng)
- SECURITY_POLICY_FILE : 安全策略文件, 如果啟動(dòng)的時(shí)候加上了 -security 參數(shù)的話, 下面會(huì)對(duì)這個(gè)參數(shù)指定到 Tomcat 的 conf 目錄下的 catalina.policy 文件.
- JPDA : 這個(gè)參數(shù)可以百度一下, 我們平時(shí)幾乎用不到.
第十段代碼
if not ""%1"" == ""jpda"" goto noJpda set JPDA=jpda if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport set JPDA_TRANSPORT=dt_socket :gotJpdaTransport if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress set JPDA_ADDRESS=localhost:8000 :gotJpdaAddress if not "%JPDA_SUSPEND%" == "" goto gotJpdaSuspend set JPDA_SUSPEND=n :gotJpdaSuspend if not "%JPDA_OPTS%" == "" goto gotJpdaOpts set JPDA_OPTS=-agentlib:jdwp=transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND% :gotJpdaOpts shift :noJpda
好像直接從第一行跳到了最后一行, 沒錯(cuò), 一般我沒啟動(dòng)的時(shí)候沒有加 jpda 參數(shù)的話, 這里會(huì)直接跳過, 里面的腳本是關(guān)于 JPDA 的設(shè)置等.
第十一段腳本代碼
if ""%1"" == ""debug"" goto doDebug if ""%1"" == ""run"" goto doRun if ""%1"" == ""start"" goto doStart if ""%1"" == ""stop"" goto doStop if ""%1"" == ""configtest"" goto doConfigTest if ""%1"" == ""version"" goto doVersion echo Usage: catalina ( commands ... ) echo commands: echo debug Start Catalina in a debugger echo debug -security Debug Catalina with a security manager echo jpda start Start Catalina under JPDA debugger echo run Start Catalina in the current window echo run -security Start in the current window with security manager echo start Start Catalina in a separate window echo start -security Start in a separate window with security manager echo stop Stop Catalina echo configtest Run a basic syntax check on server.xml echo version What version of tomcat are you running? goto end
好似一個(gè) switch 開關(guān).
- 如果我們用 startup.bat 啟動(dòng) Tomcat 的話, 這里的 "%1" 的值是 start
- 如果通過 catalina.bat run 啟動(dòng) Tomcat 的話, 這里的 "%1" 的值是 run
第十二段腳本代碼
:doRun shift if not ""%1"" == ""-security"" goto execCmd shift echo Using Security Manager set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy" goto execCmd :doStart shift if "%TITLE%" == "" set TITLE=Tomcat set _EXECJAVA=start "%TITLE%" %_RUNJAVA% if not ""%1"" == ""-security"" goto execCmd shift echo Using Security Manager set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy" goto execCmd
首先分析一下其中的兩個(gè) shift 命令
第一個(gè) shift 是把 start 或者 run 參數(shù)移除, 然后下面 還是利用 "%1" 來取參數(shù), 這時(shí)候, 取出來的就是參數(shù)列表中的第二個(gè).
第二個(gè) shift 是在第二個(gè)參數(shù)移除掉.
我們?cè)賮肀容^一下 start 和 run 的啟動(dòng)區(qū)別.
差別
if "%TITLE%" == "" set TITLE=Tomcat set _EXECJAVA=start "%TITLE%" %_RUNJAVA%
- 如果是 startup.bat 腳本啟動(dòng)的話, 會(huì)啟動(dòng)一個(gè)新的 cmd 窗口, 并且把 cmd 的 title 設(shè)置為 Tomcat.
- 如果是 catalina.bat run 啟動(dòng)的話, 不會(huì)新建 cmd 窗口, 也不會(huì)設(shè)置 cmd 的 title.
最后都跳到了 execCmd 標(biāo)簽處.
第十三段腳本代碼
:execCmd rem Get remaining unshifted command line arguments and save them in the set CMD_LINE_ARGS= :setArgs if ""%1""=="""" goto doneSetArgs set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 shift goto setArgs :doneSetArgs
這里還是利用 "%1" 來取出啟動(dòng)命令之后的參數(shù), 如果存的話, 追加到 CMD_LINE_ARGS 環(huán)境變量上, 并把這個(gè)參數(shù)移除.
通常情況下, 我們這里是不會(huì)有什么參數(shù)了, -security 這個(gè)參數(shù)我們都不會(huì)追加.
繼續(xù)往下走.
第十四段腳本代碼
rem Execute Java with the applicable properties if not "%JPDA%" == "" goto doJpda if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity %_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% goto end
很明顯, 我們的 %JPDA% 沒有值, 不會(huì)跳轉(zhuǎn); 由于我們沒有加 -security 參數(shù), 所以 %SECURITY_POLICY_FILE% 沒有值, 不會(huì)跳轉(zhuǎn).
下面這段長命令就是來啟動(dòng) BootStrap 類, 并把相應(yīng)的參數(shù)傳進(jìn)去.
只要把對(duì)應(yīng)的環(huán)境變量替換為它們的值, 就可以解析出這個(gè)長命令的內(nèi)容. 相信你可以的. Be patient!
總結(jié)一下
- 首先判斷一下用戶直接使用 catalina.bat run 來啟動(dòng) Tocmat
- 設(shè)置 CATALINA_HOME 和 CATALINA_BASE 環(huán)境變量值
- 驗(yàn)證 CATALINA_HOME 和 CATALINA_BASE 環(huán)境變量值的正確性
- 調(diào)用 setnv.bat 腳本
- 調(diào)用 setclasspath.bat 腳本
- 添加 bootstrap.jar 和 tomcat-juli.jar 到 CLASSPATH 中
- 設(shè)置 CATALINA_TMPDIR 臨時(shí)目錄的值為 Tomcat 目錄下的 temp
- 追加一系列的參數(shù)到 JAVA_OPTS 中
- 整合相關(guān)的啟動(dòng)信息, 參數(shù)
- 啟動(dòng) Tomcat
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,有興趣的朋友可以看下上篇文章《解析Tomcat的啟動(dòng)腳本-startup.bat》
相關(guān)文章
Linux系統(tǒng)下安裝三個(gè)或者多個(gè)tomcat(步驟詳細(xì))
這篇文章主要介紹了Linux系統(tǒng)下安裝三個(gè)或者多個(gè)tomcat(步驟詳細(xì)),文中通過步驟介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04詳解tomcat部署靜態(tài)html網(wǎng)站方法
這篇文章主要介紹了tomcat部署靜態(tài)html網(wǎng)站方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06tomcat8中startup可以啟動(dòng)tomcat8w無法啟動(dòng)的問題分析
這篇文章主要介紹了tomcat8中startup可以啟動(dòng),tomcat8w無法啟動(dòng)的問題,根本原因是windows?服務(wù)內(nèi)沒有tomcat服務(wù),所以無法啟動(dòng),本文給大家分享解決方法,需要的朋友可以參考下2022-08-08window和linux通過tomcat9手工部署war包的方法
這篇文章主要介紹了window和linux通過tomcat9手工部署war包的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-10-10Tomcat中實(shí)現(xiàn)Session小結(jié)
本篇文章主要介紹了Tomcat中實(shí)現(xiàn)Session小結(jié) ,Session的主要目的就是為了彌補(bǔ)Http的無狀態(tài)特性。簡單的說,就是服務(wù)器可以利用session存儲(chǔ)客戶端在同一個(gè)會(huì)話期間的一些操作記錄。2017-01-01Linux部署Tomcat發(fā)布項(xiàng)目過程中各種問題及解決方法
這篇文章主要介紹了解決Linux部署Tomcat發(fā)布項(xiàng)目過程中各種問題,本文通過圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04