2020了,还要学JSP嘛?入个门呗!毕竟Servlet亲兄弟~
目錄
- 1、什么是JSP
- 2、JSP原理
- 3、JSP基礎語法
- jsp表達式
- jsp腳本片段
- jsp聲明
- jsp注釋
- 4、JSP指令
- 5、JSP行為
- 6、9大內置對象
- 7、EL表達式
- 格式
- 變量
- [ ]與.運算符
- 8、JSTL表達式
- 9、JSP標簽
ps:本文著重于一些重點(第二點原理)哦~ 畢竟2020了 ,JSP很少用到了!
1、什么是JSP
Java Server Pages:Java服務器端頁面,和Servlet一樣,用于動態Web技術!
JSP部署于網絡服務器上,可以響應客戶端發送的請求,并根據請求內容動態地生成HTML、XML或其他格式文檔的Web網頁,然后返回給請求者。
特點:
-
JSP 技術是以 Java 語言作為腳本語言的,JSP 網頁為整個服務器端的 Java 庫單元提供了一個接口來服務于HTTP的應用程序。因此JSP里可以直接寫Java代碼!
-
寫JSP就像寫HTML
- HTML頁面是靜態頁面,固定內容,不會變,由web服務器向客戶端發送。
- JSP頁面是有JSP容器執行該頁面的Java代碼部分然后實時生成動態頁面,可動態更新頁面上的內容。
- JSP頁面中可以嵌入Java代碼,為用戶提供動態數據
2、JSP原理
JSP是怎么執行的?
在IDEA中使用Tomcat會在IDEA目錄下的tomcat中產生一個work目錄
IDEA的工作目錄位置:
C:\Users\zsr204\AppData\Local\JetBrains\IntelliJIdea2020.1
或者C:\Users\zsr204.IntelliJIdea2019.3
點進去,可以看到我們使用過tomcat的項目
點入一個項目,就可以看到對應的work目錄
繼續點開,可以發現index.jsp頁面轉換成了Java程序
我們打開.java文件,發現繼承了HttpJspBase類
而HttpJspBase繼承了JspPage,JspPage又繼承了Servlet
所以:JSP最終會被轉換為Java類,JSP本質上就是Servlet,瀏覽器向服務器發送請求,不管訪問什么資源,其實都是在訪問Servlet
經過以上分析,我們可以得出以下原理圖
接下來我們分析一下index.java類
有以下三個主要的方法:
//初始化jsp頁面
public void _jspInit() {}//關閉jsp頁面
public void _jspDestroy() {}//JspService
public void _jspService(HttpServletRequest request,HttpServletResponse response)
關于**_jspService**方法:有幾個部分組成
- 判斷請求
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {final java.lang.String _jspx_method = request.getMethod();if ("OPTIONS".equals(_jspx_method)) {response.setHeader("Allow","GET, HEAD, POST, OPTIONS");return;}if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {response.setHeader("Allow","GET, HEAD, POST, OPTIONS");response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允許 GET、POST 或 HEAD。Jasper 還允許 OPTIONS");return;}}
-
內置一些對象
這些對象我們可以直接在JSP頁面中使用~
final javax.servlet.jsp.PageContext pageContext;//頁面上下文,包含整個頁面相聯系的數據
javax.servlet.http.HttpSession session = null; //session(服務端會話)對象
final javax.servlet.ServletContext application; //applicationContext
final javax.servlet.ServletConfig config; //config配置
javax.servlet.jsp.JspWriter out = null; //out輸出對象,用來寫入響應流的數據
final java.lang.Object page = this; //page,servlet自身
HttpServletRequest request //HTTP request(請求)對象
HttpServletResponse response //HTTP response(響應)對象
- 輸出頁面前增加的代碼
response.setContentType("text/html"); //設置響應的頁面類型
pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); //初始化pageContext對象
_jspx_page_context = pageContext; //賦值
application = pageContext.getServletContext(); //獲取servlet上下文
config = pageContext.getServletConfig(); //獲取配置對象
session = pageContext.getSession(); //獲取session對象
out = pageContext.getOut(); //獲取out輸出對象
_jspx_out = out; //賦值
- 輸出當前頁面
out.write("<html>\n");
out.write("<body>\n");
out.write("<h2>Hello World!</h2>\n");
out.write("</body>\n");
out.write("</html>\n");
這時候,如果我們在IDEA中新加一個hello.jsp,我們點擊運行
我們會發現,剛才打開index.jsp所在的的目錄不存在了,其實是原先的整個work目錄沒了,并生成了一個新的work目錄
我們繼續點開新的work目錄,同樣可以看到之前的index.jsp和index.java
這時候我們在瀏覽器訪問hello.jsp頁面,發現頁面輸出了我們jsp中用java代碼定義的name
然后可以發現,我們多了hello.jsp和hello.java兩個文件
我們再點開hello.java,可以發現除了輸出頁面的代碼變成對應hello.jsp的代碼以外,其他沒有區別
out.write("\r\n");out.write("<html>\r\n");out.write("<head>\r\n");out.write(" <title>Title</title>\r\n");out.write("</head>\r\n");out.write("<body>\r\n");out.write("hello\r\n");out.write('\r');out.write('\n');String name = "zsr";out.write('\r');out.write('\n');out.write("\r\n");out.write("name:");out.print(name);out.write("\r\n");out.write("</body>\r\n");out.write("</html>\r\n");
我們觀察這段段代碼,可以發現
在JSP頁面中:Java代碼會原封不動的輸出,如果是Html代碼,就會被轉換為以下形式
out.write("<html?\r\n");
3、JSP基礎語法
jsp表達式
用來將程序輸出到客戶端
<%= 變量或者表達式 %>
<%=new Date()%>
jsp腳本片段
- 腳本程序可以包含任意量的Java語句、變量、方法或表達式,只要它們在腳本語言中是有效的。
<% 代碼片段 %>
等價于
<jsp:scriptlet>代碼片段
</jsp:scriptlet>
<%int sum = 0;for (int i = 0; i < 100; i++) {sum += i;}out.print("<h1>總和為" + sum + "</h1>");
%>
腳本片段的嵌套
<%int x = 10;out.print(x);
%>
<p>這是一個jsp文檔</p>
<%out.println(x);
%>
<%for (int i = 0; i < 5; i++) {
%>
<h1>helloworld</h1>
<%}
%>
jsp聲明
- 一個聲明語句可以聲明一個或多個變量、方法,供后面的Java代碼使用
<%! declaration; [ declaration; ]…%>
等價于
<jsp:declaration>代碼片段
</jsp:declaration>
<%!static {System.out.println("加載中");}private int count = 0;public void function() {System.out.println("進入了方法");}
%>
會被編譯到jsp生成的Java類index_jsp中!
而上述jsp表達式和腳本片段都會生成到**_jspService**方法中
jsp注釋
<%--注釋--%>
| 語法 | 描述 |
|---|---|
| <%-- 注釋 --%> | JSP注釋,注釋內容不會被發送至瀏覽器甚至不會被編譯 |
| HTML注釋,通過瀏覽器查看網頁源代碼時可以看見注釋內容 |
4、JSP指令
JSP指令用來設置與整個JSP頁面相關的屬性。
| 指令 | 描述 |
|---|---|
| <%@ page … %> | 定義頁面的依賴屬性,比如腳本語言、error頁面、緩存需求等等 |
| <%@ include … %> | 包含其他文件 |
| <%@ taglib … %> | 引入標簽庫的定義,可以是自定義標簽 |
實例1:定制500錯誤頁面,利用<%@ page … %>指令跳轉
error.jsp(1/0會出現500錯誤,會跳轉到500錯誤頁面)
<%@ page contentType="text/html;charset=UTF-8" language="java" %><%--定制錯誤頁面--%>
<%@ page errorPage="error/500.jsp" %><html>
<head><title>出現錯誤</title>
</head>
<body>
<%int x = 1/0;
%>
</body>
</html>
500.jsp(自定義500錯誤頁面,顯示500錯誤圖片)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body><img src="../img/500.jpg" alt="500"></body>
</html>
測試:點擊運行,輸入地址localhost:8080/error.jsp,就會跳轉到自定義的500錯誤頁面
實現錯誤頁面的跳轉還可以再web.xml中配置
<error-page><error-code>404</error-code><location>/error/404.jsp</location>
</error-page>
<error-page><error-code>500</error-code><location>/error/500.jsp</location>
</error-page>
實例二 :效仿正常頁面,利用<%@ include … %>指令包含一個頭部一個尾部
header.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %><h1>頁面頭部</h1>
footer.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>頁面尾部</h1>
common.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>包含頭部尾部常規頁面</title>
</head>
<body><%--將兩個頁面合二為一--%>
<%@include file="common/header.jsp" %>
<h1>網頁主體</h1>
<%@include file="common/footer.jsp" %></body>
</html>
測試:點擊運行,輸入localhost:8080/common.jsp,發現如下結果
5、JSP行為
JSP行為標簽使用XML語法結構來控制servlet引擎。它能夠動態插入一個文件,重用JavaBean組件,引導用戶去另一個頁面,為Java插件產生相關的HTML等等。
行為標簽只有一種語法格式,它嚴格遵守XML標準:
<jsp:action_name attribute="value" />
行為標簽基本上是一些預先就定義好的函數,下表羅列出了一些可用的JSP行為標簽:
| 語法 | 描述 |
|---|---|
| jsp:include | 用于在當前頁面中包含靜態或動態資源 |
| jsp:useBean | 尋找和初始化一個JavaBean組件 |
| jsp:setProperty | 設置 JavaBean組件的值 |
| jsp:getProperty | 將 JavaBean組件的值插入到 output中 |
| jsp:forward | 從一個JSP文件向另一個文件傳遞一個包含用戶請求的request對象 |
| jsp:plugin | 用于在生成的HTML頁面中包含Applet和JavaBean對象 |
| jsp:element | 動態創建一個XML元素 |
| jsp:attribute | 定義動態創建的XML元素的屬性 |
| jsp:body | 定義動態創建的XML元素的主體 |
| jsp:text | 用于封裝模板數據 |
例如上述實現正常頁面包含頭部尾部還可以通過以下代碼來實現
<%--jsp標簽--%>
<%--拼接頁面,本質還是三個頁面--%>
<jsp:include page="common/header.jsp"/>
<h1>網頁主體</h1>
<jsp:include page="common/footer.jsp"/>
6、9大內置對象
| 對象 | 描述 |
|---|---|
| request | HttpServletRequest類的實例**(存東西)** |
| response | HttpServletResponse類的實例 |
| out | PrintWriter類的實例,用于把結果輸出至網頁上 |
| session | HttpSession類的實例**(存東西)** |
| application | ServletContext類的實例,與應用上下文有關**(存東西)** |
| config | ServletConfig類的實例 |
| pageContext | PageContext類的實例,提供對JSP頁面所有對象以及命名空間的訪問**(存東西)** |
| page | 類似于Java類中的this關鍵字 |
| Exception | Exception類的對象,代表發生錯誤的JSP頁面中對應的異常對象 |
其中request、session、application、pageContext可以存相應信息
關于request、session、application、pageContext的層級關系圖:
作用域(scope)從低到高:pageContext—>request—>session—>application
案例測試:
test.jsp(用來存東西,并取出顯示)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>內置對象的測試</title>
</head>
<body>
<%pageContext.setAttribute("name1", "zsr");//保存的數據只在一個頁面中有效request.setAttribute("name2", "barry");//保存的數據只在一次請求中有效,請求轉發會攜帶這個數據session.setAttribute("name3", "gcc");//保存的數據只在一次會話中有效,從打開瀏覽器到關閉瀏覽器application.setAttribute("name4", "marry");//保存的數據只在服務器中有效,從打開服務器到關閉服務器
%>
<%//從pageContext中取,利用尋找的方式//從底層到高層(作用域)String name1 = (String) pageContext.findAttribute("name1");String name2 = (String) pageContext.findAttribute("name2");String name3 = (String) pageContext.findAttribute("name3");String name4 = (String) pageContext.findAttribute("name4");
%>
<%--使用EL表達式輸出--%>
<h1>取出的值為:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3></body>
</html>
然后我們點擊運行,輸入localhost:8080/test.jsp,可以看到下圖所示結果
我們再新建一個頁面test2.jsp,取出上述test.jsp存進去的東西
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>內置對象的測試</title>
</head>
<body><%//從pageContext中取,利用尋找的方式//從底層到高層(作用域)String name1 = (String) pageContext.findAttribute("name1");String name2 = (String) pageContext.findAttribute("name2");String name3 = (String) pageContext.findAttribute("name3");String name4 = (String) pageContext.findAttribute("name4");
%>
<%--使用EL表達式輸出--%>
<h1>取出的值為:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3></body>
</html>
然后我們點擊運行,輸入localhost:8080/test2.jsp,可以看到下圖所示結果
發現只取出了name3和name4,也就是存在session和application里的東西,這就是因為作用域的原因
-
pageContext的作用域最小,只在當前頁面有效,所以換了新頁面,就找不到了
-
request的作用域其次,因為沒有進行轉發,所以內容也丟失了,所以沒有找到
這時候如果我們在test1.jsp里面加入轉發,轉發到test2.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>內置對象的測試</title>
</head>
<body>
<%pageContext.setAttribute("name1", "zsr");//保存的數據只在一個頁面中有效request.setAttribute("name2", "barry");//保存的數據只在一次請求中有效,請求轉發會攜帶這個數據session.setAttribute("name3", "gcc");//保存的數據只在一次會話中有效,從打開瀏覽器到關閉瀏覽器application.setAttribute("name4", "marry");//保存的數據只在服務器中有效,從打開服務器到關閉服務器
%>
<%//從pageContext中取,利用尋找的方式//從底層到高層(作用域)String name1 = (String) pageContext.findAttribute("name1");String name2 = (String) pageContext.findAttribute("name2");String name3 = (String) pageContext.findAttribute("name3");String name4 = (String) pageContext.findAttribute("name4");pageContext.forward("/test2.jsp");
%>
<%--使用EL表達式輸出--%>
<h1>取出的值為:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3></body>
</html>
然后我們點擊運行,輸入localhost:8080/test.jsp,可以看到下圖所示結果
可以發現我們取出了存在request里的name2,這是因為我們進行了轉發
7、EL表達式
EL(Expression Language) 是為了使JSP寫起來更加簡單
<!--standard 標簽庫-->
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version>
</dependency>
作用:
- 獲取數據
- 執行運算
- 獲取web開發的常用對象
格式
${}
-
例如,${info}代表獲取變量info的值。
-
當EL表達式中的變量不給定范圍時
則默認在page范圍查找,然后依次在request、session、application范圍查找。
-
可以用范圍作為前綴表示屬于哪個范圍的變量
例如:${ pageScope. info}表示訪問page范圍中的info變量。
變量
-
EL存取變量數據的方法很簡單,例如:${name}。它的意思是取出某一范圍中名稱為name的變量。
-
因為并沒有指定哪一個范圍的name,所以會依序從Page、Request、Session、Application范圍查找。
-
假如找到name,就直接回傳,不再繼續找下去,但是假如全部的范圍都沒有找到時,就回傳""。
EL表達式的屬性如下:
| 屬性范圍在EL中的名稱 | |
|---|---|
| Page | PageScope |
| Request | RequestScope |
| Session | SessionScope |
| Application | ApplicationScope |
[ ]與.運算符
-
EL 提供“.“和“[ ]“兩種運算符來存取數據。
-
當要存取的屬性名稱中包含一些特殊字符,如 . 或 - 等并非字母或數字的符號,就一定要使用“[ ]“。
例如:user.My?Name應當改為{ user. My-Name}應當改為user.My?Name應當改為{user[“My-Name”]}
-
如果要動態取值時,就可以用“[ ]“來做,而“.“無法做到動態取值。
例如:${sessionScope.user[data]}中data 是一個變量
8、JSTL表達式
JSTL(Java server pages standarded tag library,即JSP標準標簽庫)
- JSTL標簽庫的使用就是為了彌補HTML標簽的不足;他自定義許多標簽供使用,功能和Java代碼一樣。
<!--standard 標簽庫-->
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version>
</dependency>
<!--JSTL表達式的依賴-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<dependency><groupId>javax.servlet.jsp.jstl</groupId><artifactId>jstl-api</artifactId><version>1.2</version>
</dependency>
菜鳥教程JSTL
根據JSTL標簽所提供的功能,可以將其分為5個類別。
- 核心標簽
- 格式化標簽
- SQL 標簽
- XML 標簽
- JSTL 函數
JSTL標簽庫的使用步驟:
-
引入對應的taglib
-
使用其中的方法
-
在Tomcat的lib目錄下也要引入對應jstl的jar包,否則會報錯:JSTL解析錯誤
示例:
coreif.jsp(測試用戶登錄)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>Title</title>
</head>
<body>
<h4>if測試</h4>
<hr>
<%--EL表達式獲取表單中的數據${param.參數名}
--%>
<form action="coreif.jsp" method="get"><input type="text" name="username" value="${param.username}"><input type="submit" value="登錄">
</form><%--判斷如果提交的用戶名是管理員,則登錄成功--%>
<c:if test="${param.username=='admin'}" var="isAdmin"><c:out value="管理員歡迎你"/>
</c:if>
<c:out value="${isAdmin}"/>
</body>
</html>
點擊運行,打開 http://localhost:8080/coreif.jsp,出現如下結果
如果我們輸入admin再點擊登錄
9、JSP標簽
一共以下幾種標簽
實例:
jsptag:(攜帶參數,請求轉發到 jsptag2)
<html>
<head><title>Title</title>
</head>
<body><jsp:forward page="jsptag2.jsp"><jsp:param name="name" value="zsr"/><jsp:param name="age" value="20"/>
</jsp:forward></body>
</html>
jsptag2:(取出請求參數)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<%--取出參數--%>
名字:<%=request.getParameter("name")%>
年齡:<%=request.getParameter("age")%>
</body>
</html>
然后點擊運行,在瀏覽器訪問 http://localhost:8080/jsptag.jsp,可以看到對應結果
到這就結束了!!謝謝大家支持哦~
總結
以上是生活随笔為你收集整理的2020了,还要学JSP嘛?入个门呗!毕竟Servlet亲兄弟~的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 8086汇编语言精华笔记总结~
- 下一篇: MySQL最新版8.0.21安装配置教程