簡單的Tomcat實現--3.3 歡迎頁面
阿新 • • 發佈:2020-08-06
歡迎頁面
-
當服務啟動之後,如果指定的某個Context沒有指定頁面,也就是uri為
/
,那麼預設進入index.html
或者index.jsp
-
實現的思想就是,在專案配置資料夾conf下建立一個web.xml,這個配置檔案中儲存著設定好的檔案,當一個訪問未指定具體的哪個檔案時,就去解析這個檔案,獲取其中存在的檔案。
-
<?xml version="1.0" encoding="UTF-8" ?> <web-app> <welcome-file-list> <welcome-file>index.heml</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
-
建立工具類webXmlUtil來解析這個檔案
-
package jerrymice.util; import cn.hutool.core.io.FileUtil; import jerrymice.catalina.Context; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.File; /** * @author xsl20 */ public class WebXmlUtil { public static String getWelcomeFile(Context context) { String xml = FileUtil.readUtf8String(Constant.webXmlFile); Document document = Jsoup.parse(xml); Elements elements = document.select("welcome-file"); for (Element element : elements) { File tmpFile = new File(context.getDocBase(), element.text()); if (tmpFile.exists()) { // 如果找到了配置檔案中指定的檔案 return tmpFile.getName(); } } return "index.html"; } }
-
下面改動Request類,根據請求解析其uri,然後先直接根據uri來獲取context物件,這樣就可以保證像
/b
這樣的訪問可以獲取到context,如果此時獲取到的context不為null,那麼就直接返回即可,如果獲取到的context為null,那麼就說明此時的uri不是一個資料夾或者是一個不存在的資料夾,那就繼續向下執行,嘗試從uri中解析出path,如果獲取到的path為null,那麼訪問的就是ROOT目錄下的檔案,如果不為空,就用這個path去獲取context物件,如果獲取到context物件為空,說明沒有這個path,那麼將context的path指定為根目錄下的那個context。儘管這個context是對應著根目錄的,但是uri並沒有變,例如訪問一個不存在的目錄/c/
/
,但是這個uri對應的fileName是c/
,這個檔案本身並不存在,所以會報404錯誤。 -
public void parseContext(){ Engine engine = service.getEngine(); // 根據獲取到的uri去掃描得到的對映中去尋找這個資料夾,這樣/b就能夠獲取匹配而不一定是/b/ context = engine.getDefaultHost().getContext(uri); if (context != null) { return; } String path = StrUtil.subBetween(uri, "/", "/"); if (null == path) { // 如果uri = /timeConsume.html,那麼path = null, 不對uri進行改動 path = "/"; } else { // uri = /dir1/1.html, 那麼path= dir1, 經過此處之後path=/dir1 // uri = /b/, path = /b path = "/" + path; } context = engine.getDefaultHost().getContext(path); if (null == context){ context = engine.getDefaultHost().getContext("/"); } }
-
public Request(Socket socket, Service service) throws IOException { this.socket = socket; this.service = service; parseHttpRequest(); if (StrUtil.isEmpty(requestString)){ return; } parseUri(); parseContext(); // 比如 uri 是 /a/index.html, 獲取出來的 Context路徑不是 "/”, 那麼要修正 uri 為 /index.html if (!"/".equals(context.getPath())){ // 如果訪問的地址是/a,那麼經過remove之後uri就變為“”了,考慮到這種情況,讓uri等於"/" uri = StrUtil.removePrefix(uri, context.getPath()); if (StrUtil.isEmpty(uri)){ uri = "/"; } } }
-
uri 最後都會被修正為
/檔名
的形式, 然後在server中再去掉前面的/
,得到檔名 -
下面是Server類的修改
-
if("/".equals(uri)){ uri = WebXMLUtil.getWelcomeFile(request.getContext()); }
-
當uri是根目錄時,就去訪問配置檔案中指定的那幾個檔案中存在的那一個,如果都不存在的話,就預設訪問
index.html
,這會報404錯誤。 -
測試結果
- 當訪問
/b/
時,會自動跳轉到/b/index.html
- 當訪問