一、JSP基礎語法
1.理解
JSP:Java Server Page SUN 公司提供的動態網頁編程技術,是 Java Web 服務器端的動態資源。
Jsp 就是一個 Servlet,當我們第一次訪問 Jsp 的時候,Jsp 引擎都會將這個Jsp 翻譯 成一個 Servlet,這個文件存放在 Tomcat 中的 work 目錄中。
相比 html 而言,html 只能爲用戶提供靜態數據,而 Jsp 技術允許在頁面中嵌套 java 代碼,爲用戶提供動態數據。
2.準備工作
1、修改JSP頁面的編碼
選擇"Window",選擇"Preferfences",搜索"JSP",選擇"JSP Files",設置編碼爲UTF-8(默認是ISO-8859-1)
2、修改模板
將模板中html4修改html5
3.註釋
兩類三種
第一類:隱式註釋
在瀏覽器中看不見的註釋
1.Jsp自己的註釋 <%–JSP註釋–%>
<%–JSP註釋 --%>
2.繼承java風格的註釋
//單行註釋
/多行註釋/
第二類:顯示註釋
在瀏覽中審查元素或者查看源代碼可以看到的註釋
繼承HTML風格的註釋 <!–html註釋–>
<!-- JSP頁面中寫Java代碼 --> <% /* Java代碼 */ // 定義變量 String str = "Hello"; %>
4.Scriptlet
Scriptlet腳本小程序
所有嵌入在 HTML 代碼中的 Java 程序。
JSP一種有三種腳本小程序:
第一種:Java腳本段,可以定義局部變量、寫java語句等
生成的源碼在編譯後的Servlet類中的service方法體中
格式:<% //Java代碼 %>
<% %>
第二種:聲明,可以聲明全局變量、方法、類等
生成的源碼在編譯後的Servlet類體中
格式:<%! //聲明 %>
<%! %>
第三種:輸出,可以輸出變量或字面量
格式:<%=變量或字面量 %>
<%=1 %><!-- 第一種:Java腳本段,可以定義局部變量、寫java語句等 --> <% // 定義變量 int a = 1; // 定義集合 List<String> list = new ArrayList<>(); list.add("Hello"); // 輸出 System.out.println(list.get(0)); // 輸出 System.out.println(num); // 輸出到瀏覽器 out.print(num); List<String> list2 = null; %> <% if (1 > 0) { %> <h2>哈哈哈哈哈</h2> <% } %> <!-- 第二種:聲明,可以聲明全局變量、方法、類等 --> <%! // 聲明全局變量 int num = 100; // 定義方法 // 定義類 %> <br> <!-- 第三種:輸出,可以輸出變量或字面量 --> <%=a %> <br> <!-- jsp註釋的內容不會被編譯 --> <%-- <%=list2.get(0) %> --%> </body> </html>
二、JSP的指令標籤
1.page指令
格式:
<%@ page 屬性名=“屬性值” 屬性名=“屬性值”%>
常用屬性:(多個屬性之間用空格隔開)
language:語言,目前只有java
contentType:響應類型及編碼格式
pageEncoding:頁面編碼格式
頁面的編碼以contentType中的charset的值爲準,若charset未設置,則以pageEncoding的屬性值爲準;
如果pageEncoding的屬性也未設置則使用默認編碼ISO-8859-1。
import:導包。只有該屬性可以在page指令中出現多次。
errorPage:當頁面報錯時,跳轉的頁面(與isErrorPage屬性結合使用)
isErrorPage:是處理報錯的頁面,默認是false (與errorPage屬性結合使用)<%@page import="java.util.*" import="java.io.*" %> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*" errorPage="error.jsp"%>
2.taglib標籤
當使用到第三方標籤庫時需要通過 taglib 標籤進行導入。
<%@taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>
3.include靜態包含
格式:
<%@ include file=“要包含的文件路徑” %> 相對路徑特點:
相當於將內容直接複製
只會生成一個源碼文件,不能有同名變量。
運行效率快一點點,耦合度高,不夠靈活。<!-- 靜態包含 --> <%@include file="header.jsp" %> <div style="background-color: green;height: 200px"> <h2>我是主體!</h2> <%-- <% int a =1; %> --%> </div> <!-- 靜態包含 --> <%@include file="footer.jsp" %>
4.include動態包含
格式:
<jsp:include page=“要包含的頁面”></jsp:include>
有參數:
<jsp:include page=“要包含的頁面”>
<jsp:param value=“參數值” name=“參數名”/>
<jsp:param value=“參數值” name=“參數名”/>
</jsp:include>
value:參數值,可以接收表達式
name:參數名,字符串,不接受任何表達式
取值方式:request.getparameter(“參數名”);
特點:
相當於方法的調用
會生成多個源碼文件,可以有相同的變量名。
靈活,耦合度低。
動態包含和靜態包含的區別:
1、靜態包含相當於將內容進行直接的複製,動態包含相當於方法的調用。
2、靜態包含只會生成一個源碼文件,而動態包含會生成多個源碼文件。
3、靜態包含不能有同名變量,而動態包含可以有同名變量。
4、靜態包含不能傳遞參數,而動態包含可以。
5、靜態包含耦合度高,而動態包含耦合度低。注:
當使用動態包含沒有設置參數時,jsp:include雙標籤中不要有任何內容,包括空格和換行。<% String str = "admin"; %> <!-- 動態包含 --> <jsp:include page="header.jsp"></jsp:include> <!-- 動態包含並傳遞參數 --> <jsp:include page="header.jsp"> <jsp:param value="zhangsan" name="uname"/> <jsp:param value="<%=str %>" name="uname2"/> </jsp:include> <div style="background-color: green;height: 200px"> <h2>我是主體!</h2> <% int a =20; %> </div> <jsp:include page="footer.jsp"></jsp:include>
三、九大內置對象
1.內置對象
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-afgytqVQ-1582809367948)(C:\Users\Hello Word\AppData\Roaming\Typora\typora-user-images\1582804488275.png)]
九大內置對象
四大域對象:
pageContext 當前JSP頁面有效,跳轉頁面後無效
request 一次請求,請求轉發跳轉(服務端跳轉)有效,重定向跳轉(客戶端跳轉)無效
session 一次會話,無論是服務端跳轉還是客戶端,都有效;session對象銷燬後失效。
application 整個應用,只有服務器不關閉都不會失效public void setAttribute(String name, Object o) 設置屬性的名稱及內容 public Object getAttribute(String name) 根據屬性名稱取屬性 public void removeAttribute(String name) 刪除指定的屬性
兩個輸出對象
response 響應對象
out 輸出對象
一個配置對象
config 獲取配置信息
一個異常對象
exception 只有設置過isErrorPage="true"的頁面才能使用
一個頁面對象
page 指代jsp頁面本身
四、EL表達式
1.EL表達式
EL 表達式一般操作的都是域對象中的數據,操作不了局部變量。(通過限域變量名獲取域對象中的值。)
格式:
**{pageScope.限域變量名}
request作用域:{sessionScope.限域變量名}
application作用域:${applicationScope.限域變量名}
默認取值方式:
EL表達式在取值時,會自動從小範圍到大範圍查找,找到即止;
從page->request->session->application,如果四個域範圍都未找到,則返回空字符串。<% // 設置域對象 pageContext.setAttribute("uname", "zhangsan"); request.setAttribute("uname", "lisi"); session.setAttribute("uname", "wangwu"); application.setAttribute("uname", "zhaoliu"); %> <h4>EL表達式 取值</h4> 獲取域對象的值:${uname } <br> request作用域:${requestScope.uname }<br> session作用域:${sessionScope.uname }<br> application作用域:${applicationScope.uname }<br>
2.EL表達式使用
EL表達式取值:
1、判斷域對象是否爲空
{!empty 限域變量名}
判斷域對象不爲空
a、字符串:
如果字符串是null或空字符串,返回true
b、JavaBean對象
如果JavaBean是null,返回true
c、List集合
如果集合爲null或集合的長度不大於0,返回true
d、Map
如果map對象爲null或map沒有內容,返回true 2、獲取JavaBean對象
a、獲取對象
{限域變量名.屬性名 } 或 {限域變量名.屬性名.屬性名}
注:JavaBean中屬性需要提供getter方法
3、獲取List集合
a、獲取集合對象
{限域變量名[下標] }
c、獲取集合的長度
{限域變量名.key} 或 ${限域變量名[“key”]}
EL表達式運算:
運算:
${限域變量名1 + 限域變量名2}
${限域變量名1 + 字面量}
比較:
等值比較:
a、 ==
${限域變量名1 == 限域變量名2} 或 ${限域變量名1 == 字面量}
b、eq
${限域變量名1 eq 限域變量名2} 或 ${限域變量名1 eq 字面量}
大小比較:
${限域變量名1 > 限域變量名2}
${限域變量名1 >= 限域變量名2}
{}裏面<% // 字符串 String str = "Hello"; String str2 = null; String str3 = ""; request.setAttribute("str", str); request.setAttribute("str2", str2); request.setAttribute("str3", str3); // JavaBean對象 User user = new User(); user.setUserId(1); user.setUserName("Lisa"); Dog dog = new Dog(); dog.setName("張二狗"); dog.setAge(1); user.setDog(dog); User user2 = null; User user3 = new User(); request.setAttribute("user", user); request.setAttribute("user2", user2); request.setAttribute("user3", user3); // List集合 List<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); List<User> userList = new ArrayList<>(); userList.add(user); List list2 = null; List list3 = new ArrayList<>(); request.setAttribute("list", list); request.setAttribute("list2", list2); request.setAttribute("list3", list3); request.setAttribute("userList", userList); // Map Map<String,Object> map = new HashMap<>(); map.put("uname","admin"); map.put("user",user); map.put("userList",userList); Map map2 = null; Map map3 = new HashMap<>(); request.setAttribute("map", map); request.setAttribute("map2", map2); request.setAttribute("map3", map3); %> <h4>判斷域對象是否爲空</h4> 字符串:${empty str } -- ${empty str2 } -- ${empty str3 }<br> JavaBean對象:${empty user } -- ${empty user2 } -- ${empty user3 }<br> List集合:${empty list } -- ${empty list2 } -- ${empty list3 }<br> Map:${empty map } -- ${empty map2 } -- ${empty map3 }<br> <h4>獲取JavaBean</h4> 獲取對象:${user } <br> 獲取JavaBean的屬性:${user.userName } -- ${user.getUserName() } <br> 獲取對象中的對象的屬性:${user.dog.name } <h4>獲取List集合</h4> 獲取集合對象:${list }<br> 獲取集合中的元素:${list[0] }<br> 獲取集合的長度:${list.size() }<br> 獲取對象集合:${userList } -- ${userList[0] } -- ${userList[0].userName } <h4>獲取Map對象</h4> 過map的key獲取值:${map.uname } -- ${map["user"].userName } -- ${map.userList[0].userName } <% request.setAttribute("num", 10); request.setAttribute("num2", 2); request.setAttribute("s1", "aa"); request.setAttribute("s2", "bb"); %> <h4>EL表達式運算</h4> ${num+1 } -- ${num + num2 }<br> ${num/num2 } -- ${num div num2 }<br> ${num > 1 } -- ${num+num2 > 10 }<br> ${num == num2 } -- ${s1 == s2 } -- ${s1 == "aa" } -- ${s1 eq s2 }
五、JSTL標籤庫
1.標籤的使用
1、將jstl所需的兩個jar包拷貝到項目的WEB-INF的lib目錄下
2、在需要使用標籤庫的頁面引入對應庫<%--核心籤庫--%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> prefix表示該庫的前綴,可以是任意字符,但一般使用"c" <%--格式化標籤庫--%> <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
2.條件動作標籤
1)if標籤
無主體內容
<c:if test=“條件” var=“限域變量名” scope=“域範圍”></c:if>
有主體內容
<c:if test=“條件” var=“限域變量名” scope=“域範圍”>
內容
/c:if>
常用屬性:
test:if判斷的條件,一般結合el表達式操作域對象
**var:**條件判斷後的返回結果(true|false),存在一個域對象中
**scope:**域對象的範圍,默認是page。可以取值page|request|session|application 注:if標籤沒有else標籤,所以如果需要else的效果,需要寫一個完全相反的條件
<% // 後臺將數據存到request作用域中 request.setAttribute("score", 59); %> <c:if test="${score > 100 }" var="flag" scope="request"></c:if>${requestScope.flag } <br> <c:if test="${'1' == '1'}" var="flag2" ></c:if>${flag2 } <br> <c:if test="${'1==1'}" var="flag3" ></c:if>${flag3 } <br> <c:if test="1==1" var="flag4" ></c:if>${flag4 } <br> <%-- <c:if test="${1 == '1'}" var="flag5" ></c:if>${flag5 } <br> --%> <c:if test="${score == '59'}" var="flag6" ></c:if>${flag6 } <br> <hr> <c:if test="${score >1 }"> <h2>值大於1</h2> </c:if> <c:if test="${score <= 1 }"> <h2>值小於等於1</h2> </c:if> <!-- 使用JSTL的if標籤 --> <c:if test="${score < 60 }"> <h2>你個渣渣!</h2> </c:if> <c:if test="${score == 60 }"> <h2>分不在高,及格就行!</h2> </c:if> <!-- 頁面需要從作用域中將數據獲取 --> <% Integer score = (Integer)request.getAttribute("score"); // 判斷分數 if (score < 60) { %> <h2>你個渣渣!</h2> <% } else if (score == 60) { %> <h2>分不在高,及格就行!</h2> <% } %>
2)choose、when、otherwise標籤
choose 和 when 標籤的作用與 Java 中的 switch 和 case 關鍵字相似。
注意點:
1、choose、otherwise標籤沒有屬性,但是when標籤必須要有test屬性
2、choose標籤中只能嵌套otherwise和when標籤,otherwise和when標籤中可以嵌套其他標籤 Illegal “c:if” after “c:otherwise” tag in “c:choose” tag.
3、choose標籤中至少有一個when標籤,可以沒有otherwise標籤
Illegal “choose” without child “when” tag
4、otherwise標籤必須放在最後一個when標籤之後
Illegal “c:when” after “c:otherwise” tag in “c:choose” tag.
5、otherwise標籤會在所有的when標籤不執行時,執行<% // 後臺將數據存到request作用域中 request.setAttribute("score", 60); %> <c:choose> <c:when test="${score < 60 }"> <h2>你個渣渣!</h2> </c:when> <c:when test="${score >= 60 && score < 80 }"> <h2>哎喲不錯哦!</h2> </c:when> <c:otherwise> <h2>你很棒棒哦!</h2> </c:otherwise> </c:choose>
3)forEach標籤
forEach標籤
迭代內容多次
<c:forEach begin=“開始數” end=“結束數” var=“限域變量名” step=“間隔數” ></c:forEach>
循環
<c:forEach items=“要遍歷的對象(集合、map等)” var=“限域變量名” varStatus=“當前成員的相關信息”></c:forEach><% request.setAttribute("start", 0); request.setAttribute("end", 10); %> <!--迭代主體內容多次 --> <c:forEach var="i" begin="${start }" end="${end }" step="2"> <h4>${i }</h4> </c:forEach> <hr> <% List list = new ArrayList(); for (int i = 0; i < 10; i++) { list.add("A:" + i); } pageContext.setAttribute("li", list); %> <!-- 遍歷集合 --> <c:forEach items="${li }" var="item"> ${item } <br> </c:forEach> <%---varStatus--%> <h2>forEach</h2> <table> <tr> <td>List內容</td> <td>當前下標</td> <td>成員總數</td> <td>是/否first成員</td> <td>是/否爲last成員</td> </tr> <c:forEach items="${li}" var="item" begin="0" end="9" varStatus="idx"> <tr> <td><b>${item}</b></td> <td>${idx.index}</td> <td>${idx.count }</td> <td>${idx.first }</td> <td>${idx.last}<br /></td> </tr> </c:forEach> </table> <% // Map Map<String,Object> map = new HashMap<>(); map.put("uname","admin"); map.put("user",user); map.put("userList",userList); request.setAttribute("map", map); %> <!-- 迭代map --> <c:forEach items="${map }" var="item"> ${item.key } -- ${item.value } <br> </c:forEach> <%--九九乘法表--%> <table border="1" style="border-collapse: collapse;"> <c:forEach begin="1" end="9" var="i"> <tr> <c:forEach begin="1" end="${i }" var="j"> <td>${j } * ${i } = ${i*j }</td> </c:forEach> </tr> </c:forEach> </table>
3.迭代標籤
forEach標籤
迭代內容多次
<c:forEach begin="開始數" end="結束數" var="限域變量名" step="間隔數" ></c:forEach>
循環
<c:forEach items=“要遍歷的對象(集合、map等)” var=“限域變量名” varStatus=“當前成員的相關信息”></c:forEach><% request.setAttribute("start", 0); request.setAttribute("end", 10); %> <!--迭代主體內容多次 --> <c:forEach var="i" begin="${start }" end="${end }" step="2"> <h4>${i }</h4> </c:forEach> <hr> <% List list = new ArrayList(); for (int i = 0; i < 10; i++) { list.add("A:" + i); } pageContext.setAttribute("li", list); %> <!-- 遍歷集合 --> <c:forEach items="${li }" var="item"> ${item } <br> </c:forEach> <%---varStatus--%> <h2>forEach</h2> <table> <tr> <td>List內容</td> <td>當前下標</td> <td>成員總數</td> <td>是/否first成員</td> <td>是/否爲last成員</td> </tr> <c:forEach items="${li}" var="item" begin="0" end="9" varStatus="idx"> <tr> <td><b>${item}</b></td> <td>${idx.index}</td> <td>${idx.count }</td> <td>${idx.first }</td> <td>${idx.last}<br /></td> </tr> </c:forEach> </table> <% // Map Map<String,Object> map = new HashMap<>(); map.put("uname","admin"); map.put("user",user); map.put("userList",userList); request.setAttribute("map", map); %> <!-- 迭代map --> <c:forEach items="${map }" var="item"> ${item.key } -- ${item.value } <br> </c:forEach> <%--九九乘法表--%> <table border="1" style="border-collapse: collapse;"> <c:forEach begin="1" end="9" var="i"> <tr> <c:forEach begin="1" end="${i }" var="j"> <td>${j } * ${i } = ${i*j }</td> </c:forEach> </tr> </c:forEach> </table>
4.格式化動作標籤
1)formatNumber
將數值型的數據轉換成指定格式的數值字符串
有主體內容
<fmt:formatNumber type=“類型” var=“限域變量名” >
要格式化的數據(接收表達式)
</fmt:formatNumber
無主體內容
<fmt:formatNumber type=“percent” value=“要格式化的數據(接收表達式)” />
常用屬性:
type:格式化後的格式
percent 百分比類型
number 數值型
currency 貨幣型
var:限域變量名
用來接收格式化後的結果。如果設置了var屬性,格式化後的結果不會輸出,需要通過el表達式獲取var屬性的值2)formatDate
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-TYjDvpcU-1582809367951)(C:\Users\Hello Word\AppData\Roaming\Typora\typora-user-images\1582806649877.png)]
將日期型的數據轉換成指定格式的字符串
var:限域變量名
用來接收格式化後的結果。如果設置了var屬性,格式化後的結果不會輸出,需要通過el表達式獲取var屬性的值
type:日期類型
date 日期型,默認
time 時間型
both 日期+時間
dateStyle:日期型的格式
timeStyle:時間型的格式
pattern:具體的時間格式
y 年
M 月
d 日
H 時(0-24)
h 時(0-12)
m 分
s 秒3)parseNumber
將指定格式的數值字符串轉換成數值型數據4)parseDate
將指定格式的字符串轉換成日期型的數據<% request.setAttribute("num", 1); %> <h4>formatNumber</h4> <fmt:formatNumber type="percent" >10</fmt:formatNumber> <br> <fmt:formatNumber type="percent" var="num1" >10</fmt:formatNumber> ${num1 }<br> <fmt:formatNumber type="percent" var="num2" >${num }</fmt:formatNumber> ${num2 }<br> <fmt:formatNumber type="percent" value="${num }" /><br> <fmt:formatNumber type="currency" value="${num }" /><br> <fmt:formatNumber type="number" value="${num }" /><br> <!--設置地區 --> <fmt:setLocale value="en_US"/> <fmt:formatNumber type="currency" value="${num }" /><br> <hr> <% request.setAttribute("myDate", new Date()); %> <h4>formatDate</h4> ${myDate }<br> <fmt:formatDate value="${myDate }"/><br> <fmt:formatDate value="${myDate }" type="date"/><br> <fmt:formatDate value="${myDate }" type="time"/><br> <fmt:formatDate value="${myDate }" type="both"/><br> <fmt:formatDate value="${myDate }" dateStyle="short"/><br> <fmt:formatDate value="${myDate }" type="both" dateStyle="short" timeStyle="short"/><br> <fmt:formatDate value="${myDate }" pattern="yyyy-MM-dd HH:mm:ss"/><br> <fmt:formatDate value="${myDate }" pattern="yyyy/MM/dd HH:mm:ss"/><br> <fmt:formatDate value="${myDate }" pattern="yyyy年MM月dd日 HH:mm:ss"/><br> <h4>parseNumer</h4> <fmt:parseNumber type="number">100</fmt:parseNumber> <br> <fmt:parseNumber type="percent">100%</fmt:parseNumber> <br> <% request.setAttribute("n", "$1.00"); %> <fmt:parseNumber value="${n }" type="currency" /><br> <h4>parseDate</h4> <fmt:parseDate pattern="yyyy-MM-dd">2017-03-04</fmt:parseDate>