本貼主要介紹了 Latke 的關(guān)鍵配置及其設(shè)計(jì)用意,所以無(wú)論你是 Latke 的 開發(fā)者 還是基于 Latke 開發(fā)的產(chǎn)品的 使用者,希望本貼能夠幫助到你。
為了說明方便,我們會(huì)使用 Solo 博客系統(tǒng)作為主要的應(yīng)用場(chǎng)景進(jìn)行舉例。
文件路徑是 WEB-INF/classes/latke.properties
,該配置文件是 必須的。通常情況其中的配置項(xiàng)比較少,最簡(jiǎn)化的情況是只需要配置 #### Server ####
部分的 3 個(gè)項(xiàng),其他項(xiàng)都有默認(rèn)值,不需要顯示設(shè)置。
一些 Solo 用戶在初始化時(shí)會(huì)遇到“配置錯(cuò)誤”的問題,這是因?yàn)?latke.props 沒有配置或配置不當(dāng)造成的。該配置文件中 #### Server ####
部分的默認(rèn)配置如下:
#### Server ####
## Browser visit protocol
serverScheme=http
## Browser visit domain name
serverHost=localhost
## Browser visit port, 80 as usual, THIS IS NOT SERVER LISTEN PORT!
serverPort=8080
這 3 個(gè)配置項(xiàng)需要配置為用戶通過瀏覽器 訪問時(shí)候 的值。換句話說,如果你的服務(wù)在本機(jī)啟動(dòng),那么默認(rèn)的配置是可以讓你在本機(jī)通過 http://localhost:8080
訪問時(shí)一切正常的;但非本機(jī)訪問時(shí)(比如通過 http://domain-or-ip:8080
) 就 不能 正常加載靜態(tài)資源了。
解決方案:將這三個(gè)配置項(xiàng)的值調(diào)整為最終訪問時(shí)候?qū)?yīng)的樣子。
比如我的博客域名是 myblog.com,該域名已經(jīng)正常解析到服務(wù)器 IP,此時(shí)只需要將 serverHost
的值設(shè)置為 myblog.com
就可以通過 http://myblog.com:8080
訪問了。要進(jìn)一步消除后面的端口有兩種方式:
推薦第一種方式,因?yàn)椋篠ervlet 容器主要是 Java Web 應(yīng)用的處理環(huán)境,主要處理的是動(dòng)態(tài)請(qǐng)求。HTTPS 或者是靜態(tài)資源請(qǐng)求應(yīng)該交由更專業(yè)的 HTTP 處理引擎來(lái)做,這樣能減少很多復(fù)雜的配置(比如配置 Java 的 SSL 證書),也能充分優(yōu)化性能(比如靜態(tài)資源由 NGINX 處理,配置 Cache、限流等)。
一個(gè)正確的配置 樣例 如下:
#### Server ####
## Browser visit protocol
serverScheme=http
## Browser visit domain name
serverHost=myblog.com
## Browser visit port, 80 as usual, THIS IS NOT SERVER LISTEN PORT!
serverPort=
請(qǐng)注意其中 serverPort
項(xiàng)并沒有賦值,因?yàn)檫@樣就能夠使用 HTTP 的瀏覽器默認(rèn)端口 80 了,HTTPS 也可以這樣留空。
該部分通常情況是沒有顯示配置的(比如 Solo 里面默認(rèn)的配置文件就沒有出現(xiàn)這部分),需要顯示配置的情況是需要做 動(dòng)靜分離 的應(yīng)用場(chǎng)景。
前面我們提到過可以通過 NGINX 作為前置服務(wù)器,將靜態(tài)資源請(qǐng)求分離出來(lái)進(jìn)行處理。其具體的分離規(guī)則可以按 path 或后綴。這個(gè)動(dòng)靜分離的層次是在具體服務(wù)器節(jié)點(diǎn)上的分離,是用戶請(qǐng)求到達(dá)內(nèi)部網(wǎng)絡(luò)后的處理。
我們可以在用戶瀏覽器請(qǐng)求時(shí)就進(jìn)行動(dòng)靜分離,將靜態(tài)資源請(qǐng)求分發(fā)到配置好的 CDN 服務(wù)上,這個(gè) CDN 服務(wù)一般是一個(gè)域名地址。而 staticServerScheme
、staticServerHost
、staticServerPort
這三項(xiàng)就是用來(lái)配置該地址的,如果沒有顯示配置,則這三項(xiàng)會(huì)分別使用 serverScheme
、serverHost
、serverPort
的值。
下面這些配置項(xiàng)也是在某些場(chǎng)景才會(huì)用到,一般來(lái)說也不用單獨(dú)配置的。
項(xiàng) | 說明 | 默認(rèn)值 | 備注 |
---|---|---|---|
runtimeMode | 運(yùn)行模式,可選值 DEVELOPMENT 或 PRODUCTION |
PRODUCTION |
線上環(huán)境一定要使用 PRODUCTION |
staticResourceVersion | 靜態(tài)資源版本號(hào),主要用于刷緩存 | 默認(rèn)取服務(wù)啟動(dòng)的時(shí)間毫秒 | |
contextPath | 容器上下文路徑 | 自動(dòng)獲取部署上下文路徑 | 會(huì)和 虛擬目錄 的配置相關(guān) |
staticPath | 靜態(tài)資源服務(wù)的上下文路徑 | 同 contextPath |
顯示配置的話一般都是留空 |
其中“上下文路徑”是 Java Servlet 中的概念,指的是請(qǐng)求 URL 上第一層目錄路徑,比如對(duì)于 http://mydomain.com/solo/login
,/solo 就是上下文路徑,但該值也和部署目錄相關(guān),本例需要應(yīng)用部署在 tomcat/webapps/solo
目錄中,如果應(yīng)用部署在 ROOT 目錄下,那上下文路徑就是空字符串。
順便吐槽一下,“上下文路徑”這個(gè)概念是 Java Servlet 規(guī)范里面特有的,是一個(gè)很奇葩的設(shè)計(jì),標(biāo)準(zhǔn)的 HTTP 協(xié)議是沒有這個(gè)設(shè)定的,并且 Servlet API 中定義的 Request URI 和 URI RFC 定義的完全不是一個(gè)東西,關(guān)于 URI 和 URL 的正解請(qǐng)看這里。
文件路徑是 WEB-INF/classes/local.properties
,該文件是 必須的,主要用于配置數(shù)據(jù)庫(kù)。比如在 Solo 中默認(rèn)的配置如下:
#### H2 runtime ####
runtimeDatabase=H2
jdbc.username=root
jdbc.password=
jdbc.driver=org.h2.Driver
jdbc.URL=jdbc:h2:~/solo_h2/db
jdbc.pool=h2
#### MySQL runtime ####
#runtimeDatabase=MYSQL
#jdbc.username=root
#jdbc.password=
#jdbc.driver=com.mysql.jdbc.Driver
#jdbc.URL=jdbc:mysql://localhost:3306/solo?useUnicode=yes&characterEncoding=utf8
#jdbc.pool=druid
## The minConnCnt MUST larger or equal to 3
jdbc.minConnCnt=5
jdbc.maxConnCnt=10
## Be care to change the transaction isolation
jdbc.transactionIsolation=REPEATABLE_READ
## The specific table name prefix
jdbc.tablePrefix=b3_solo
其中 #### H2 runtime ####
和 #### MySQL runtime ####
只能啟用一種,該部分配置了使用哪一種數(shù)據(jù)庫(kù)實(shí)現(xiàn)。
其他的配置項(xiàng)比較好識(shí)別,一般來(lái)說使用默認(rèn)值就好。
默認(rèn)使用應(yīng)用內(nèi)嵌的 H2 數(shù)據(jù)庫(kù),其中 jdbc.URL
中可以配置數(shù)據(jù)持久化的文件路徑,比如 jdbc:h2:~/solo_h2/db
使用的路徑就是 操作系統(tǒng)用戶 home (即 ~
)下的 solo_h2/db 目錄,在 Java 中對(duì)于的系統(tǒng)變量是 ${user.home},如果你不大熟悉 Unix-like 的表示法,也可以將該路徑配置成完整的絕對(duì)路徑,比如 jdbc:h2:D:/solo_h2/db
。
文件路徑是 WEB-INF/classes/mail.properties
,該配置文件是可選的。在 Solo 中如果正確進(jìn)行了配置,將會(huì)在有文章評(píng)論時(shí)發(fā)送郵件,下面是默認(rèn)配置:
mail.user=b3log.solo@gmail.com
mail.password=
mail.debug=false
mail.smtp.host=smtp.gmail.com
mail.smtp.port=587
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
mail.smtp.socketFactory.fallback=false
mail.smtp.socketFactory.port=465
和前面的配置項(xiàng)類似,郵件的配置也有一些隱式默認(rèn)項(xiàng):
項(xiàng) | 說明 | 默認(rèn)值 |
---|---|---|
mail.smtp.auth | 是否啟用身份驗(yàn)證 | true |
mail.smtp.starttls.enable | 是否啟用 SSL 連接 | true |
文件路徑是 WEB-INF/static-resources.xml
,該配置文件是 必須的,用于配置靜態(tài)資源路徑。
每款 Servlet 容器都有一個(gè)“默認(rèn)的 Servlet”來(lái)處理請(qǐng)求,并包括了對(duì)靜態(tài)資源 IO 的優(yōu)化實(shí)現(xiàn),所以我們需要根據(jù)請(qǐng)求路徑將靜態(tài)資源請(qǐng)求分發(fā)到該 Servlet 上。
路徑的匹配模式是 Ant-style 匹配,簡(jiǎn)單說來(lái)就是:
*
匹配多個(gè)字符?
匹配單個(gè)字符**
匹配多層目錄 如果你需要 添加自己的靜態(tài)資源(比如 HTML、MP3 等)就需要修改一下該文件。
Latke 對(duì)于“默認(rèn)的 Servlet”支持如下:
default
resin-file
FileServlet
SimpleFileServlet
在 HTTP 層,我們希望 Latke 是一個(gè)對(duì) Servlet 的輕薄封裝,這需要開發(fā)者對(duì) Servlet 規(guī)范有一定了解,以最大的自由度來(lái)組合自己熟悉的工具庫(kù),比如:
在實(shí)體模型 / 持久化層,Latke 做了一個(gè)較創(chuàng)新的設(shè)計(jì)嘗試,即使用 JSON 進(jìn)行貫穿、無(wú)實(shí)體類。較理想的應(yīng)用實(shí)現(xiàn)場(chǎng)景是前端提交的請(qǐng)求數(shù)據(jù)以 JSON 作為格式,該 JSON 在 Controller、Service 中做處理(校驗(yàn)、增減字段等)后就能直接保存到關(guān)系型數(shù)據(jù)庫(kù)中,免去很多無(wú)謂的類型轉(zhuǎn)換和復(fù)雜的 ORM。
除了實(shí)體模型,其他的類對(duì)象(控制器、服務(wù)、切面、事件、插件、定時(shí)任務(wù)、緩存等)都是使用 IoC 容器進(jìn)行管理的,這一點(diǎn)和 Spring 核心原理一致。因?yàn)?IoC / AOP 確實(shí)有用,也是業(yè)界主流技術(shù)。
Latke 整體的設(shè)計(jì)理念是 在不影響開發(fā)效率的前提下,讓開發(fā)者懂得 Java Web 的基本原理。
框架只是輔助,原理才是根本。一個(gè)框架如果讓開發(fā)者 知其然而不知其所以然 表面上是提高了生產(chǎn)效率,但本質(zhì)上是在坑害它的使用者。Latke 并不是快餐,而是可以細(xì)細(xì)品味的粗茶淡飯。
更多建議: