沒有需求,就沒有折騰
不過我還是喜歡折騰,只要有目的,就要嗨起來。
先說一下背景。
某天,產品小伙伴過來提了一個需求:能不能把公司的需求文檔以列表的方式展示出來,當開發者需要哪個的時候,自己在目錄中尋找并點擊進入(需要哪個點哪個,so easy),也就不用記錄那么多文檔url了。
另外說明一下,公司的需求文檔是以文件夾和html組織形式部署在tomcat的,版本8,這是前提。
聽完需求,格子的腦袋就開始運轉起來,這不是分分鐘能搞定的事嗎,袖子擼起來,說做咱做。
眾(Java)所(程序猿)周知,一般訪問Tomcat某個目錄時,如果沒有設置歡迎文件的話,是會報找不到的異常的(也就是傳說中的404),如果你開心的話,是可以設置歡迎文件來防止404,顯然這個方法是解決不了我們的需求的,確切來說,是沒辦法簡單解決。(如果非要解決,思路無非是這樣,設置歡迎文件,在歡迎文件里讀取當前目錄,并將目錄下的子目錄遍歷作為列表展示給訪問者,這里不做討論,愛咋咋地)
片頭結束,開始正片,tomcat是提供目錄訪問功能的,請不要眨眼觀看下列實驗步驟。
1、在webapp下新建目錄,并啟動tomcat
#目錄結構
/webapps
/zoro
/dir1
/dir2
/dir3
/dir4
/dir5
/dir6
#啟動tomcat
#如果是Windows請執行startup.bat
→startup.bat(雙擊運行)
#如果是linux請執行startup.sh
cd $CATALINA_BASE/bin
chmod *.sh (如果已賦權,請忽略)
./bin/startup.sh
接下來,訪問http://localhost/zoro
觀看效果,是不是看到了,甩手就是一個404
2、修改tomcat配置
#編輯tomcat配置目錄下的web的xml文件
vim $CATALINA_BASE/conf/web.xml
#大概在100來行,可以看到如下一串神秘代碼
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
把上面的listings的值改為true
,然后重啟tomcat查看效果。
是不是很丑,我也覺得很丑,對于我這種顏控來說,簡直不忍直視,看不下去了,那就開始整容。
3、定制目錄列表
在web.xml的90幾行(上面那串神秘代碼之上),有這樣一些注釋
<!-- ================== Built In Servlet Definitions ==================== -->
<!-- The default servlet for all web applications, that serves static -->
<!-- resources. It processes all requests that are not mapped to other -->
<!-- servlets with servlet mappings (defined either here or in your own -->
<!-- web.xml file). This servlet supports the following initialization -->
<!-- parameters (default values are in square brackets): -->
<!-- -->
<!-- debug Debugging detail level for messages logged -->
<!-- by this servlet. [0] -->
<!-- -->
<!-- fileEncoding Encoding to be used to read static resources -->
<!-- [platform default] -->
<!-- -->
<!-- input Input buffer size (in bytes) when reading -->
<!-- resources to be served. [2048] -->
<!-- -->
<!-- listings Should directory listings be produced if there -->
<!-- is no welcome file in this directory? [false] -->
<!-- WARNING: Listings for directories with many -->
<!-- entries can be slow and may consume -->
<!-- significant proportions of server resources. -->
<!-- -->
<!-- output Output buffer size (in bytes) when writing -->
<!-- resources to be served. [2048] -->
<!-- -->
<!-- readonly Is this context "read only", so HTTP -->
<!-- commands like PUT and DELETE are -->
<!-- rejected? [true] -->
<!-- -->
<!-- readmeFile File to display together with the directory -->
<!-- contents. [null] -->
<!-- -->
<!-- sendfileSize If the connector used supports sendfile, this -->
<!-- represents the minimal file size in KB for -->
<!-- which sendfile will be used. Use a negative -->
<!-- value to always disable sendfile. [48] -->
<!-- -->
<!-- useAcceptRanges Should the Accept-Ranges header be included -->
<!-- in responses where appropriate? [true] -->
<!-- -->
<!-- For directory listing customization. Checks localXsltFile, then -->
<!-- globalXsltFile, then defaults to original behavior. -->
<!-- -->
<!-- localXsltFile Make directory listings an XML doc and -->
<!-- pass the result to this style sheet residing -->
<!-- in that directory. This overrides -->
<!-- contextXsltFile and globalXsltFile[null] -->
<!-- -->
<!-- contextXsltFile Make directory listings an XML doc and -->
<!-- pass the result to this style sheet which is -->
<!-- relative to the context root. This overrides -->
<!-- globalXsltFile[null] -->
<!-- -->
<!-- globalXsltFile Site wide configuration version of -->
<!-- localXsltFile. This argument must either be an -->
<!-- absolute or relative (to either -->
<!-- $CATALINA_BASE/conf or $CATALINA_HOME/conf) -->
<!-- path that points to a location below either -->
<!-- $CATALINA_BASE/conf (checked first) or -->
<!-- $CATALINA_HOME/conf (checked second).[null] -->
<!-- -->
<!-- showServerInfo Should server information be presented in the -->
<!-- response sent to clients when directory -->
<!-- listings is enabled? [true] -->
屬性 | 描述 |
---|---|
debug | 調試級別,如果不是 tomcat 開發人員,則沒有什么太大的用處。截止本文寫作時,有用的值是 0、1、11、1000。默認值為0。 |
listings | 如果沒有歡迎文件,要不要顯示目錄列表?值可以是true 或 false。歡迎文件是servlet api的一部分。警告:目錄列表中含有的很多項目都是非常消耗服務性能的,如果對大型目錄列表多次進行請求,會嚴重消耗服務器資源。 |
gzip | 如果某個文件存在gzip格式的文件(帶有gz后綴名的文件通常就在原始文件旁邊)。如果用戶代理支持 gzip 格式,并且啟用了該選項,Tomcat 就會提供該格式文件的服務。默認為 false。如果直接請求帶有 gz 后綴名的文件,是可以訪問它們的,所以如果原始資源受安全挾制的保護,則 gzip 文件也同樣是受保護的。 |
readmeFile | 如果提供了目錄列表,那么可能也會提供隨帶的 readme 文件。這個文件是被插入的,因此可能會包含 HTML。 |
globalXsltFile | 如果你希望定制目錄列表,你可以使用一個 XSL 轉換)。這個值是一個可用于所有目錄列表的相對路徑文件名(既相對于 CATALINA_BASE/conf/ 也相對于 $CATALINA_HOME/conf/)。可參看下面介紹的 contextXsltFile 和 localXsltFile。該 xml 文件的格式會在下文介紹。 |
contextXsltFile | 你可以通過contextXsltFile 來定制你的目錄列表。這必須是一個上下文相對路徑(例如:/path/to/context.xslt),相對于帶有 .xsl 或 .xslt 擴展名的文件。它將覆蓋 globalXsltFile。如果提供了該值,但相對文件卻不存在,則將使用 globalXsltFile。如果 globalXsltFile 也不存在,則顯示默認的目錄列表。 |
localXsltFile | 你還可以在每個目錄通過配置 localXsltFile 定制你的目錄列表。它應該是在產生列表的目錄里的一個相對路徑文件名。它覆蓋 globalXsltFile 和 contextXsltFile。如果該值存在,但是文件不存在,那么就使用 contextXsltFile。如果contextXsltFile 也不存在,那么就會使用 globalXsltFile。如果 globalXsltFile 也不存在,那么默認的目錄列表就會被顯示出來。 |
showServerInfo | 當使用目錄列表,服務器信息是否應該提供給發往客戶端的響應中。默認為 true。 |
上述來源:tomcat官網
看完上面的文檔,應該對定制自己的目錄列表有一些思路了。
定制目錄列表需要自己定義globalXsltFile/contextXsltFile/localXsltFile,tomcat提供了定制的example。
話不多說,動手吧,如果諸位看官需要對所有目錄進行同樣的定制,那么可以采用globalXsltFile,如果跟格子一樣,只需要特定目錄下的,那么建議采用localXstlFile
,先用tomcat提供的示例看下效果。
在特定目錄下(格子這里是$CALINA_BASE/webapps/zoro)下新建文件zoro.xslt(or .xsl后綴名要對),然后把下面的代碼拷貝進去~
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0">
<xsl:output method="html" html-version="5.0"
encoding="UTF-8" indent="no"
doctype-system="about:legacy-compat"/>
<xsl:template match="listing">
<html>
<head>
<title>
Sample Directory Listing For
<xsl:value-of select="@directory"/>
</title>
<style>
h1 {color : white;background-color : #0086b2;}
h3 {color : white;background-color : #0086b2;}
body {font-family : sans-serif,Arial,Tahoma;
color : black;background-color : white;}
b {color : white;background-color : #0086b2;}
a {color : black;} HR{color : #0086b2;}
table td { padding: 5px; }
</style>
</head>
<body>
<h1>Sample Directory Listing For
<xsl:value-of select="@directory"/>
</h1>
<hr style="height: 1px;" />
<table style="width: 100%;">
<tr>
<th style="text-align: left;">Filename</th>
<th style="text-align: center;">Size</th>
<th style="text-align: right;">Last Modified</th>
</tr>
<xsl:apply-templates select="entries"/>
</table>
<xsl:apply-templates select="readme"/>
<hr style="height: 1px;" />
<h3>Apache Tomcat/<version-major-minor/></h3>
</body>
</html>
</xsl:template>
<xsl:template match="entries">
<xsl:apply-templates select="entry"/>
</xsl:template>
<xsl:template match="readme">
<hr style="height: 1px;" />
<pre><xsl:apply-templates/></pre>
</xsl:template>
<xsl:template match="entry">
<tr>
<td style="text-align: left;">
<xsl:variable name="urlPath" select="@urlPath"/>
<a href="{$urlPath}">
<pre><xsl:apply-templates/></pre>
</a>
</td>
<td style="text-align: right;">
<pre><xsl:value-of select="@size"/></pre>
</td>
<td style="text-align: right;">
<pre><xsl:value-of select="@date"/></pre>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
保存上面文件后,修改web.xml的神秘代碼
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>
<!--看這里-->
<init-param>
<param-name>localXsltFile</param-name>
<param-value>zoro.xslt</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
重啟tomcat,看效果
是不是好了一些了,但是還是一般般,畢竟是官網提供的示例,也沒辦法漂亮到哪里去,不過定制的方法已經提供,剩下的就是html美化了,各位可以自行發揮。
格子這邊用bootstrap的表格改了一版,如圖
5、再啰嗦幾句
在進行定制化的時候,難免有些特殊需求,雖然繁瑣但是還是可以實現的。
比如格子這邊需要對目錄進行截取,可以在xslt文件中,利用substring函數來實現
<xsl:variable name="urlPath" select="substring(@urlPath,12)"/>
當然,還有很多其他的函數,或者通過java/javasrcipt方式來擴展,畢竟不是本文主題,不做贅述,需要的自行百度。
寫在最后
好久沒寫博客了,求捧場,求點贊,求夸獎。