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