JSP知識總結
JSP的引入
Servlet的作用: 用java語言開發動態資源的技術!!! Jsp的作用:用java語言(+html語言)開發動態資源的技術!!! Jsp就是servlet!!! |
JSP的特點:
1)jsp的運行必須交給tomcat服務器!!!! tomcat的work目錄: tomcat服務器存放jsp運行時的臨時文件 2)jsp頁面既可以寫html代碼,也可以寫java代碼。 (html頁面不能寫java代碼 。而jsp頁面可以寫java代碼)
|
JSP初體驗
需求:顯示當前時間到瀏覽器上
可以把jsp頁面當做html頁面在tomcat中 |
01.hello.jsp 代碼:
<%@ page language="java" import="java.util.*,java.text.*,java.io.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>第一個jsp頁面</title> </head>
<body> <% //寫java代碼 //獲取當前時間 SimpleDateFormat sdf = new SimpleDateFormat(); String curDate = sdf.format(new Date()); //輸出內容到瀏覽器 //response.getWriter().write(""); out.write("當前時間為:"+curDate); %> </body> </html>
|
當前時間為:17-9-25 下午12:23 |
JSP的執行流程:
問題: 訪問http://localhost:8080/day12/01.hello.jsp 如何顯示效果?
1)訪問到01.hello.jsp頁面,tomcat掃描到jsp文件,在%tomcat%/work把jsp文件翻譯成java源文件 (01.hello.jsp -> _01_hello_jsp.java) (翻譯) 2)tomcat服務器把java源文件編譯成class字節碼文件 (編譯) (_01_hello_jsp.java -> _01_hello_jsp.class) 3)tomcat服務器構造_01_hello_jsp類對象 4)tomcat服務器調用_01_hello_jsp類裏面方法,返回內容顯示到瀏覽器。 第一次訪問jsp: 走(1)(2)(3)(4) 第n次訪問jsp: 走(4)
註意:1)jsp文件修改了或jsp的臨時文件被刪除了,要重新走翻譯(1)和編譯(2)的過程 |
JSP和Servlet的關系:
jsp翻譯的java文件: public final class _01_hello_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent {
HttpJspBase類: public abstract class org.apache.jasper.runtime.HttpJspBase extends javax.servlet.http.HttpServlet implements javax.servlet.jsp.HttpJspPage {
|
可以看到,繼承了HTTPServlet類
結論: Jsp就是一個servlet程序!!! servlet的技術可以用在jsp程序中 jsp的技術並不是全部適用於servlet程序! |
JSP和Servlet的生命周期對比:
Servlet的生命周期: 1)構造方法(第1次訪問) 2)init方法(第1次訪問) 3)service方法 4)destroy方法 Jsp的生命周期 1)翻譯: jsp->java文件 2)編譯: java文件->class文件(servlet程序) 3)構造方法(第1次訪問) 4)init方法(第1次訪問):_jspInit() 5)service方法:_jspService() 6)destroy方法:_jspDestroy() |
JSP表達式
語法:<%=變量或表達式%> 作用: 向瀏覽器輸出變量的值或表達式計算的結果 註意: 1)表達式的原理就是翻譯成out.print(“變量” );通過該方法向瀏覽器寫出內容 2)表達式後面不需要帶分號結束。 |
JSP腳本
語法:<%java代碼 %> 作用: 執行java代碼 (定義的變量是局部的變量) 註意: 1)原理把腳本中java代碼原封不動拷貝到_jspService方法中執行。 2)腳本中是不可以定義方法的,原因是腳本的代碼會被拷貝帶_jspService 方法中,方法中 是不能在定義方法 |
JSP生命
語法:<%! 變量或方法 %> 作用: 聲明jsp的變量或方法(定義的變量是全局的變量和方法) 註意: 1)變量翻譯成成員變量,方法翻譯成成員方法。 |
例子:
<!-- jsp腳本 --> <% //變量 String name = "eric"; int a = 10; int b =20; %>
<!-- JSP聲明 --> <%! String name = "jarry"; %>
<%--JSP表達式: 同名時,局部變量會覆蓋全局變量,打印的是局部變量--%> <%=name %> |
打印輸出:eric |
JSP註釋
<!-- html註釋 --> <%-- jsp註釋 --%> |
html的註釋會被翻譯和執行。而jsp的註釋不能被翻譯和執行 |
JSP的三大指令
include指令
作用: 在當前頁面用於包含其他頁面 語法: <%@include file="common/header.jsp"%> 註意: 1)原理是把被包含的頁面(header.jsp)的內容翻譯到包含頁面(index.jsp)中,合並成翻譯成一個java源文件,再編譯運行!!,這種包含叫靜態包含(源碼包含) 2)如果使用靜態包含,被包含頁面中不需要出現全局的html標簽了!!!(如html、head、body) |
|
Head.jsp文件代碼:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 頭部頁面的內容wwwwwww <br/> |
Index.jsp文件代碼:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>網站首頁</title> </head>
<body> <%@include file="common/header.jsp"%> 首頁的內容xxxxxxx </body> </html>
|
Page指令:
作用: 告訴tomcat服務器如何翻譯jsp文件 <%@ page language="java" --告訴服務器使用什麽動態語言來翻譯jsp文件 import="java.util.*" --告訴服務器java文件使用什麽包導入包,多個包之間用逗號分割 pageEncoding="utf-8" --告訴服務器使用什麽編碼翻譯jsp文件(成java文件) contentType="text/html; charset=utf-8" 服務器發送瀏覽器的數據類型和內容編碼 註意:在開發工具中,以後只需要設置pageEncoding即可解決中文亂碼問題 buffer="8kb" session="true" isELIgnored="false" |
異常錯誤相關的: errorPage: 指定當前jsp頁面的錯誤處理頁面。 isErorrPage: 指定當前頁面是否為錯誤處理頁面。false,不是錯誤處理頁面, 則 不能使用exception內置對象;true,是錯誤處理頁面,可以使用exception內置對象。
配置全局的錯誤處理頁面: |
<!-- 全局錯誤處理頁面配置 --> <error-page> <error-code>500</error-code> <location>/common/500.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/common/404.html</location> </error-page> |
session: 是否開啟session功能。 false,不能用session內置對象; true,可以使用session內置對象。 buffer: jsp頁面的緩存區大小。 isELIgnore: 是否忽略EL表達式。 |
JSP的內置對象:
內置對象的概念:
在jsp開發中,會頻繁使用到一些對象 。例如HttpSession,ServletContext,,HttpServletRequet。如果我們每次要使用這些對象都去創建這些對象就顯示非常麻煩。所以Sun公司設計Jsp時,在jsp頁面加載完畢之後就會自動幫開發者創建好這些對象,而開發者只需要直接使用這些對象調用方法即可!,這些創建好的對象就叫內置對象! |
舉例: servlet: HttpSession session = request.getSession(true); (需要開發者做)
jsp: tomcat服務器: HttpSession session = request.getSession(true);(不需要開發者做) 開發者做的: session.getId(); |
九大內置對象:
內置對象名 對應的類 request HttpServletRequest response HttpServletResponse config ServletConfig application ServletContext session HttpSession
exception Throwable out JspWriter page Object(this) pageContext PageContext |
Out對象:
out對象類型,JspWriter類,相當於帶緩存的PrintWriter PrintWriter: wrier(內容): 直接向瀏覽器寫出內容。 JspWriter writer(內容): 向jsp緩沖區寫出內容 當滿足以下條件之一,緩沖區內容寫出: 1)緩沖區滿了 2)刷新緩存區 3)關閉緩存區 4)執行完畢jsp頁面 |
PageContext對象:
pageContext對象的類型是PageContext,叫jsp的上下文對象
可以獲取其它八個內置對象
ServletRequest request2 = pageContext.getRequest(); ServletResponse response2 = pageContext.getResponse(); pageContext.getServletConfig(); pageContext.getServletContext(); pageContext.getSession(); pageContext.getException(); pageContext.getOut(); pageContext.getPage(); |
在自定義標簽的時候,PageContext對象頻繁使用到!!! |
四大域對象:
類 域範圍 ServletContext context域 HttpServletRequet request域 HttpSession session域 --Servlet學習的 PageContext page域 --jsp學習的 |
作用: 保存數據和獲取數據,用於共享數據 |
四個域對象: Jsp內置對象 域範圍 pageContext page域 request request域 session session域 application context域 |
#保存數據 1)默認情況下,保存到page域 pageContext.setAttribute("name"); 2)可以向四個域對象保存數據 pageContext.setAttribute("name",域範圍常量
#獲取數據 1)默認情況下,從page域獲取 pageContext.getAttribute("name") 2)可以從四個域中獲取數據 pageContext.getAttribute("name",域範圍常量)
域範圍常量: PageContext.PAGE_SCOPE PageContext.REQUEST_SCOPE PageContext..SESSION_SCOPE PageContext.APPLICATION_SCOPE 3)自動在四個域中搜索數據 pageContext.findAttribute("name"); 順序: page域 -> request域 -> session域- > context域(application域) |
3)域對象作用範圍: page域: 只能在當前jsp頁面中使用(當前頁面) request域: 只能在同一個請求中使用(轉發) session域: 只能在同一個會話(session對象)中使用(私有的) context域: 只能在同一個web應用中使用。(全局的) |
例子: |
<% pageContext.setAttribute("message","page‘s message"); pageContext.setAttribute("message","request‘s messsage",PageContext.REQUEST_SCOPE);//保存到request域中 pageContext.setAttribute("message","session‘s messsage",PageContext.SESSION_SCOPE);//保存到sessio域中 pageContext.setAttribute("message","application‘s messsage",PageContext.APPLICATION_SCOPE);//保到context域中 %> |
page域:<%=pageContext.getAttribute("message",PageContext.PAGE_SCOPE) %><br/> request域: <%=pageContext.getAttribute("message",PageContext.REQUEST_SCOPE) %><br/> session域: <%=pageContext.getAttribute("message",PageContext.SESSION_SCOPE) %><br/> context域:<%=pageContext.getAttribute("message",PageContext.APPLICATION_SCOPE) %><br/> |
打印的結果: |
page域:null request域: null session域: session‘s messsage context域:application‘s messsage |
findAttribute(): 在四個域自動搜索數據 順序: page域 -> request域 -> session域 -> context域 <%=pageContext.findAttribute("message") %> |
JSP+Servlet的模式
Servlet技術: 開發動態資源。是一個java類,最擅長寫java代碼 jsp技術: 開發動態資源。通過java代碼,最擅長輸出html代碼。 |
servlet+jsp模式
servlet: 優點 1)接收參數 2)處理業務邏輯 3)把結果保存到域對象中 4)跳轉到jsp頁面 Jsp:優點 1)從域對象取出數據 2)把數據顯示到瀏覽器
servlet的數據 -> jsp頁面 List<Contact> 使用域對象 共享數據 |
EL表達式
開發jsp的原則: 盡量在jsp頁面中少寫甚至不寫java代碼。
使用EL表達式替換掉jsp表達式
EL表達式作用: 向瀏覽器輸出域對象中的變量值或表達式計算的結果!!!
語法: ${變量或表達式}
|
輸出基本類型的變量
|
1.1 從四個域獲取 ${name} 1.2 指定域獲取 ${pageScope.name} 域範圍: pageScoep / requestScope / sessionScope / applicationScope |
例子: |
<body> <% String name = "rose"; //放入域中 pageContext.setAttribute("name",name); pageContext.setAttribute("name",name,PageContext.REQUEST_SCOPE); %> 1)從四個域自動搜索 : <br/> EL表達式: ${name } <br/> 等價於 <%=pageContext.findAttribute("name")%> <br/> 2)從指定的域中獲取數據 <br/> EL表達式: ${pageScope.name }; <br/> EL表達式: ${requestScope.name }; </body> |
打印結果: 1)從四個域自動搜索 : EL表達式: rose 等價於 rose 2)從指定的域中獲取數據 EL表達式: rose; EL表達式: rose; |
輸出對象的屬性值和輸出集合對象
Student類,有name和age屬性,這二個屬性的get方法和set方法,
JSP文件 代碼
<body> <%-- 1)EL輸出對象的屬性 --%> <% //保存數據 Student student = new Student("eric",20); //放入域中 pageContext.setAttribute("student",student);
//List List<Student> list = new ArrayList<Student>(); list.add(new Student("rose",18)); list.add(new Student("jack",28)); list.add(new Student("lucy",38)); //放入域中 pageContext.setAttribute("list",list);
//Map Map<String,Student> map = new HashMap<String,Student>(); map.put("100",new Student("mark",20)); map.put("101",new Student("maxwell",30)); map.put("102",new Student("narci",40)); //放入域中 pageContext.setAttribute("map",map);
%>
<%--使用EL獲取對象 --%> ${student.name} - ${student.age } <%-- ${student.name} 等價於 (點相對於調用getXX()方法) <%=((Student)pageContext.findAttribute("student")).getName()%> --%>
<hr/> <%--使用EL獲取List對象 --%> ${list[0].name } - ${list[0].age }<br/> ${list[1].name } - ${list[1].age }<br/> ${list[2].name } - ${list[2].age } <%-- list[0]等價於 (中括號相對於調用get(參數)方法) ((List)pageContext.findAttribute("list")).get(0) --%>
<hr/> <%--使用EL獲取Map對象 --%> ${map[‘100‘].name } - ${map[‘100‘].age }<br/> ${map[‘101‘].name } - ${map[‘101‘].age }<br/> ${map[‘102‘].name } - ${map[‘102‘].age }<br/> </body> |
打印結果 eric - 20 |
rose - 18 jack - 28 lucy - 38 |
mark - 20 maxwell - 30 narci - 40 |
EL表達式判斷對象非空
<body> <%-- 4)判空 null 或 空字符串: empty --%> <% Student student = null; String name = ""; pageContext.setAttribute("name",name); %> 判斷null: ${name==null }<br/> 判斷空字符: ${name=="" }<br/> 判空: ${name==null || name=="" } <br/> 另一種判空寫法: ${empty student } <br/> ${empty name }
</body> |
判斷null: false 判斷空字符: true 判空: true 另一種判空寫法: true true |
JSP標簽
jsp標簽作用:替換jsp腳本。
JSP標簽的分類:
1)內置標簽(動作標簽): 不需要在jsp頁面導入標簽 2)jstl標簽: 需要在jsp頁面中導入標簽 3)自定義標簽 : 開發者自行定義,需要在jsp頁面導入標簽 |
JSP動作標簽
轉發標簽: <jsp:forward /> 參數標簽: <jsp:pararm/> 包含標簽: <jsp:include/>(動作標簽) |
動作標簽的特點和靜態包含的對比:
原理: 包含與被包含的頁面先各自翻譯成java源文件,然後再運行時合並在一起。 (先翻譯再合並),動態包含 |
|
靜態包含 vs 動態包含的區別?
|
|
1) 語法不同 靜態包含語法: <%@inclue file="被包含的頁面"%> 動態包含語法: <jsp:include page="被包含的頁面">
2)參數傳遞不同 靜態包含不能向被包含頁面傳遞參數 動態包含可以向被包含頁面傳遞參數
3)原理不同 靜態包含: 先合並再翻譯 動態包含: 先翻譯再合並 |
|
例子: |
|
<jsp:include page="/common/header.jsp"> <jsp:param value="lucy" name="name"/> //動態包含 </jsp:include>
<%@include file="common/header.jsp" %> <br/> //靜態包含 主頁的內容 |
|
結果: 通用的頭部頁面的內容 參數: lucy 通用的頭部頁面的內容 參數: null 主頁的內容 |
|
JSP:forword標簽:Servlet轉發的另一種寫法 |
|
<body> <% request.setAttribute("AA", "aa"); %> <jsp:forward page="/09.action2.jsp"> <jsp:param value="jacky" name="name"/> //可以帶參數過去 <jsp:param value="123456" name="password"/> </jsp:forward>
</body> |
|
09.action。Jsp代碼: <body> <%=request.getParameter("name")%><br/> <%=request.getParameter("password")%> <br/> ${requestScope.AA } </body> |
Jacky 打印結果: 123456 aa |
JSTL標簽
JSTL (全名:java standard tag libarary - java標準標簽庫 ) |
分類
核心標簽庫 (c標簽庫) 天天用 國際化標簽(fmt標簽庫) EL函數庫(fn函數庫) xml標簽庫(x標簽庫) sql標簽庫(sql標簽庫)(幾乎不用) |
使用JSTL標簽的步驟
1) 導入jstl支持的jar包(標簽背後隱藏的java代碼) 註意:使用javaee5.0的項目自動導入jstl支持jar包 2)使用taglib指令導入標簽庫 <%@taglib uri="tld文件的uri名稱" prefix="簡寫" %> <%--導入標簽庫 --%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 3)在jsp中使用標簽 |
|
核心標簽庫的重點標簽: 保存數據: <c:set></c:set> 獲取數據: <c:out value=""></c:out> 單條件判斷 <c:if test=""></c:if> 多條件判斷 <c:choose></c:choose> <c:when test=""></c:when> <c:otherwise></c:otherwise> 循環數據 <c:forEach></c:forEach> <c:forTokens items="" delims=""></c:forTokens> 重定向 <c:redirect></c:redirect> |
例子:
<%--使用標簽 --%> <%--set標簽 :保存數據(保存到域中)默認保存到page域 --%> <c:set var="name" value="rose" scope="request"></c:set>
<% String msg = null; pageContext.setAttribute("msg",msg); %>
${msg } <br/> ${name } <br/>
<%--out標簽: 獲取數據(從域中) default: 當value值為null時,使用默認值 escapeXml: 是否對value值進行轉義,false,不轉義,true,轉義(默認) --%> <c:out value="${msg}" default="<h3>標題3</h3>" escapeXml="true"></c:out> |
打印的數據
rose <h3>標題3</h3> |
單條件判斷
|
<%--set標簽 :保存數據(保存到域中)默認保存到page域 --%> <c:set var="name" value="rose" scope="request"></c:set>
<% String msg = null; pageContext.setAttribute("msg",msg); %>
<%--if標簽 :單條件判斷--%> <c:if test="${empty msg}"> 條件成立 </c:if> 打印:條件成立 |
多重條件判斷 |
<%--choose標簽+when標簽+otherwirse標簽: 多條件判斷 --%> <c:set var="score" value="80"></c:set>
<c:choose> <c:when test="${score>=90 && score<=100}"> 優秀 </c:when> <c:when test="${score>=80 && score<90}"> 良好 </c:when> <c:when test="${score>=70 && score<80}"> 一般 </c:when> <c:when test="${score>=60 && score<70}"> 及格 </c:when> <c:otherwise> 不及格 </c:otherwise> </c:choose> |
<%-- forEach標簽:循環 --%> <% //List List<Student> list = new ArrayList<Student>(); list.add(new Student("rose",18)); list.add(new Student("jack",28)); list.add(new Student("lucy",38)); //放入域中 pageContext.setAttribute("list",list);
//Map Map<String,Student> map = new HashMap<String,Student>(); map.put("100",new Student("mark",20)); map.put("101",new Student("maxwell",30)); map.put("102",new Student("narci",40)); //放入域中 pageContext.setAttribute("map",map); %> <hr/> <%-- begin="" : 從哪個元素開始遍歷,從0開始.默認從0開始 end="": 到哪個元素結束。默認到最後一個元素 step="" : 步長 (每次加幾) ,默認1 items="": 需要遍歷的數據(集合) var="": 每個元素的名稱 varStatus="": 當前正在遍歷元素的狀態對象。(count屬性:當前位置,從1開始)
--%> <c:forEach items="${list}" var="student" varStatus="varSta"> 序號:${varSta.count} - 姓名:${student.name } - 年齡:${student.age}<br/> </c:forEach>
<hr/>
<c:forEach items="${map}" var="entry"> ${entry.key } - 姓名: ${entry.value.name } - 年齡:${entry.value.age }<br/> </c:forEach> <hr/> <%-- forToken標簽: 循環特殊字符串 --%> <% String str = "java-php-net-平面"; pageContext.setAttribute("str",str); %>
<c:forTokens items="${str}" delims="-" var="s"> ${s }<br/> </c:forTokens> |
序號:1 - 姓名:rose - 年齡:18 序號:2 - 姓名:jack - 年齡:28 序號:3 - 姓名:lucy - 年齡:38 --------------------------- 100 - 姓名: mark - 年齡:20 101 - 姓名: maxwell - 年齡:30 102 - 姓名: narci - 年齡:40 --------------------------- java php net 平面 |
<%--redrict:重定向 --%> |
<c:redirect url="http://www.baidu.com"></c:redirect> |
JSP知識總結