javascript
03-JavaWeb之JSP
一、JSP介紹
我們學習了servlet來后,就可以接收客戶端的請求,并使用響應對象給瀏覽器返回結果。但是,使用response返回結果是件 “很可怕的事” 。例如:就為了返回一個網頁,我們需要進行復雜的拼接,很明顯這不是明智之舉。所以,我們需要jsp來完成。
response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.println("<!doctype html>"); writer.println("<html>"); writer.println("<head>"); writer.println("<title>測試</title>"); writer.println("<meta charset='utf-8'>"); writer.println("</head>"); writer.println("<body>"); writer.println("<h1>測試使用response對象響應網頁</h1>"); writer.println("</body>"); writer.println("</html>"); writer.close();- JSP(全稱JavaServer Pages)是由Sun公司主導創建的一種動態網頁技術標準。
- JSP將Java代碼和特定變動內容嵌入到靜態的頁面中,實現以靜態頁面為模板,動態生成其中的部分內容,從而實現數據的動態顯示。
- JSP文件后綴名為 *.jsp
二、第一個JSP
嘗試動態的返回當前時間給客戶端
<%@ page import="java.text.SimpleDateFormat" %> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head><title>第一個jsp</title> </head> <body><h1>當前系統時間為:</h1><%= new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(new Date()) %> </body> </html>解釋:
1.<%@ page ... ... %> 稱為JSP的page指令,可用于定義JSP頁面的各種屬性。
2.<%= java代碼 %> 稱為jsp表達式,用于將已經聲明的變量或者表達式結果輸出到網頁上面。
三、如何在JSP中編寫java代碼
在體驗了JSP的helloworld后,咱們來具體說說在jsp編寫java有哪些方式?
3.1 JSP注釋
<%-- 注釋內容 --%>3.2 JSP聲明
一個聲明語句可以聲明一個或多個變量、方法,供后面的Java代碼使用。在JSP文件中,您必須先聲明這些變量和方法然后才能使用它們。
JSP聲明的語法格式:
<%! 聲明變量或方法 %>案例:
<%! int i = 0; %> <%! int a, b, c; %>3.3 JSP腳本
JSP腳本可以包含Java代碼片段。語法如下:
<% Java代碼片段 %>案例1:使用聲明好的變量,并打印到頁面上。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head><title>測試JSP腳本</title> </head> <body><%!int a = 1;String str = "hello";%><%a++;int length = str.length();out.println("a:"+a+",length:"+length); //將a和length 輸出到頁面%> </body> </html>案例2:使用分支語句
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head><title>測試JSP腳本</title> </head> <body><%! int day = 3; %><%if (day == 6 | day == 7) {%><p> 今天是周末 </p><%} else {%><p> 今天需要工作 </p><% } %> </body> </html>可以發現,這樣的代碼可讀性就不好了,不便于后期的維護和擴展。咱們后續會給出解決方案。
3.4 JSP表達式
jsp表達式,用于將已經聲明的變量或者表達式結果輸出到網頁上面。語法如下:
<%= java代碼 %> 等價于 JSP腳本中編寫的:out.println( 內容 );四、JSP指令
4.1 指令語法
JSP指令用來設置整個JSP頁面相關的屬性,如網頁的編碼方式和腳本語言。
語法格式如下:
<%@ 指令名 屬性名1="屬性值" 屬性名2="屬性值" ... %>4.2 page指令
page指令一般書寫在jsp頁面的第一行,用于定義jsp頁面的相關屬性。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>屬性解釋: 1. language:定義JSP頁面所用的腳本語言,默認是Java 2. contentType:指定當前JSP頁面的MIME類型和字符編碼 3. pageEncoding:設置頁面編碼 4. import:導入要使用的Java類 5. errorPage:指定當JSP頁面發生異常時需要轉向的錯誤處理頁面 6. isErrorPage:指定當前頁面是否可以作為另一個JSP頁面的錯誤處理頁面 7. 等等4.3 include指令
JSP可以通過include指令來包含其他JSP文件,包含的文件就好像是該JSP文件的一部分,會被同時編譯執行。
在很多網頁中頭尾兩部分基本都是不變的,所以沒必要在每個頁面中單獨寫一遍,只需要編寫1份,在需要的頁面中使用include指令引入即可。
include指令的語法格式如下:
4.4 taglib指令
用于引入標簽庫,在JSTL章節具體講解。
<%@ taglib uri="標簽庫的uri路徑" prefix="自定義前綴" %>五、JSP的九大內置對象和四大作用域
5.1 九大內置(隱式)對象
JSP隱式對象是JSP容器為每個頁面提供的Java對象,開發者可以直接使用它們而不用顯式聲明。
1.request對象
request對象是javax.servlet.http.HttpServletRequest 類的實例。每當客戶端請求一個JSP頁面時,JSP引擎就會制造一個新的request對象來代表這個請求。
request對象提供了一系列方法來獲取HTTP頭信息,cookies,HTTP方法等等。
2.response對象
response對象是javax.servlet.http.HttpServletResponse類的實例。當服務器創建request對象時會同時創建用于響應這個客戶端的response對象。
response對象也定義了處理HTTP頭模塊的接口。通過這個對象,開發者們可以添加新的cookies,時間戳,HTTP狀態碼等等。
3.out對象
out對象是 javax.servlet.jsp.JspWriter 類的實例,用來在response對象中寫入內容。
4.session對象
session對象是 javax.servlet.http.HttpSession 類的實例。和Java Servlets中的session對象有一樣的行為。session對象用來跟蹤在各個客戶端請求間的會話。
5.application對象
application對象直接包裝了servlet的ServletContext類的對象,是javax.servlet.ServletContext 類的實例。
這個對象在JSP頁面的整個生命周期中都代表著這個JSP頁面。這個對象在JSP頁面初始化時被創建,隨著jspDestroy()方法的調用而被移除。
通過向application中添加屬性,則所有組成您web應用的JSP文件都能訪問到這些屬性。
6.config對象
config對象是 javax.servlet.ServletConfig 類的實例,直接包裝了servlet的ServletConfig類的對象。
這個對象允許開發者訪問Servlet或者JSP引擎的初始化參數,比如文件路徑等。
以下是config對象的使用方法,不是很重要,所以不常用:config.getServletName();
它返回包含在 <servlet-name> 元素中的servlet名字,注意,<servlet-name> 元素在 WEB-INF\web.xml 文件中定義。
7.pageContext 對象
pageContext對象是javax.servlet.jsp.PageContext 類的實例,用來代表整個JSP頁面。
這個對象主要用來訪問頁面信息,同時過濾掉大部分實現細節。
這個對象存儲了request對象和response對象的引用。application對象,config對象,session對象,out對象可以通過訪問這個對象的屬性來導出。
pageContext對象也包含了傳給JSP頁面的指令信息,包括緩存信息,ErrorPage URL,頁面scope等。
8.page 對象
這個對象就是頁面實例的引用。它可以被看做是整個JSP頁面的代表。
page 對象就是this對象的同義詞。
9.exception 對象
exception 對象包裝了從先前頁面中拋出的異常信息。它通常被用來產生對出錯條件的適當響應。
5.2 四大作用域
JSP的四大作用域:page、request、session、application。
page作用域:當前頁面有效,page作用域可以使用pageContext對象的setAttribute()和getAttribute()方法進行訪問。
request作用域:當前請求有效,可以通過調用request對象的setAttribute()和getAttribute()方法進行訪問。可在轉發時進行值的傳遞。
session作用域:當前會話內有效,只要將數據綁定到session作用域中,則該數據可以被本次會話中的其他頁面所訪問。可以通過session.setAttribute() 和session.getAttribute()方法進行訪問其作用域。
application作用域:整個web應用有效(全局有效),即從tomcat啟動到停止,被該應用下的所有用戶共享。通過application.setAttribute() 和application.getAttribute()方法進行訪問。
由此可以看出,作用域范圍依次是:application > session > request > page
六、JSP的運行原理
定論: JSP就是Servlet
首先我們要明白一點:JSP中是可以嵌入Java代碼的,那也就是說JSP內容 = HTML + Java,但是瀏覽器是無法執行Java代碼的,如果細心一點還會發現,當我們請求JSP時,瀏覽器端得到的頁面中僅僅包含HTML,而沒有Java代碼,那么,我們就可以大致斷定,tomcat給我們的不是JSP,而是把JSP處理后的瀏覽器能夠解析執行的標準HTML頁面。
真正的流程是:
1.當瀏覽器端發出 xxx.jsp請求時,會被org.apache.jasper.servlet.JspServlet映射到該請求,這一點,可以在tomcat的conf中的web.xml中看到,被JspServlet攔截后,會將對應的jsp翻譯為相應的servlet代碼,文件名命名規則是:jsp文件名_jsp.java,并將該java文件編譯為對應的class。相應的java和class文件都存儲在tomcat的work目錄中。
2.jsp被翻譯為servlet后,其內部有也會有一個service方法,方法名叫:_jspService,代碼如下:
七、EL表達式
7.1 介紹
- Expression Language表達式語言。語法規則:${key}
- 是一種在JSP頁面獲取數據的方式,在JSP2.0開始引入概念。
- EL表達式獲取數據(從四大域中獲取屬性)。
7.2 EL從四大作用域中獲取值
1.初體驗,嘗試從request中獲取值
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head><title>測試el表達式</title> </head> <body><%-- 1.向request作用域中存值 --%><%request.setAttribute("name", "tom");%><%-- 2.原本的獲取方式 --%><%out.println("<h1>name:"+request.getAttribute("name")+"</h1>");%><%-- 3.el的獲取方式 --%><h1>name:${name}</h1> </body> </html>2.取值順序測試,在四個作用域中都存了值,key也是一樣的,那么取出的值到底是哪個呢?
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head><title>測試el表達式取值順序</title> </head> <body><%pageContext.setAttribute("name", "tom1");request.setAttribute("name", "tom2");session.setAttribute("name", "tom3");application.setAttribute("name", "tom4");%><h1>name:${name}</h1> </body> </html>答案是:tom1 , 使用 EL 表達式 獲取數據順序為:從小到大,即:pageContext -> request -> session -> application)。pageContext作用域范圍最小,優先從他里邊取值。
那么如何從從指定作用域取值呢?比如從session中取值,寫法是:${sessionScope.name}
從指定作用域取值的語法是:${作用域名Scope.key}
7.3 EL從對象中取值
7.3.1 bean屬性
來看下面這個Emp類,它有id和name兩個對象屬性,并且都有相應的get和set方法,我們把get和set一般就稱之為bean屬性,其分為可讀屬性和可寫屬性,即:getId()為可讀屬性,setId()為可寫屬性。
讀:調用bean的可讀屬性。
寫:調用bean的可寫屬性。
7.3.2 EL取值:獲取對象屬性
如果我們將一個Emp的實例存在request作用域中,使用el表達式取值應該怎么取呢?
<%@ page import="包路徑.Emp" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head><title>測試el表達式取值對象屬性</title> </head> <body><%Emp e = new Emp();e.setId(1);e.setName("tom");request.setAttribute("emp", e);%><p>員工編號為:${emp.id}</p> <p>員工姓名為:${emp.name}</p> </body> </html>這里的 ${emp.id} ,表面上看是在調用Emp的id屬性,但是id屬性是私有化的無法被直接訪問,其本質是調用了對應的bean的可讀屬性,也就是 getId()方法拿到的值。
需要注意的是,咱們如果寫的是 ${emp.id},那么就是在調用 getId(),如果寫的是${emp.abc},那么就是在調用 getAbc() ,他只會關注有沒有對應的bean屬性,如果沒有就會報錯。例如我改為:${emp.abc},就會報錯:
這里并不是說在Emp這兒找不到對象屬性abc,而是找不到對應的bean可讀屬性getAbc(),也是就如果提供一個getAbc()就可以了。我們將Emp改造一下,這樣就不會報錯,并取到值了。
當然我們一般不會自己為難自己,在編寫類的時候,對象屬性和bena屬性都是對應起來的,并不會故意把名字寫的不一樣。
7.3.3 EL取值:獲取數組的值
普通元素:
<%String[] arr={"a","b","c"};request.setAttribute("arr", arr); %> <p>${arr[0]}</p> <p>${arr[1]}</p> <p>${arr[2]}</p>對象元素:
<%Emp[] arr={new Emp(1,"tom"),new Emp(2,"jack")};request.setAttribute("arr", arr); %> <p>${arr[0].id} -- ${arr[0].name}</p> <p>${arr[1].id} -- ${arr[1].name}</p>7.3.4 EL取值:獲取集合的值
普通元素:
<%List<String> list=new ArrayList<String>();list.add("a1");list.add("a2");request.setAttribute("list", list); %> <p>${list[0]}</p> <p>${list[1]}</p>對象元素:
<%List<Emp> list=new ArrayList<Emp>();list.add(new Emp(1,"tom"));list.add(new Emp(2,"jack"));request.setAttribute("list", list); %> <p>${list[0].id} -- ${list[0].name}</p> <p>${list[1].id} -- ${list[1].name}</p>7.3.5 EL取值:從map中取值
<%Map<String,Object> map = new HashMap<>();map.put("id",1);map.put("name","tom");request.setAttribute("map",map); %> <p>${map.id} -- ${map.name}</p>小節一下:有了el表達式,好處是什么???
答案是:簡化代碼,el取值在代碼量上要少很多,同時,jsp中如果嵌入大量的java代碼,可讀性是很差的,有了el表達式,代碼的一致性增強了(jsp主要職責就是展示數據,而在jsp中使用java代碼獲取并展示數據就比較突兀,使用el展示數據風格就相對一致)。
7.4 EL中的表達式
el表達式中允許編寫變量或者表達式:${ 變量名或表達式},并支持各種運算:算術、邏輯、關系、三元運算等。
1.算術運算
2.比較運算
3.邏輯運算
4.三元運算
${邏輯判斷 ? 真的值 : 假的值}
5.判空表達式
${empty 變量名} 變量一定要放在作用域中
- 如果變量名在作用域中為空,不存在,返回 true
- 如果變量名為空串,返回 true
- 變量名是一個集合,如果集合中沒有元素,返回 true
八、JSTL標簽庫
8.1 介紹
有了el表達式,我們可以把存儲在四大作用域中的數據取出來進行展示。但是如果遇到一些判斷和遍歷,el就不方便了,例如:要把list中的數據取出顯示,就只能一個個的自己取出。
JSTL全稱為 JSP Standard Tag Library 即JSP標準標簽庫。
JSTL作為最基本的標簽庫,提供了一系列的JSP標簽,實現了基本的功能:集合的遍歷、數據的輸出、字符串的處理、數據的格式化等等功能!
8.2 在JSP中使用JSTL標簽庫
① 為項目導入jstl.jar和standard.jar 依賴包
jstl:https://repo1.maven.org/maven2/javax/servlet/jstl/1.2/jstl-1.2.jar
standard:https://repo1.maven.org/maven2/taglibs/standard/1.1.2/standard-1.1.2.jar
② 在JSP頁面中用taglib指令引入需要用到的JSTL標簽,在眾多的JSTL標簽庫中,我們一般用的比較多的是他的核心標簽庫:core標簽庫
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
說明:prefix是前綴,uri是標簽庫的路徑
8.3 if標簽
語法:
<c:if test="el表達式">內容(滿足條件才執行) </c:if> //el表達式為真,就執行if中的內容。案例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%--引入核心標簽庫--%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head><title>測試JSTL標簽庫</title> </head> <body><%request.setAttribute("age",20);%><c:if test="${age>=18}">成年了!</c:if><c:if test="${age<18}">未成年了!</c:if> </body> </html>8.4 forEach標簽
<c:forEach> 標簽用于元素遍歷,最常用的是遍歷list集合。
語法:
案例:遍歷獲取并遍歷 request作用域中的員工列表信息。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%--引入核心標簽庫--%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head><title>c:forEach測試</title> </head> <body><%-- 1.向request中存入員工列表 --%><%List<Emp> emps = new ArrayList<>();emps.add(new Emp(1,"張三"));emps.add(new Emp(2,"李四"));emps.add(new Emp(3,"王五"));request.setAttribute("emps",emps);%><%-- 2.使用forEach標簽遍歷展示 --%><c:forEach items="${emps}" var="emp"><p>${emp.id} -- ${emp.name}</p></c:forEach> </body> </html>//展示的結果為: 1 -- 張三 2 -- 李四 3 -- 王五除此以外,forEach標簽還有其他屬性:
begin:開始的元素(下標從0開始) end:最后一個元素 step:每一次迭代的步長 varStatus: 代表循環狀態的變量名稱,其包含:index(索引),count(計數),first(是否為第一項),last(是否為最后一項) 等等屬性。來一個完整的練習:
<%List<Emp> emps = new ArrayList<>();emps.add(new Emp(1,"張三"));emps.add(new Emp(2,"李四"));emps.add(new Emp(3,"王五"));emps.add(new Emp(4,"趙六"));emps.add(new Emp(5,"錢七"));request.setAttribute("emps",emps); %> <table border="1"><tr><th>索引(0開始)</th><th>計數(1開始)</th><th>是否為第一項</th><th>是否為最后項</th><th>員工編號</th><th>員工姓名</th></tr><c:forEach items="${emps}" var="emp" begin="0" end="3" step="1" varStatus="empStatus"><tr><td>${empStatus.index}</td><td>${empStatus.count}</td><td>${empStatus.first}</td><td>${empStatus.last}</td><td>${emp.id}</td><td>${emp.name}</td></tr></c:forEach> </table>運行結果為:
8.5 核心標簽庫中其他標簽
總結
以上是生活随笔為你收集整理的03-JavaWeb之JSP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dev-C++创建项目
- 下一篇: 点灯游戏原生JS实现与jQuery实现