Java Web 學習(2) —— JSP

JSP

 

1、 什麼是 JSP

JSP 和 Servlet

Servlet 有兩個缺點是沒法克服的:首先,寫在 Servlet 中的全部 HTML 標籤必須包含 Java 字符串,這使得處理HTTP響應報文的工做十分繁瑣;第二,全部的文本和 HTML 標記是硬編碼,致使即便是表現層的微小變化,如改變背景顏色,也須要從新編譯。html

JavaServer Pages(JSP)解決了上述兩個問題。同時,JSP 不會取代 Servlet,相反,它們具備互補性。
JSP 頁面本質上是一個 Servlet。然而,用 JSP 頁面開發比使用 Servlet 更容易。首先,沒必要編譯 JSP 頁面;其次,JSP 頁面是一個以 jsp 爲擴展名的文本文件,可使用任何文本編輯器來編寫它們。 java

JSP 不須要添加註解或在部署描述符配置映射 URL。應用程序目錄中的每個JSP頁面能夠直接在瀏覽器中輸入路徑頁面來訪問。添加新的 JSP 界面後,無需重啓 Tomcat。apache

 

2、 運行 JSP

JSP頁面在JSP容器中運行,一個Servlet容器一般也是JSP容器。例如,Tomcat 就是一個 Servlet/JSP 容器。
當一個 JSP 頁面第一次被請求時,Servlet/JSP 容器主要作如下兩件事情:瀏覽器

1. 把 JSP 頁面轉換到 JSP 頁面實現類,該實現類是一個實現 javax.servlet.jsp.JspPage 接口或子接口 javax.servlet.jsp.HttpJspPage 的 Java 類。JspPage 是 javax.servlet.Servlet 的子接口,這使得每個 JSP 頁面都是一個 Servlet。該實現類的類名由 Servlet/JSP 容器生成。若是出現轉換錯誤,則相關錯誤信息將被髮送到客戶端。
2. 若是轉換成功,Servlet/JSP 容器隨後編譯該 Servlet 類,並裝載和實例化該類,像其餘正常的 Servlet 同樣執行生命週期操做。安全

對於同一個 JSP 頁面的後續請求,Servlet/JSP 容器會先檢查 JSP 頁面是否被修改過。若是是,則該 JSP 頁面會被從新轉換、編譯並執行。若是不是,則執行已經在內存中的 JSP Servlet。
這樣一來,一個JSP頁面的第一次調用的實際花費總比後來的花費多。session

JSP頁面能夠包含模板數據和語法元素(如:'<%'元素表示Java代碼塊的開始)。除語法元素以外的一切都是模板數據。模板數據會原樣發送給瀏覽器。例如,JSP頁面中的HTML標記和文字都是模板數據。jsp

在 Tomcat 中,welcome.jsp 頁面在第一次請求時被轉換成名爲 welcome_jsp 的 Servlet。你能夠在 Tomcat 工做目錄下的子目錄中找到生成的 Servlet,該 Servlet 繼承自 org.apache.jasper.
runtime.HttpJspBase,這是一個抽象類,它繼承自 javax.servlet.http.HttpServlet 並實現了 javax.
servlet.jsp.HttpJspPage。編輯器

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.DateFormat" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Date</title>
</head>
<body>
<%
    DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
    out.println(dateFormat.format(new Date()));
%>
</body>
</html>

 

3、 註釋

JSP支持兩種不一樣的註釋格式:學習

  • JSP註釋。該註釋記錄頁面中作了什麼,不會被髮送到瀏覽器。以"<%--"開始,以"--%>"結束
  • HTML/XHTML註釋。這些註釋不會被容器處理,會原樣發送到瀏覽器。

 

4、 隱式對象

Servlet 容器會傳遞幾個對象給它運行的 Servlet。例如,能夠經過 Servlet 的 service 方法獲取 HttpServletRequest 和 HttpServletResponse 對象。在 JSP 中,能夠經過隱式對象來訪問上述對象。
編碼

 

pageContext 提供了上下文信息,能夠用於獲取和設置屬性(getAttribute, setAttribute)。屬性值可被存儲在4個範圍之一:頁面(JSP),請求(ServletRequest),會話(HttpSession),應用程序(ServletContext)。

public void setAttribute(String name, Object value); // page scope
public Object getAttribute(String name);        // page scope
public void setAttribute(String name, Object value, int scope);
public Object getAttribute(String name, int scope);

 

 

out 引用了一個 javax.servlet.jsp.JspWriter 對象,這相似於你在調用 HttpServletResponse 的 getWriter 方法時獲得 java.io.PrintWriter。能夠經過調用它的 print 方法將消息發送到瀏覽器。

 

5、 指令

指令指示 JSP 轉換器如何把 JSP 頁面轉換爲 Servlet。

page

<%@ page attribute1="value1" attribute2="value2" ... %>

attributes :

  • import:定義本頁面中被導入的 java 類型。類型間可用','分隔。
  • session:值爲 True,本頁面加入會話管理;值爲 False 則相反。默認值爲True,訪問該頁面時,若當前不存在javax.servlet.http.HttpSession實例,則會建立一個。
  • buffer:以 kB 爲單位,定義隱式對象 out 的緩衝大小。必須以 kB 後綴結尾。默認大小爲8kB或更大(取決於JSP容器)。該值能夠爲 none,這意味着沒有緩衝,全部數據將直接寫入PrintWriter。
  • autoFlush:默認值爲 True。若值爲True,則當輸出緩衝滿時會自寫入輸出流。而值爲 False,則僅當調用隱式對象的flush方法時,纔會寫入輸出流。所以,若緩衝溢出,則會拋出異常。
  • isThreadSafe:定義該頁面的線程安全級別。不推薦使用。
  • info:指定生成的 Servlet 類的 getServletlnfo 方法的返回值。
  • errorPage:定義當出錯時用來處理錯誤的頁面。
  • isErrorPage:標識本頁是一個錯誤處理頁面。
  • contentType:定義本頁面隱式對象 response 的內容類型,默認是 "text/html"。
  • pageEncoding:定義本頁面的字符編碼,默認是"ISO-8859-1"。
  • isELIgnored:配置是否忽略 EL(Expression Language) 表達式。
  • language:定義本頁面的腳本語言類型,默認是 Java,這在JSP2.2中是惟一的合法值。
  • extends:定義JSP實現類要繼承的父類。較少使用,僅在很是特殊理由下使用。
  • deferredSyntaxAllowedAsLiteral:定義是否解析字符串中出現"#{"符號,默認是False。"{#"是一個表達式語言的起始符號,於是很重要。
  • trimDirectiveWhitespaces:定義是否不輸出多餘的空格/空行,默認是False。

大部分 page 指令能夠出如今頁面的任何位置,但當 contentType 或 pageEncoding 屬性時,必須出如今 Java 代碼發送任何內容以前。
page 指令也能夠出現屢次,但出現屢次的指令屬性必須具備相同的值,import 屬性除外,多個包含 import 屬性的 page 指令的結果是累加的。

 

include

include 指令將其餘文件中的內容包含到當前JSP頁面。

<%@ include file="url" %>

 

taglib

taglib 指令引入一個自定義標籤集合的定義,包括庫路徑、自定義標籤。

<%@ taglib uri="uri" prefix="prefixOfTag" %>

 

6、 腳本元素

腳本程序是 java 代碼塊,以"<%"符號開始,以"%>"符號結束。

Today is
<%
    out. print(Calendar.getInstance().getTime());
%>

 

表達式會被JSP容器執行,並使用隱式對象 out 的打印方法輸出結果。表達式以
"<%="開始,並由"%>"結束。表達式無需分號結尾。

Today is <%= Calendar.getInstance().getTime() %>

 

聲明以"<%!"開始,以"%>"結束,聲明頁面中使用的變量和方法。

<%!
    public String getTodaysDate() { return new Date().toString(); }
%>
<!DOCTYPE html>
<html>
<head><title>Declarations</title></head>
<body>
    Today is <%= getTodaysDate() %>
</body>
</html>


在 JSP 頁面中,一個聲明能夠出如今任何地方,而且一個頁面能夠有多個聲明。
可使用聲明來重寫 JSP 頁面,實現類的 init 和 destroy 方法。經過聲明 jsplnit 方法,來重寫 init 方法。經過聲明 jspDestroy 方法,來重寫 destory 方法。

 

注意:儘可能不要在 JSP 頁面中編寫 Java 代碼。除非應用程序只包含一個或兩個簡單的 JSP 頁面,而且永遠不會增加;不然,你應該採用模型2,它規定 JSP 頁面僅用於顯示 Java 對象中的值。

 

7、 動做

動做是第三種類型的語法元素,它們被轉換成 Java 代碼來執行操做,如訪問一個 Java 對象或調用方法。

 

useBean

useBean將建立一個關聯 Java 對象的腳本變量。這是早期分離表示層和業務邏輯的努力之一。隨着其餘技術的發展,如自定義標籤和表達語言,如今不多使用useBean方式。

 

setProperty 和 getProperty

setProperty 動做可對一個 Java 對象設置屬性,而 getProperty 則會輸出 Java 對象的一個屬性。

 

include

include 動做用來動態地引入另外一個資源。能夠引入另外一個 JSP 頁面,也能夠引入一個 Servlet 或一個靜態的 HTML 頁面。

<! DOCTYPE html>
<html><head>
<title>Include action</title>
</head>
<body>
<jsp:include page="menu.jsp">
    <jsp:param name="text" value="How are you?"/>
</jsp:include>
</body></html>


對於 include 指令,資源引入發生在頁面轉換時,即當 JSP 容器把頁面轉換爲生成的 Servlet 時。而 include 動做,資源引入發生在請求頁面時。所以,使用 include 動做是能夠傳遞參數的,而 include 指令不支持。

 

forward

forward 動做把當前頁面轉向到其餘資源。

<jsp:forward page="login.jsp">
<jsp:param name="text" value="Please login"/>
</jsp:forward>

 

param

用於傳遞參數。能夠經過 request.getParameter(String name) 取出參數值。

 

plugin

用於指定插件。

 

8、 錯誤處理

page 指令的 isErrorPage 屬性標誌一個 JSP 頁面是否爲錯誤頁面。
page 指令的 errorPage 屬性指向錯誤處理頁面。

<%-- errorHandler.jsp --%>
<%@ page isErrorPage="true" %>
<! DOCTYPE html><html>
<head><title>Error</title></head>
<body>
An error has occurred.<br/>
Error message:
<%
    out.print1n(exception. toString());
%>
</body></html>
<%@ page errorPage="errorHandler.jsp"%>
Deliberately throw an exception
<%
    Integer. parseInt("Throw me");
%>

 

 

參考資料:《Spring MVC 學習指南》 Paul Deck 著

相關文章
相關標籤/搜索