一、jsp概述
JSP全稱是Java Server Pages,它和servle技術一樣,都是SUN公司定義的一種用於開發動態web資源的技術。
JSP實際上就是Servlet。
JSP這門技術的最大的特點在於:寫jsp就像在寫html,但它相比html而言,html只能爲用戶提供靜態數據,而Jsp技術允許在頁面中嵌套java代碼,爲用戶提供動態數據。
jsp = html + java
html:靜態內容。
servlet:服務器端的小應用程序。適合編寫java邏輯代碼,如果編寫網頁內容-->太苦逼。
jsp:適合編寫輸出動態內容,但不適合編寫java邏輯。
Servlet負責那些事情?
1. 獲取表單數據
2. 處理業務邏輯
3. 分發轉向
提問:爲什麼JSP技術也是一種動態web資源的開發技術?
答:因爲JSP技術允許在頁面中嵌套java代碼,以產生動態數據,並且web服務器在執行jsp時,web服務器會傳遞web開發相關的對象給jsp,
jsp通過這些對象,可以與瀏覽器進行交互,所以jsp當然也是一種動態web資源開發技術。
強調一個概念:
對現在的用戶而言,認爲通過瀏覽器看到的東西都是網頁。
但我們程序員心裏要清楚,開一個瀏覽器訪問網頁,這些網頁有可能是一個html頁面(即靜態web資源),也有可能是一個動態web資源(即用servlet或jsp程序輸出的)。
二、jsp的原理
1. IE瀏覽器在訪問JSP頁面時,Web服務器是如何調用並執行一個jsp頁面的?(Servlet)
答:第一次:轉譯(翻譯) --> 編譯 --> 執行
第二次:執行
2. Web服務器在執行jsp頁面時,是如何把Jsp頁面中的html排版標籤發送到客戶端的?
答:out.print("<......>"); 或者 out.write("<......>");
3. Jsp頁面中的java代碼服務器是如何執行的?
答:服務器 --> .java文件 --> .class文件 --> 結果out回客戶端
4. Web服務器在調用jsp時,會給jsp提供一些什麼java對象(內置對象)?
答:HttpSession、ServletConfig、ServletContent、request、response、out等等。
三、jsp的最佳實踐
Servlet:控制器。重點編寫java代碼邏輯。(獲取表單數據、處理業務邏輯、分發轉向)
JSP:代碼顯示模板。重點在於顯示數據。(爲什麼顯示數據不直接用.html文件呢?因爲.jsp文件中可以插入java代碼顯示回顯消息,簡言之,jsp功能更強大)
示例:
lojin.jsp
doLogin.jsp(該jsp文件,先轉譯成java文件,注意:該jsp文件說白了其實就是純的java代碼,那麼就最好不使用jsp文件了。)
success.jsp
但是用戶關心的是隻有顯示給他們的頁面,你怎麼實現的,跟我(用戶)沒有關係。所以doLogin.jsp的代碼可以放到src中。
四、jsp的基本語法
1、JSP的模版元素:簡言之就是網頁的靜態內容
例如:html標籤和普通文本。
2、JSP的腳本
2.1、小腳本
<% java代碼 %>
2.1、表達式
<%= 2 + 3 %> 等價於out.print(2 + 3);
2.3、聲明
<%! %> 表示在類中定義全局成員和靜態塊。
3、JSP註釋
JSP註釋:<%-- 被註釋的內容 --%> 特點:安全,省流量
網頁註釋:<!-- 網頁註釋 --> 特點:不安全,費流量
4、JSP的3個指令
5、JSP的6個動作
6、JSP的9個內置對象
五、jsp的3個指令
JSP指令(directive)是爲JSP引擎而設計的,它們並不直接產生任何可見輸出,而只是告訴引擎如何處理JSP頁面中的其餘部分。
在JSP 2.0規範中共定義了三個指令:
page指令(頁面級別)
include指令(導入其它頁面的信息)
taglib指令(標籤指令)
例如:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; UTF-8"%>
語法:
<%@ 指令名稱 屬性1="屬性值1" 屬性2="屬性值2 ...... %>
或者:
<%@ 指令名稱 屬性1="屬性值1" %>
<%@ 指令名稱 屬性2="屬性值2" %>
示例:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
或者:
<%@ page language="java" %>
<%@ page import="java.util.*" %>
1、page
作用:page指令用於定義JSP頁面的各種屬性,無論page指令出現在JSP頁面中的什麼地方,它作用的都是整個JSP頁面。
爲了保持程序的可讀性和遵循良好的編程習慣,page指令最好是放在整個JSP頁面的起始位置。
屬性:
1.1、import和java代碼中的import是一樣的。
<%@ page import="java.util.Date, java.util.List" %>
或者:
<%@ page import="java.util.Date" %>
<%@ page import="java.util.List" %>
JSP會自動導入(默認導入)以下的包:
import java.lang.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
1.2、session: 表示是否會自動創建session對象。其默認值是true。
1.3、buffer: JSP中有javax.servlet.jsp.JspWriter輸出字符流。設置輸出數據的緩存大小,默認大小是8kb。建議最好不要改大小。
1.4、errorPage: 如果頁面中有錯誤,則跳轉到指定的資源。(即不讓頁面彈出404/500等錯誤)
errorPage="/uri"
如果寫"/"則代表當前應用的目錄下,絕對路徑。
如果不寫"/"則代表相對路徑。
1.5、isErrorPage: 表示是否創建throwable對象。其默認值是false。作用:輸出頁面錯誤信息:by zero
1.6、contextType: contentType="text/html; charset=UTF-8" 告訴瀏覽器使用什麼編碼來解析文本。等同於 response.setContextType("text/html; charset=utf-8");
1.7、pageEncoding: 告訴JSP引擎(服務器)要轉譯(翻譯)的文件使用的編碼。
例如:<%@ page pageEncoding="gbk" %>
1.8、isELIgnored: 是否支持EL表達式。 默認是false,表示支持EL表達式。
例如:${1+1} 等價於out.print(1+1);
pageEncoding說明圖:
2、include
include指令用於引入其它JSP頁面,如果使用include指令引入了其它JSP頁面,那麼JSP引擎將把這兩個JSP翻譯成一個servlet。所以include指令引入通常也稱之爲靜態引入。
靜態包含:把其它資源包含到當前頁面中。
<%@ include file="/include/header.jsp" %>
動態包含:
<jsp:include page="/include/header.jsp"></jsp:include>
兩者的區別:轉譯(翻譯)的時間段不同
前者:在翻譯時就把兩個文件合併
後者:不會合並文件,當代碼執行到include時,才包含另一個文件的內容。
使用原則:能用靜的就不用動的。原因之一是:可以省略一些代碼的書寫。
3、taglib
作用:在JSP頁面中導入JSTL標籤庫。替換jsp中的java代碼片段。
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> prefix:前綴(相當於重新給uri起個名字)
示例:
<%
if (5 > 3) {
out.print(5);
}
%>
<%-- 上下二種方式是等價的 --%>
<c:if test="${5>3}">
aaa
</c:if>
下面的這種方式很好用!後面慢慢體會。
六、jsp的6個動作
使用標籤的形式來表示一段java代碼。
如:
<jsp:include page="2.jsp"></jsp:include>
<jsp:include > 動態包含
<jsp:forward> 請求轉發
<jsp:param> 設置請求轉發的參數
<jsp:useBean> 創建一個對象
<jsp:setProperty> 給指定的對象屬性賦值
<jsp:getProperty> 取出指定對象的屬性值
示例:
七、jsp的9個內置對象
指在JSP的<%=%> 和<% %>中可以直接使用的對象,服務器給我們創建好的對象,直接拿過來用就行了。
例如:
<%=request.getParameter("name") %>
<%
Student stu = new Student();
stu.setName("tom");
out.print(stu.getName());
// request.getRequestDispatcher("/7.jsp").forward(request, response);
%>
pageContext(重要):做自定義標籤的時候會用到它,該域對象用的比較少,因爲該域對象只在當前頁面有效。
1、本身也是一個域對象:它可以操作其它三個域對象(request、session、application)的數據
void setAttribute(String name, Object value);
Object getAttribute(String name);
void removeAttribute(String name);
操作其它域對象的方法
void setAttribute(String name, Object value, int scope);
Object getAttribute(String name, int scope);
void removeAttribute(String name, int scope);
scpoe(域)的值:
PageContext.PAGE_SCOPE
PageContext.REQUEST_SCOPE
PageContext.SESSION_SCOPE
PageContext.APPLICATION_SCOPE
findAttribute(String name); // 自動從page、request、session、application依次查找,找到了就取值,然後結束查找。(很牛的方法,要記住)
2、它可以創建其它的8個隱式對象
在普通類中可以通過PageContext獲取其他JSP隱式對象。自定義標籤時使用。
3、提供了轉發和包含的簡易方法
pageContext.forward("2.jsp"); // 請求轉發
pageContext.include("2.jsp"); // 包含
八、四大域對象:實際開發如何用?
PageContext:pageConext 存放的數據僅在當前頁面有效。開發時使用較少。當前頁面存放數據用表單標籤中的 <input type="hidden" />,且該存值方式用戶看不到。
ServletRequest: request 存放的數據在一次請求(轉發:可以傳數據)內有效。使用非常多。
HttpSession: session 存放的數據在一次會話(多次請求)中有效。使用的比較多。例如:存放用戶的登錄信息、購物車功能。
ServletContext: application 存放的數據在整個應用範圍內都有效。因爲範圍太大,應儘量少用。用於統計在線人數。
九、EL表達式
1、EL的概述和基本語法
EL表達式:expression language 表達式語言
作用:要簡化jsp中java代碼開發。
特點:具有很強的容錯機制。
它不是一種開發語言,而是jsp中獲取數據的一種規範。或者說,它把java底層代碼進行了封裝。
2、EL的具體功能
a、獲取數據
EL表達式只能獲取存在4個作用域中的數據。
${ s } 原理: ${ s } 等價於 pageContext.findAttribute("s");
注意1:${ s }取不到表單數據,若想取到表單數據,需要 ${ param.s } 這樣纔可以取到。
注意2:url?name=tom&pwd=123 這種方式就是get提交的表單方式,所以需要 ${ param.name } 才能取到值。
EL獲取對於null這樣的數據,在頁面中表現爲空字符串(""),不會報錯,說明EL具有很強的容錯機制。
${ s.name } 等價於 s.getName()方法
點(.) 運算符相當於調用了getter方法,點後頁面跟的是屬性名。
屬性導航:非常好用。以後學習框架Hibernate的時候,一個對象中包含其它對象。
[]運算符:點能做的,它也能做; 它能做的,點不一定能做。
${ s.name } == ${ s['name'] } == ${ s["name"] }
b、運算
empty
判斷null、空字符串、沒有元素的集合(即使集合對象本身不爲null)都返回true。
三元運算符
c、隱式對象:11個
十、JSTL
1、什麼是JSTL
JSTL(JavaServerPages Standard Tag Library)JSP標準標籤庫。
作用是:簡化java代碼。
EL表達式${...} 只能處理簡單java代碼,複雜的邏輯java代碼就不行了!此時就用JSTL。
2、JSTL的作用
使用JSTL實現JSP頁面中邏輯處理。如判斷、循環等。
注意:在JSTL中想取值,必須加${值}。
3、使用JSTL
1)在JSP頁面中添加taglib指令(prefix:前綴(相當於重新給uri起個名字))
2)使用JSTL標籤
4、常用標籤介紹
核心標籤庫:
> 通用標籤:set、 out、 remove(瞭解就行,開發時根本不用個!)
> 條件標籤:if choose
> 迭帶標籤:forEach
普通for循環
迭帶器
注意:
<tr></tr> 代表行
<td></td> 代表單元格
<th></th> 相當於<td>,只是內置樣式加粗居中
或者使用css選擇器中的類選擇器的方式改變樣式,如下:
c:forEach中的varStatus屬性。
該屬性指向一個字符串,該字符串引用一個對象。map.put("vs", 一個對象);
這個對象記錄着當前遍歷的元素的一些信息:
getIndex() 返回索引,從0開始。
getCount() 返回計數,從1開始。
isFirst() 是否是第一個元素。
isLast() 是否是最後一個元素。