1. JSP概述
Servlet是j2ee提供的動態資源開發技術,是以java的程序的形式進行開發,在java中書寫HTML標籤是一件十分頭疼的事情,所以人們開發出了JSP,看起來像是HTML一樣,但是通過服務器的編譯最終可以生成Servlet。JSP技術有點類似ASP技術,它是在傳統的網頁HTML(標準通用標記語言的子集)文件(.htm,.html)中插入Java程序段(Scriptlet)和JSP標記(tag),從而形成JSP文件,後綴名爲(*.jsp)。 用JSP開發的Web應用是跨平臺的,既能在Linux下運行,也能在其他操作系統上運行。
JSP的本質就是Servlet,每個JSP頁面就是一個Servlet實例,JSP頁面由系統編譯成Servlet,Servlet負責相應用戶請求。
當我們新建一個項目並佈置到tomcat服務器上運行時,我們可以在tomcat 目錄下的 \work\Catalina\localhost\ 下找到相應的jsp頁面編譯生成的servlet代碼。這些就是系統編譯生成的Servlet類。
2. JSP的組成部分
- 2.1模版元素
直接書寫在JSP中的HTML內容,看起來就像寫HTML一樣的方便,但是最終會在被翻譯成Servlet的過程中 out.write()直接輸出
- 2.2腳本表達式
<%= 表達式%> 接受的是一段java表達式,在JSP翻譯到Servlet的過程中,將會計算表達式的值,利用out.write()輸出出去
- 2.3腳本片段
<% %>直接可以在腳本片段中書寫java源代碼,其中的源代碼將會直接拷貝到翻譯過來的servlet中的響應位置上。
- 2.4JSP聲明
<%! %>在其中可以寫java代碼,其中的源代碼會被拷貝到servlet中的service方法之外,可以利用它來爲servlet增加成員方法、成員變量、靜態代碼塊
- 2.5JSP註釋
<%– –%>被jsp註釋包圍起來的內容將不會被服務器翻譯到servlet之中,要注意區分html註釋和java註釋的區別
jsp註釋不會被翻譯到servlet中,會在翻譯時遺棄
java註釋不會被編譯到class文件中,會在編譯時遺棄
html註釋將會當作模版元素,直接輸出到瀏覽器中,瀏覽器將不會顯示html註釋中的內容
- 2.6JSP指令
2.6.1 page指令
用來通知翻譯引擎,如果翻譯當前的JSP
[ language="java" ] 當前JSP使用的開發語言
[ extends="package.class" ] 當前jsp翻譯成servlet後要繼承的類,注意此值必須是一個servlet的子類,一般情況下不要改
[ import="{package.class | package.*}, ..." ] 導入需要使用到的包 java.lang.*;javax.servlet.*;javax.servlet.jsp.*;javax.servlet.http.*;
[ session="true | false" ] 用來指定當前頁面是否使用session,如果設置爲true,則翻譯過來的servlet中將會有對session對象的引用,於是可以直接在jsp中使用session隱式對象。但是這將導致一旦訪問jsp就會調用request.getSession()方法,可能導致不必要的空間浪費。如果確定jsp中不需要session可以設爲false
[ buffer="none | 8kb | sizekb" ] out隱式對象所使用的緩衝區的大小
[ autoFlush="true | false" ] out隱式對象是否自動刷新緩衝區,默認爲true,不需要更改
[ isThreadSafe="true | false" ] 翻譯過來的servlet是否實現SingleThreadModel
[ errorPage="relative_url" ] 如果頁面出錯,將要跳轉到的頁面,除了在jsp中使用此屬性指定錯誤頁面外也可以在web.xml中配置整個web應用的錯誤頁面,如果兩個都設置則jsp中的此屬性起作用
[ isErrorPage="true | false" ] 如果設置此屬性爲true,翻譯過來的servlet中將含有Exception隱式對象,其中封裝的就是上一個頁面中拋出的異常對象
[ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ] 和jsp亂碼相關的指令,用來指定jsp輸出時,設置的Content-Type響應頭用來指定瀏覽器打開的編碼
[ pageEncoding="characterSet | ISO-8859-1" ] 服務器翻譯jsp時使用的編碼集.如果向防止jsp亂碼,應該保證文件的保存編碼和jsp翻譯成servlet用的編碼以及輸出到瀏覽器後瀏覽器打開的編碼一致.此屬性一旦設置好,翻譯引擎會間接幫我們設置content-type屬性.
[ isELIgnored="true | false" ] 當前頁面是否使用el表達式,設置爲false時表示啓用el,j2ee4.0開始默認支持,j2ee4.0一下做開發時,如果要使用el表達式,需將此屬性設置爲fals
2.6.2include指令
<%@ incluede file=”“%> 靜態引入其他頁面的內容
*靜態引入:在源文件級別進行合併,多個jsp生成一個servlet,最終由這一個servlet生成響應。推薦使用。
*動態引入:在運行時將多個輸出進行合併,多個jsp分別生成多個servlet,最終由這多個servlet生成響應,組成一個輸出流,提供響應。執行效率沒有靜態引入高。
2.6.3taglib指令
<%@ taglib uri=”” prefix=”“%>用來引入標籤庫。
uri指定被引入.tld文件的名稱空間
prefix 對該名稱空間的一個縮寫
- 2.7九大隱式對象
config
application
request
response
session
out
page
pageContext
Exception
3. JSP標籤
JSP既可以用來生成HTML頁面,也可以直接書寫java源碼處理邏輯,這就導致了很多開發者在JSP出現初期,只用JSP做開發,這個JSP頁面十分龐大、充滿了java源碼和HTML標籤、許多百分號,邏輯結構混亂,不宜調試程序和頁面美化。於是人們希望將java源碼從JSP頁面中儘量抽離,但是把所有java源碼都抽走是不現實的,最基本的獲取屬性、簡單的頁面邏輯還是需要的,於是,sun公司就提供了JSP中的標籤開發技術,以一個標籤代表一種功能的java代碼,是整個jsp看起來更像一個HTML,並且不丟失JSP進行邏輯處理的功能。
- 3.1.JSP標籤
由sun公司提供,屬於jsp規範中的內容,不需要引入第三方標籤庫
<jsp:inclue>用來替代request.getRequestDispatcher().include()
<jsp:forward>用來替代request.getRequestDispatcher().forward()
<jsp:param>配合前兩個標籤使用,可以在包含或轉發時,帶一些參數過去
<jsp:useBean id="beanName" class="package.class" scope="page|request|session|application"/>在指定域中搜尋名字爲id設置值的bean,如果沒有就在該域中創建一個
<jsp:setProperty name="beanName"
{
property="propertyName" value="{string | <%= expression %>}" |
property="propertyName" [ param="parameterName" ] |
property= "*"
}/>
用於爲bean的屬性負值name指定bean的名字,property指定要設定的屬性的名字,value指定設定的屬性的值,param用來指定使用哪個請求參數設定該屬性,property可以設置爲*,用來將所有的請求參數自動設置懂啊bean對應的屬性上
<jsp:getProperty name="beanInstanceName" property="PropertyName" />用於獲取屬性的值輸出到輸出流中,其中name指定bean的名字,property指定bean上屬性的名字
- 3.2.el表達式
替代<%= %>腳本表達式,在j2ee1.4以前默認是不支持el,如果需要需要指定page指令[isELIgnored=”true | false” ]爲false,j2ee4.0後默認支持el
3.2.1獲得域中的屬性
${propName}在四個域中搜尋proName屬性,輸出該值到輸出流中
${pageScope/requestScope/sessionScope/applicationScope.proName}獲取指定域中的屬性
${list[0]}獲取list中的指定位置元素
${map.keyName}獲取map中指定鍵的值
3.2.2進行簡單運算
(1)算數運算:所有參與元算的元素都會被轉成數字,如果不能轉就報錯,空元素參與運算當作沒參與。
(2)關係運算:
(3)邏輯運算:
(4)empty/not empty判斷一個對象或集合或數組是否爲空或長度爲0
(5)二元表達式 name == null ? "張三" : name;
3.2.3獲取web開發常用對象
pageContext:代表pageContext對象,注意和pageScope進行區分
pageScope:代表page域,可以用來獲取page域中的屬性
reqeustScope:代表reqeust域,可以用來獲取reqeust域中的屬性
sessionScope:代表session域,可以用來獲取session域中的屬性
applicationScope:代表application域,可以用來獲取application域中的屬性
param 代表請求參數組成的map集合${param.userName}
paramValues 代表請求參宿組成的map集合,但是此集合的value是String[],用來獲取一名多值的param
header 獲取請求頭組成的map
headerValues 獲取請求頭組成的map但是value是一個String[],用來獲取一名多值的head
cookie 獲取cookie組成的map對象,此map的值是一個cookie對${cookie.cookieName.cookieValue}
initParam 以map封裝的web.xml中配置的整個web應用的初始化參數
4.EL函數
下面我們來自定義實現EL的URL編碼函數標籤
(1)編寫靜態方法,一定要是靜態方法
// 目錄: /web_test/src/com.chen/CodeTag.java
package com.chen;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.print.DocFlavor.URL;
public class CodeTag {
//實現對輸入參數的url編碼
public static String Encode(String name){
try {
return URLEncoder.encode(name, "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
(2)編寫tld文件
<!-- /WEB-INF/coder.tld -->
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>UrlCodeer</short-name>
<uri>http://www.chen.com</uri>
<function>
<!-- name 便籤的名字 -->
<name>encode</name>
<!--函數所在的類名 -->
<function-class>com.chen.CodeTag</function-class>
<!-- 方法的聲明,包括返回值和輸入參數的類型 -->
<function-signature>java.lang.String Encode(java.lang.String )</function-signature>
</function>
</taglib>
(3)在web.xml中實現uri配置
<jsp-config>
<taglib>
<taglib-uri>http://www.chen.com</taglib-uri>
<taglib-location>/WEB-INF/coder.tld</taglib-location>
</taglib>
</jsp-config>
(4)使用標籤
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!--引入標籤-->
<%@ taglib uri="http://www.chen.com" prefix="UrlCoder" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'MyJsp.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
${UrlCoder:encode("中文") }
</body>
</html>
輸出結果:
%E4%B8%AD%E6%96%87