這次標(biāo)題夠長的,在Servlet3協(xié)議規(guī)范中,包含在JAR文件/META-INFO/resources/路徑下的資源可以直接訪問了。這么說一說,可能感覺不到到底有什么好處,以往的JSP或者HTML頁面只能存在站點(diǎn)的目錄下,或者在WEB-INF目錄下(只是不能直接訪問)。
規(guī)范說,${jar}/META-INF/resources/被視為根目錄,假設(shè)home.jsp被放在${jar}/META-INF/resources/home.jsp,用戶可以直接通過 http://域名/home.jsp 訪問了。
呈現(xiàn)一個(gè)常見的代碼片段:
/**
* 簡單示范
* @author yongboy
* @date 2011-1-16
* @version 1.0
*/
@WebServlet("/jarHome")
public class HelloJarServlet extends HttpServlet {
private static final long serialVersionUID = 6177346686921106540L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("date", new Date());
request.getRequestDispatcher("/jarpage/jarhome.jsp").forward(request, response);
}
}
而jarhome.jsp文件路徑則位于 ${jar}/META-INF/resources/jarpage/jarhome.jsp
當(dāng)然jarhome.jsp文件則沒有什么特別之處:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="css/style.css" type="text/css" />
<title>Welcome to jar home</title>
</head>
<body>
<img alt="j2ee" src="img/j2ee.png" /><br/>
<br/>
now date : <%=((java.util.Date)request.getAttribute("date")).toString()%>
</body>
</html>
jarhome.jsp文件所引用css/style.css和img/j2ee.png等文件分別位于 ${jar}/META-INF/resources/css/style.css和${jar}/META-INF/resources/img/j2ee.png目錄下。
把生成的jar文件存放在 WEB-INF/lib/ 中,下面為一個(gè)運(yùn)行示范圖:

樣式和圖片等都可以正常訪問。
有時(shí)候可能需要使用路徑信息等,再看一個(gè)示范吧:
/**
* 演示jarDemo
*
* @author yongboy
* @date 2011-1-16
* @version 1.0
*/
@WebServlet("/jarDemo")
public class DemoWebINFPagesServlet extends HttpServlet {
private static final long serialVersionUID = -1040850432869481349L;
private static final Log log = LogFactory
.getLog(DemoWebINFPagesServlet.class);
@SuppressWarnings("deprecation")
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
log.info("the /jarDemo is accessed now!");
log.info("getRealPath : " + request.getRealPath("/"));
log.info("ServletContext : getRealPath : "
+ getServletContext().getRealPath("/"));
log.info("getPathTranslated : " + request.getPathTranslated());
log.info("get jar's resource:");
InputStream is = getServletContext().getResourceAsStream(
"/jarfile/demo.txt");
log.info("the JAR/META-INF/resources/jarfile/demo.txt's content is :\n"
+ IOUtils.toString(is));
request.getRequestDispatcher("/WEB-INF/pages/notaccess.jsp");
}
}
輸入命令行信息為:
[framework] 2011-01-03 11:45:16,664 - com.learn.servlet3.jardync.DemoWebINFPagesServlet -798292 [http-8080-exec-6] INFO com.learn.servlet3.jardync.DemoWebINFPagesServlet - the /jarDemo is accessed now!
[framework] 2011-01-03 11:45:16,664 - com.learn.servlet3.jardync.DemoWebINFPagesServlet -798292 [http-8080-exec-6] INFO com.learn.servlet3.jardync.DemoWebINFPagesServlet - getRealPath : /home/yongboy/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/d/
[framework] 2011-01-03 11:45:16,664 - com.learn.servlet3.jardync.DemoWebINFPagesServlet -798292 [http-8080-exec-6] INFO com.learn.servlet3.jardync.DemoWebINFPagesServlet - ServletContext : getRealPath : /home/yongboy/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/d/
[framework] 2011-01-03 11:45:16,665 - com.learn.servlet3.jardync.DemoWebINFPagesServlet -798293 [http-8080-exec-6] INFO com.learn.servlet3.jardync.DemoWebINFPagesServlet - getPathTranslated : null
[framework] 2011-01-03 11:45:16,665 - com.learn.servlet3.jardync.DemoWebINFPagesServlet -798293 [http-8080-exec-6] INFO com.learn.servlet3.jardync.DemoWebINFPagesServlet - get jar's resource:
[framework] 2011-01-03 11:45:16,665 - com.learn.servlet3.jardync.DemoWebINFPagesServlet -798293 [http-8080-exec-6] INFO com.learn.servlet3.jardync.DemoWebINFPagesServlet - the ${JAR}/META-INF/resources/jarfile/demo.txt's content is :
haha,the demo.s's content!
haha,haha,haha!
可以看到getRealPath("/")得到的是項(xiàng)目的根路徑(可以參照J(rèn)AR解壓后的路徑)。而request.getPathTranslated則因?yàn)槭前趈ar文件中(規(guī)范中說包含在遠(yuǎn)程主機(jī)、數(shù)據(jù)庫、JAR存檔文件中,getPathTranslated都會(huì)返回null),則返回null。
包含在jar中的資源文件,一樣可以使用getResourceAsStream獲取到。
再來看看jar文件META-INF/resources目錄下文件結(jié)構(gòu):
- css/style.css
- img/j2ee.png
- jarfile/demo.txt
- jarpage/jarhome.jsp
- jsp/h.jsp
- jsp/helloWorld.jsp
很顯然,就是一個(gè)小型站點(diǎn)目錄結(jié)構(gòu)。
每一個(gè)模塊,建立一個(gè)WEB站點(diǎn)應(yīng)用,使用ANT腳本自動(dòng)打包成jar文件,拷貝到真正站點(diǎn)WEB-INF/lib下。
假設(shè)一個(gè)JAR文件包含一個(gè)具體的模塊,那么模塊的部署與裝載將是十分方便的。