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