本作品採用知識共用署名-非商業性使用-相同方式共用 2.5 中國大陸許可協議進行許可。
所謂基於Java的WEB應用,是通過Java技術實現HTTP協議的一種應用。Java技術中實現HTTP協議的核心技術是servlet技術,隨著架構技術的不斷完善,servlet基礎理論逐漸被淡忘,本文所討論的就是被大家淡忘的那些基礎知識。
Java WEB應用基礎理論
統一資源定位器(URL,英語Uniform Resource Locator的縮寫)也被稱為網頁地址,是網際網路上標準的資源地址。
一個典型的URL請求如
http://localhost:8080/hello/index.html
分以下幾個部分,
HTTP協議頭: http://
伺服器位址: localhost (地址可以是IP或網域名稱)
連接埠號碼: 8080(HTTP協議的預設連接埠號碼是80)
應用上下文: /hello(如果應用內容相關的根目錄是ROOT,則應用上下文為空白)
資源或請求: /index.html
Java的servlet技術解決的就是資源或請求的映射問題。
WEB應用的目錄結構
如果要建立一個基於Java的WEB應用,基本的目錄結構如下:
/[WebContent] WEB應用上下文根目錄
/WEB-INF 設定檔所在目錄
web.xml WEB應用核心設定檔
/lib 存放所有jar包的類庫目錄
/classes 存放沒有打包的所有class檔案的類路徑
根據需要,WEB應用上下文可以定義成任意名字或ROOT。
如果WEB應用內容相關的根目錄是ROOT,意味著使用者端在訪問WEB應用時不需要提供WEB應用上下文。如:
http://localhost:8080/index.html
如果WEB應用內容相關的根目錄不是ROOT,使用者端訪問時就必須明示WEB應用上下文。如上下文名為hello的訪問方式:
http://localhost:8080/hello/index.html
/WEB-INF目錄放置了所有不允許使用者直接存取的資源。典型的檔案有web.xml,它是Java Web應用的核心設定檔。
web.xml的主要任務是將使用者的請求映射到不允許使用者直接存取的資源上。
在web.xml中定義的請求
在WEB應用中,一個servlet代表一個URL請求。servlet的表現形式可以是JSP檔案資源,也可以是Servlet類。servlet在web.xml中由<servlet/>和<servlet-mapping/>組成。在<servlet-mapping></servlet-mapping>中指定使用者端的請求方式,在<servlet></servlet>中指定伺服器響應的Servlet類或JSP檔案。例如:
<servlet><br /> <servlet-name>jspIndex</servlet-name><br /> <jsp-file>/WEB-INF/jsp/index.jsp</jsp-file><br /></servlet><br /><servlet><br /> <servlet-name>servletIndex</servlet-name><br /> <servlet-class>test.servlet.IndexServlet</servlet-class><br /></servlet></p><p><servlet-mapping><br /> <servlet-name>jspIndex</servlet-name><br /> <url-pattern>/index.html</url-pattern><br /></servlet-mapping><br /><servlet-mapping><br /> <servlet-name>sevletIndex</servlet-name><br /> <url-pattern>/index.jsp</url-pattern><br /></servlet-mapping>
通過上述例子,可以瞭解以下幾個要點:
1. 通過<servlet-name/>關聯<servlet></servlet>和<servlet-mapping></servlet-mapping>。
2. <url-pattern/>指定了使用者端的請求方式。必須以“/”開頭,請求基於WEB應用上下文。
3. <url-pattern/>指定的請求方式與JSP資源的定位或Servlet類的位置無關。
4. <jsp-file/>指定了JSP資源在WEB應用中的目錄位置。必須以“/”開頭,目錄位置基於WEB應用內容相關的根目錄。
5. <servlet-class/>指定了Servlet類的位置,位置資訊包括包名及類名。
WEB應用的資源定位方式
我們將“/”開頭的路徑稱為絕對路徑,將非“/”開頭的路徑稱為相對路徑。Java資源的常用定位方式有三種:檔案系統定位方式、類路徑定位方式與WEB應用上下文定位方式。檔案系統定位與類路徑定位可以參考《Java資源的定位方式》一文,WEB應用上下文定位是以上下文根目錄為絕對路徑,以資源檔所在目錄為相對路徑進行資源定位。
例如,一個應用內容相關的根目錄為“/hello”的WEB應用中web.xml的描述
<servlet><br /> <servlet-name>jspIndex</servlet-name><br /> <jsp-file>/WEB-INF/jsp/index.jsp</jsp-file><br /></servlet><br /><servlet-mapping><br /> <servlet-name>jspIndex</servlet-name><br /> <url-pattern>/index.html</url-pattern><br /></servlet-mapping>
上面的描述可以為我們提供以下資訊
/WEB-INF/jsp/index.jsp描述了index.jsp檔案的在WEB應用中的目錄位置(它是相對於WEB應用的根目錄的):
/hello(WEB應用內容相關的根目錄)
/WEB-INF
/jsp
index.jsp
程式化的Servlet類
使用者自訂的Servlet類必須繼承自javax.servlet.http.HttpServlet,這樣才可以處理HTTP請求。在web.xml的<servlet></servlet>中必須指明自訂Servlet類的完整包名及類名,如:
<servlet><br /> <servlet-name>servletIndex</servlet-name><br /> <servlet-class>test.servlet.IndexServlet</servlet-class><br /></servlet><br /><servlet-mapping><br /> <servlet-name>sevletIndex</servlet-name><br /> <url-pattern>/index.jsp</url-pattern><br /></servlet-mapping>
Servlet類可以打包成JAR包,存放在/WEB-INF/lib目錄下;也可以不打包,存放在/WEB-INF/classes目錄下。
可以直接存取的資源
/[WebContent]是WEB應用的根目錄,在這個目錄下存放的資源(子目錄或檔案),使用者端可以直接存取,如以下目錄結構:
/hello(WEB應用內容相關的根目錄)
welcome.html
/images
logo.png
/WEB-INF
web.xml
/lib
/classes
基於上述目錄結構的WEB應用,使用者端可以直接存取welcome.html,如:
http://localhost:8080/hello/welcome.html
也可以直接存取logo.png,如:
http://localhost:8080/hello/images/logo.png
在Java WEB應用中,針對一個請求,系統首先會定位web.xml中指定的請求與資源的映射關係,其次才會定位直接可以訪問的資源。
如以下目錄結構:
/hello(WEB應用內容相關的根目錄)
welcome.html
/images
logo.png
/WEB-INF
web.xml
/lib
/classes
/test
/servlet
IndexServlet.class
在web.xml存在以下定義
<servlet><br /> <servlet-name>servletIndex</servlet-name><br /> <servlet-class>test.servlet.IndexServlet</servlet-class><br /></servlet><br /><servlet-mapping><br /> <servlet-name>sevletIndex</servlet-name><br /> <url-pattern>/welcome.html</url-pattern><br /></servlet-mapping>
此時如果使用者端請求/hello/welcome.html,系統定位到的是test.servlet.IndexServlet而不是welcome.html資源檔。
使用基礎理論實現MVC架構
MVC是使用者介面層次(UI層)的架構模式,它主要由三個部分組成:M—Model(模型),V—View(介面),C—Controller(控制器)。在基於Java的WEB應用中MVC架構的基本流程如下:
- 用戶端發出一個request到Web伺服器,request中包括表單資料;
- Controller響應request,從中取得表單資料並校正其有效性,校正通過後將表單資料傳送給Model;
- Model取得表單資料後進行業務處理,並將處理結果傳送給Controller;
- Controller根據處理結果將顯示用的資料儲存到緩衝區中;
- Controller根據處理結果轉向到指定的View;
- View從緩衝區中取得顯示用的資料渲染畫面;
- View將畫面寫到response中。
其中View的角色通常由JSP網頁資源完成,Servlet類則實現了Controller的功能。
Model是業務模組,主要由JavaBeans實現業務處理功能,在這裡不做詳細描述。
提取表單資料的方法
一般表單的提交分POST與GET方式兩種,檔案上傳使用multi-part方式提交表單。在伺服器端,一般表單可以利用request.getParameter()與request.getParameterValues()兩種方法提取資料,multi-part表單可以用以下方式提取資料:
String fileFieldName = "data";<br />MultipartHttpServletRequest multipartHttpServletRequest =<br /> (MultipartHttpServletRequest) request;<br />MultipartFile multipartFile =<br /> multipartHttpServletRequest.getFile(fileFieldName);
不同範圍的緩衝區
根據不同的生命週期,Web應用的緩衝區分request、session和application三種。在JSP檔案中,這三種對象可以直接存取,在Servlet類中,這三種對象的訪問方式如下:
protected void doGet(<br /> // request由Servlet類中的doGet()與doPost()的參數引入<br /> HttpServletRequest request,<br /> HttpServletResponse response)<br /> throws ServletException{</p><p> // session的取得<br /> HttpSession session = request.getSession();</p><p> // application通過Servlet類的getServletContext()取得。<br /> ServletContext application = getServletContext();<br />}
request、session和application均有getAttribute()和setAttribute()方法,用於資料的讀取與儲存。
請求的轉向
Forward和Redirect是servlet的兩種基本轉向方式。
Forward通過以下方式調用:
request.getRequestDispatcher("/index.html").forward(request,response);
Redirect通過以下方式調用:
response.sendRedirect("/index.jsp");
Forward方式在轉向的過程中完整保留了request,session,application中的資料。Redirect方式有保留的儲存了session,application中的資料,但request中的資料不予保留,轉向以後全部丟失。
從商務邏輯上講,轉向操作分站內轉向和站外轉向。
站內轉向是指轉向到站內的其他JSP網頁或者其他的Servlet上,Forward和Redirect兩種方式都可以進行站內轉向。站外轉向是指轉向到其他的網址上,站外轉向只能用Redirect方式完成,Forward方式不具備轉外轉向的功能。
JSP網頁的渲染
在JSP網頁上有多種方法提取緩衝區的方法,最基本的方法是指令碼化語言方式,如:
<% String contextPath = request.getContextPath(); %><br /><form action="<%=contextPath%>/index.html"><br /></form>
JSP2.0之後,EL運算式成為JSP標準的一部分,可以在JSP2.0中直接使用EL運算式。
EL運算式只能讀取request,session及application中的資訊,不能直接中指令碼化語言中取得資料,如:
<%<br /> String contextPath = request.getContextPath();<br /> request.setAttribute("contextPath", contextPath);<br />%><br /><form action="${contextPath}/index.html"><br /></form>
除JSP標準之外,還可以使用大量的第三方標籤庫如JSTL標準標籤庫,Struts標籤庫及Spring標籤庫等等來簡化和完善資料緩衝區的資料讀取與儲存操作。