2022. 2. 19. 09:28
Customizing Tomcat Directory Listings Java/Apache Tomcat2022. 2. 19. 09:28
https://tomcat.apache.org/tomcat-9.0-doc/default-servlet.html
톰캣 공식 문서를 참조했다.
1. 특정 Application에서만 디렉토리를 열어주기 위해 Web Application의 web.xml에 아래와 같이 추가함.
<!-- /WEB-INF/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><!--이부분을 true로 해준다-->
</init-param>
<init-param>
<param-name>sortListings</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>sortDirectoriesFirst</param-name>
<param-value>true</param-value><!--디렉토리를 먼저 보여줌-->
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
급하게 톰캣의 디렉토리를 임시적으로 오픈해줘야할 상황이 생겨서 위와 같이 조치했지만, 타임존이 위와같이 GMT로 되어있다.
이걸 GMT+9:00으로 바꿔보려 옵션을 찾아봤는데 의외로 쉬운일이 아니었음.
톰캣에서 사용하는 클래스를 찾아보니 포맷과 언어 TimeZone이 모두 하드코딩되어 있어서, 옵션처리는 처음부터 안되는 거.
//org.apache.tomcat.util.http.FastHttpDateFormat 의 일부
static {
TimeZone tz = TimeZone.getTimeZone("GMT");
FORMAT_RFC5322 = new ConcurrentDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US, tz);
FORMAT_OBSOLETE_RFC850 = new ConcurrentDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US, tz);
FORMAT_OBSOLETE_ASCTIME = new ConcurrentDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US, tz);
httpParseFormats = new ConcurrentDateFormat[]{FORMAT_RFC5322, FORMAT_OBSOLETE_RFC850, FORMAT_OBSOLETE_ASCTIME};
currentDateGenerated = 0L;
currentDate = null;
formatCache = new ConcurrentHashMap(CACHE_SIZE);
parseCache = new ConcurrentHashMap(CACHE_SIZE);
}
그래서 아래 사이트를 참조하여 xslt에서 String을 Date로 파싱후 다시 새로운 포맷으로 출력하는 방식으로 처리함.
1. contextXsltFile를 사용함.
<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>contextXsltFile</param-name>
<param-value>/WEB-INF/myDirectory.xslt</param-value>
</init-param>
<!-- 새롭게 추가된 부분 -->
<init-param>
<param-name>sortListings</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>sortDirectoriesFirst</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2. /WEB-INF/myDirectory.xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
xmlns:tz="java.util.TimeZone"
xmlns:lc="java.util.Locale"
xmlns:cdf="org.apache.tomcat.util.http.ConcurrentDateFormat"
xmlns:java="http://xml.apache.org/xalan/java"
exclude-result-prefixes="xsl tz lc cdf java">
<!-- 선언부에 import 설정-->
<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>[<xsl:value-of select="@directory"/>] 디렉토리 목록</title>
<style>
body {font-family:'Malgun Gothic', '맑은 고딕', Arial, sans-serif;
color:black;background-color:white;}
h1, h2, h3, b {color:white; background-color:#3e3832;}
h1 {font-size:22px}
h2 {font-size:16px}
h3 {font-size:14px}
a {color : black;}
h1 a {color:white;}
p {font-size:12px;}
pre{margin:0}
HR {height:1px;background:#525D76;border:none;color:#0086b2;}
table {border:1px solid #dae1e6; border-collapse:collapse;}
th, td {border:1px solid #dae1e6;vertical-align:middle;padding:5px;height:25px}
th {text-align:center;background-color:#fcf3eb;}
</style>
</head>
<body>
<h1>
ContextPath : [<xsl:value-of select="@contextPath"/>]
디렉토리명 : [<xsl:value-of name="directory" select="@directory"/>]
</h1>
<hr/>
<table style="width: 100%;">
<colgroup>
<col style="width:auto"/>
<col style="width:200px"/>
<col style="width:100px"/>
<col style="width:100px"/>
</colgroup>
<tr>
<th>이름</th>
<th>수정한 날짜</th>
<th>유형</th>
<th>크기</th>
</tr>
<xsl:if test="@directory != '' ">
<tr>
<td><a href="../"><pre>[..] 상위폴더로 이동</pre></a></td>
<td></td>
<td></td>
<td></td>
</tr>
</xsl:if>
<xsl:apply-templates select="entries"/>
</table>
<xsl:apply-templates select="readme"/>
<hr/>
</body>
</html>
</xsl:template>
<xsl:template match="entries">
<xsl:apply-templates select="entry">
<xsl:sort select="@type"/><!--폴더가 먼저 보이도록 정렬-->
</xsl:apply-templates>
</xsl:template>
<xsl:template match="readme">
<hr/>
<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: center;">
<!-- 날짜 TimeZone 변경-->
<xsl:variable name="inFormat" select="cdf:new('EEE, dd MMM yyyy HH:mm:ss z', lc:new('en', 'US'), tz:getTimeZone('GMT'))" />
<xsl:variable name="inDate" select="cdf:parse($inFormat, @date)"/>
<xsl:variable name="outFormat" select="cdf:new('yyyy-MM-dd(EEE) HH:mm:ss', lc:new('ko', 'KR'), tz:getTimeZone('Asia/Seoul'))" />
<pre><xsl:value-of select="cdf:format($outFormat, $inDate)" /></pre>
</td>
<td style="text-align: center;">
<pre><xsl:value-of select="@type"/></pre>
</td>
<td style="text-align: right;">
<pre><xsl:value-of select="@size"/></pre>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
아쉬운거는 xsl을 사용하면 sortListings, sortDirectoriesFirst 옵션이 무시돼서 xsl에서 별도로 sorting을 해줘야 한다는 점?
'Java > Apache Tomcat' 카테고리의 다른 글
tomcat IPv4 셋팅 (0) | 2023.07.25 |
---|---|
Tomcat setenv.bat (0) | 2022.02.26 |
IIS와 Tomcat 연동시 오류 (0) | 2021.02.12 |
Apache HTTP Server vs Apache Tomcat (0) | 2014.03.15 |