什么是JSP?
JSP(JavaServer Pages)是由Sun Microsystems公司主導(dǎo)創(chuàng)建的一種動(dòng)態(tài)網(wǎng)頁(yè)技術(shù)標(biāo)準(zhǔn)。JSP部署于網(wǎng)絡(luò)服務(wù)器上,可以響應(yīng)客戶端發(fā)送的請(qǐng)求,并根據(jù)請(qǐng)求內(nèi)容動(dòng)態(tài)地生成HTML、XML或其他格式文檔的Web網(wǎng)頁(yè),然后返回給請(qǐng)求者。JSP技術(shù)以Java語(yǔ)言作為腳本語(yǔ)言,為用戶的HTTP請(qǐng)求提供服務(wù),并能與服務(wù)器上的其它Java程序共同處理復(fù)雜的業(yè)務(wù)需求。
JSP將Java代碼和特定變動(dòng)內(nèi)容嵌入到靜態(tài)的頁(yè)面中,實(shí)現(xiàn)以靜態(tài)頁(yè)面為模板,動(dòng)態(tài)生成其中的部分內(nèi)容。JSP引入了被稱為“JSP動(dòng)作”的XML標(biāo)簽,用來(lái)調(diào)用內(nèi)建功能。另外,可以創(chuàng)建JSP標(biāo)簽庫(kù),然后像使用標(biāo)準(zhǔn)HTML或XML標(biāo)簽一樣使用它們。標(biāo)簽庫(kù)能增強(qiáng)功能和服務(wù)器性能,而且不受跨平臺(tái)問(wèn)題的限制。
JSP文件在運(yùn)行時(shí)會(huì)被其編譯器轉(zhuǎn)換成更原始的Servlet代碼。JSP編譯器可以把JSP文件編譯成用Java代碼寫(xiě)的Servlet,然后再由Java編譯器來(lái)編譯成能快速執(zhí)行的二進(jìn)制機(jī)器碼,也可以直接編譯成二進(jìn)制碼。
總結(jié):
jsp 的主要作用是代替 Servlet 程序回傳 html 頁(yè)面的數(shù)據(jù)。
因?yàn)?Servlet 程序響應(yīng) html 頁(yè)面數(shù)據(jù)是一件非常繁鎖的事情。開(kāi)發(fā)成本和維護(hù)成本都極高。
Servlet響應(yīng)html頁(yè)面數(shù)據(jù)的代碼
public class HtmlServlet extends HttpServlet {
private static final long serialVersionUID = -664392981001L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) {
// 設(shè)置返回的數(shù)據(jù)內(nèi)容的數(shù)據(jù)類型和編碼
response.setContentType("text/html; charset=utf-8");
try (
ServletOutputStream os = resp.getOutputStream();
) {
// 獲取字符輸出流
Writer writer = response.getWriter();
//輸出頁(yè)面內(nèi)容!
writer.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
\"http://www.w3.org/TR/html4/loose.dtd\">");
writer.write("<html>");
writer.write("<head>");
writer.write("<meta http-equiv=\"Content-Type\" content=\"text/html;
charset=UTF-8\">");
writer.write("<title>Insert title here</title>");
writer.write("</head>");
writer.write("<body>");
writer.write("這是由 Servlet 程序輸出的 html 頁(yè)面內(nèi)容!");
writer.write("</body></html>");
} catch (IOException e) {
e.printStackTrace();
}
}
}
總結(jié):
通過(guò)分析上述代碼,我們可以明顯看出,使用 Servlet 輸出簡(jiǎn)單的 HTML 頁(yè)面信息相當(dāng)不便捷。當(dāng)需要生成復(fù)雜頁(yè)面時(shí),問(wèn)題更為突出,不僅增加了難度,而且不利于頁(yè)面的維護(hù)和調(diào)試。因此,Sun 公司為了解決這個(gè)問(wèn)題,推出了 JSP(JavaServer Pages)這一動(dòng)態(tài)頁(yè)面技術(shù)。
JSP 旨在簡(jiǎn)化頁(yè)面輸出工作,讓開(kāi)發(fā)者能夠更輕松地創(chuàng)建、維護(hù)和調(diào)試動(dòng)態(tài)網(wǎng)頁(yè)。
使用jsp回傳html頁(yè)面的代碼:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
這是一個(gè)動(dòng)態(tài)的html 頁(yè)面數(shù)據(jù)
</body>
</html>
注意事項(xiàng):
1、jsp 頁(yè)面是一個(gè)類似于 html 的一個(gè)頁(yè)面。 jsp 直接存放到 web目錄下,和 html 一樣訪問(wèn) jsp 的時(shí)候,也和訪問(wèn) html 一樣。
2、jsp 的默認(rèn)編碼集是 iso-8859-1 修改 jsp 的默認(rèn)編碼為 UTF-8。
jsp 底層的運(yùn)行原理
jsp 頁(yè)面本質(zhì)上是一個(gè) Servlet 程序。
首先我們?nèi)フ业轿覀?Tomcat 的目錄下的 work\Catalina\localhost 目錄。當(dāng)我們發(fā)布 day03 項(xiàng)目,并啟動(dòng) Tomcat服務(wù)器后,我們發(fā)現(xiàn)在 work\Catalina\localhost 目錄下多出來(lái)一個(gè) day03目錄。
Tomcat服務(wù)器啟動(dòng)時(shí),控制臺(tái)輸出加載Tomcat相關(guān)目錄信息,找到以下目錄到資源管理器定位:
Using CATALINA_BASE: "C:\Users\lison\AppData\Local\JetBrains\IntelliJIdea2023.1\tomcat\27dea85b-c644-4a4f-bbef-74c234438fc1"

一開(kāi)始該目錄下是沒(méi)有day03這個(gè)目錄的。
當(dāng)我們?cè)跒g覽器地址欄輸入jsp頁(yè)面的訪問(wèn)路徑時(shí),此時(shí)馬上會(huì)生成一個(gè)day03\org\apache\jsp目錄,并且有兩個(gè)文件:

index_jsp.class 文件很明顯是 index_jsp.java 源文件編譯后的字節(jié)碼文件。
那么 index_jsp.java 是個(gè)什么內(nèi)容呢?
生成的 java 文件名,是以原來(lái)的文件名加上_jsp 得到。 xxxx_jsp.java 文件的名字。
當(dāng)我們第一次訪問(wèn) jsp 頁(yè)面的時(shí)候。Tomcat 服務(wù)器會(huì)幫我們把 jsp 頁(yè)面翻譯成為一個(gè) java 源文件。并且對(duì)它進(jìn)行編譯為.class 字節(jié)碼文件。我們打開(kāi) java 源文件不難發(fā)現(xiàn)其里面的內(nèi)容是:
public final class a_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
}
跟蹤源代碼發(fā)現(xiàn)HttpJspBase 類直接地繼承了 HttpServlet 類。也就是說(shuō)。jsp 翻譯出來(lái)的 java 類,它間接了繼承了 HttpServlet 類。也就是說(shuō),翻譯出來(lái)的是一個(gè) Servlet 程序。

通過(guò)分析翻譯后的 Java 源代碼,我們可以得出論:
JSP(JavaServer Pages)實(shí)際上就是特殊的 Servlet 程序。觀察這些 Servlet 程序的源代碼,我們可以發(fā)現(xiàn)其底層實(shí)現(xiàn)也是通過(guò)輸出流來(lái)完成的。具體來(lái)說(shuō),HTML 頁(yè)面數(shù)據(jù)被翻譯并直接輸出到 Servlet 程序的 service 方法中,從而實(shí)現(xiàn)了動(dòng)態(tài)網(wǎng)頁(yè)的生成。這就是我們所說(shuō)的 JSP 是專門用于輸出 HTML 頁(yè)面的 Servlet 程序。
JSP底層源碼
客戶端發(fā)送請(qǐng)求,Tomcat服務(wù)器生成的java源文件中代碼,該類間接繼承了HttpServelet類,動(dòng)態(tài)重寫(xiě)了service()方法。
public void _jspService(final HttpServletRequest request, final HttpServletResponse response)
throws java.io.IOException, ServletException {
final String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允許 GET、POST 或 HEAD。Jasper 還允許 OPTIONS");
return;
}
final PageContext pageContext;
HttpSession session = null;
final ServletContext application;
final ServletConfig config;
JspWriter out = null;
final Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\n");
out.write("\n");
out.write("<html>\n");
out.write(" <head>\n");
out.write(" <title>$Title$</title>\n");
out.write(" </head>\n");
out.write(" <body>\n");
out.write(" <h1>Hello,javaWeb</h1>\n");
out.write(" <div>\n");
out.write(" <form action=\"http://localhost:8080/day01-hello/hello2\" method=\"post\">\n");
out.write(" <label>\n");
out.write(" <input type=\"text\" name=\"uname\"/>\n");
out.write(" </label><br/>\n");
out.write(" <label>\n");
out.write(" <input type=\"text\" name=\"price\"/>\n");
out.write(" </label><br/>\n");
out.write(" <input type=\"submit\" value=\"提交\">\n");
out.write(" </form>\n");
out.write(" </div>\n");
out.write(" </body>\n");
out.write("</html>\n");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
結(jié)論:
從生成的文件我們不難發(fā)現(xiàn)一個(gè)規(guī)則。
a.jsp 翻譯成 java 文件后的全名是 a_jsp.java 文件
b.jsp 翻譯成 java 文件后的全名是 b_jsp.java 文件
那么 當(dāng)我們?cè)L問(wèn) 一個(gè) xxx.jsp 文件后 翻譯成 java 文件的全名是 xxx_jsp.java 文件, xxx_jsp.java 文件是一個(gè) Servlet 程序。原來(lái) jsp 中的 html 內(nèi)容都被翻譯到 Servlet 類的 service 方法中原樣輸出。
JSP語(yǔ)法
page指令
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
這是 jsp 文件的頭聲明。表示這是 jsp 頁(yè)面。
page指令中的屬性
language 屬性值只能是 java。 表示翻譯的得到的是 java語(yǔ)言的
contentType 屬性 設(shè)置響應(yīng)頭 contentType 的內(nèi)容
pageEncoding 屬性 設(shè)置當(dāng)前 jsp 頁(yè)面的編碼
import 屬性 給當(dāng)前 jsp 頁(yè)面導(dǎo)入需要使用的類包
autoFlush 屬性 設(shè)置是否自動(dòng)刷新 out 的緩沖區(qū),默認(rèn)為 true
buffer 屬性 設(shè)置 out 的緩沖區(qū)大小。默認(rèn)為 8KB
errorPage 屬性 設(shè)置當(dāng)前 jsp 發(fā)生錯(cuò)誤后,需要跳轉(zhuǎn)到哪個(gè)頁(yè)面去顯示錯(cuò)誤信息
isErrorPage 屬性 設(shè)置當(dāng)前 jsp 頁(yè)面是否是錯(cuò)誤頁(yè)面。是的話,就可以使用 exception 異常對(duì)象
session 屬性 設(shè)置當(dāng)前 jsp 頁(yè)面是否獲取 session 對(duì)象,默認(rèn)為 true
extends 屬性 給服務(wù)器廠商預(yù)留的 jsp 默認(rèn)翻譯的 servlet 繼承于什么類
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.Map"
errorPage="/500.jsp"
autoFlush="true"
buffer="8kb"
session="true"
extends="java.lang.Object"
%>
<!--
errorPage表示jsp發(fā)送錯(cuò)誤后自動(dòng)跳轉(zhuǎn)到錯(cuò)誤頁(yè)面路徑
這個(gè)路徑一般都是以 / 開(kāi)頭,它表示請(qǐng)求地址為http://ip:port/工程路徑/ 映射到工程的web目錄
-->
Jsp中的三種腳本
1、聲明式腳本
腳本格式:
<%!
java 代碼
%>
在聲明腳本塊中,我們可以干 4 件事情:
- 我們可以定義全局變量。
- 定義 static 靜態(tài)代碼塊
- 定義方法
- 定義內(nèi)部類
幾乎可以寫(xiě)在類的內(nèi)部寫(xiě)的代碼,都可以通過(guò)聲明腳本來(lái)實(shí)現(xiàn)。
<%!
//全局變量
public static final long NUMBER = 63712119L;
public static Map<String,Object> map;
public int num = 100;
//靜態(tài)代碼塊
static {
}
//內(nèi)部類
class AA {
}
//方法
public void show() {
}
2、表達(dá)式腳本
表達(dá)式腳本格式如下: <%=表達(dá)式 %>
表達(dá)式腳本 用于向jsp頁(yè)面輸出內(nèi)容。
表達(dá)式腳本 翻譯到 Servlet 程序的 service 方法中 以 out.print() 打印輸出
out 是 jsp 的一個(gè)內(nèi)置對(duì)象,用于生成 html 的源代碼
注意:表達(dá)式不要以分號(hào)結(jié)尾,否則會(huì)報(bào)錯(cuò)
表達(dá)式腳本可以輸出任意類型。
比如:
1.輸出整型
2.輸出浮點(diǎn)型
3.輸出字符串
4.輸出對(duì)象
<%=100 %><br/>
<%=map %><br/>
<%=88.88 %><br/>
<%=false %><br/>
<%="表達(dá)式腳本" %><br/>
3、代碼腳本
代碼腳本格式: <% java 代碼 %>
代碼腳本里可以書(shū)寫(xiě)任意的 java 語(yǔ)句。
代碼腳本的內(nèi)容都會(huì)被翻譯到 service 方法中。
所以 service 方法中可以寫(xiě)的 java 代碼,都可以書(shū)寫(xiě)到代碼腳本中。
<%
//遍歷輸出偶數(shù)
var num = 100;
for (var i = 0; i <= num; i++) {
if (i%2 == 0) {
//write寫(xiě)入除字符串到客戶端出現(xiàn)亂碼
//out.write(i);
out.print(i);
}
}
%>
jsp中的注釋
java注釋
// 單行 java 注釋
/*
多行 java 代碼注釋
*/
單行注釋和多行注釋能在翻譯后的 java 源代碼中看見(jiàn)。
jsp注釋
<%-- jsp 注釋 --%>
jsp 注釋在翻譯的時(shí)候會(huì)直接被忽略掉
html注釋
html 的注釋會(huì)被翻譯到 java 代碼中輸出到 html 頁(yè)面中查看
jsp 九大內(nèi)置對(duì)象
jsp中的內(nèi)置對(duì)象,指Tomcat在翻譯jsp頁(yè)面成為servlet源代碼后,內(nèi)部提供的九大對(duì)象,叫內(nèi)置對(duì)象。
打開(kāi)翻譯后的 java 文件。查看_jspService 方法:
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
//========九大內(nèi)置對(duì)象==============
java.lang.Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);
if (exception != null) {
response.setStatus(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
//========九大內(nèi)置對(duì)象==============
}
jsp 中九大內(nèi)置對(duì)象說(shuō)明:
request 對(duì)象 可以獲取請(qǐng)求信息
response 對(duì)象 可以設(shè)置響應(yīng)信息
pageContext 對(duì)象 當(dāng)前頁(yè)面上下文對(duì)象??梢栽诋?dāng)前上下文保存屬性信息
session 對(duì)象 可以獲取會(huì)話信息。
exception 對(duì)象 只有在 jsp 頁(yè)面的 page 指令中設(shè)置 isErrorPage="true" 的時(shí)候才會(huì)存在
application 對(duì)象 ServletContext 對(duì)象實(shí)例,可以獲取整個(gè)工程的一些信息。
config 對(duì)象 ServletConfig 對(duì)象實(shí)例,可以獲取 Servlet 的配置信息
out 對(duì)象 輸出流。
page 對(duì)象 表示當(dāng)前 Servlet 對(duì)象實(shí)例(無(wú)用,用它不如使用 this 對(duì)象)。
九大內(nèi)置對(duì)象,都是我們可以在【代碼腳本】中或【表達(dá)式腳本】中直接使用的對(duì)象。
jsp 四大域?qū)ο?/h2>
pageContext 當(dāng)前jsp頁(yè)面范圍內(nèi)有效
request 一次請(qǐng)求范圍內(nèi)有效
session 一次會(huì)話范圍內(nèi)有效 (瀏覽器訪問(wèn)服務(wù)器開(kāi)始帶關(guān)閉瀏覽器的范圍)
application(ServletContext) 就是 ServletContext 對(duì)象,整個(gè)web工程范圍內(nèi)有效(web工程啟動(dòng)到結(jié)束的范圍內(nèi))
四大域?qū)ο蠼?jīng)常用來(lái)保存數(shù)據(jù)信息。
測(cè)試四大作用域:
新建兩個(gè) jsp 頁(yè)面。分別取名叫:context1.jsp,context2.jsp
context1.jsp
<%--
Created by IntelliJ IDEA.
User: lisong
Date: 2023-07-25
Time: 17:14
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>context1頁(yè)面:</h2>
<%
//四個(gè)域中分別保存數(shù)據(jù)
pageContext.setAttribute("key1","pageContext");
request.setAttribute("key2","request");
session.setAttribute("key3","session");
application.setAttribute("key4","application");
%>
<%-- 測(cè)試當(dāng)前jsp頁(yè)面作用域 --%>
<%=pageContext.getAttribute("key1")%><br/>
<%=request.getAttribute("key2")%><br/>
<%=session.getAttribute("key3")%><br/>
<%=application.getAttribute("key4")%><br/>
<%
//測(cè)試request作用域
request.getRequestDispatcher("/context2.jsp").forward(request,response);
%>
</body>
</html>
context2.jsp
<%--
Created by IntelliJ IDEA.
User: lisong
Date: 2023-07-25
Time: 17:14
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>context2頁(yè)面:</h2>
<%=pageContext.getAttribute("key1")%> <br/>
<%=request.getAttribute("key2")%> <br/>
<%=session.getAttribute("key3")%> <br/>
<%=application.getAttribute("key4")%> <br/>
</body>
</html>
測(cè)試pageContext作用域:
直接訪問(wèn) context1.jsp 文件
測(cè)試request作用域:
1.在 context1.jsp 文件中添加轉(zhuǎn)發(fā)到 context2.jsp(有數(shù)據(jù))
2.直接訪問(wèn) context2.jsp 文件 (沒(méi)有數(shù)據(jù))
測(cè)試 session 作用域:
1.訪問(wèn)完 context1.jsp 文件
2.關(guān)閉瀏覽器。但是要保持服務(wù)器一直開(kāi)著
3.打開(kāi)瀏覽器,直接訪問(wèn) context2.jsp 文件
測(cè)試 application 作用域步驟:
1.訪問(wèn)完 context1.jsp 文件,然后關(guān)閉瀏覽器
2.停止服務(wù)器。再啟動(dòng)服務(wù)器。
3.打開(kāi)瀏覽器訪問(wèn) context2.jsp 文件
jsp 中 out 輸出流 和 response.getwriter() 輸出流
jsp 中 out 和 response 的 writer 的區(qū)別演示
<%--
Created by IntelliJ IDEA.
User: lisong
Date: 2024-01-15
Time: 00:27
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
// out 輸出
out.write("這是 out 的第一次輸出<br/>");
//flush后,輸出的內(nèi)容會(huì)被立即響應(yīng)給客戶端
out.flush();
// 最后一次的輸出,由于沒(méi)有手動(dòng) flush,會(huì)在整個(gè)頁(yè)面輸出到客戶端的時(shí)候,自動(dòng)寫(xiě)入到 writer緩沖區(qū)
out.write("這是 out 的第二次輸出<br/>");
/*
response.getWriter().write輸出內(nèi)容優(yōu)先級(jí)高于out.write
out.flush后語(yǔ)句優(yōu)先級(jí)高于response.getWriter().write
response.getWriter().close()后面的語(yǔ)句將不會(huì)被執(zhí)行
*/
response.getWriter().write("這是 writer 的第一次輸出<br/>");
response.getWriter().close();
response.getWriter().write("這是 writer 的第二次輸出<br/>");
%>
</body>
</html>
最終測(cè)試結(jié)果:

out 流和 writer 流的兩個(gè)緩沖區(qū)工作說(shuō)明:
response對(duì)象用于設(shè)置返回給客戶端的內(nèi)容(輸出),而out對(duì)象也用于向用戶提供輸出。
- 在JSP頁(yè)面中,輸出流按照從上到下的順序執(zhí)行。在沒(méi)有執(zhí)行flush語(yǔ)句和close()語(yǔ)句的情況下,response輸出流的優(yōu)先級(jí)高于out輸出流,因此會(huì)先執(zhí)行response緩沖區(qū)的內(nèi)容,然后再執(zhí)行out緩沖區(qū)的內(nèi)容。
- 如果在out輸出流之后執(zhí)行flush操作,那么out緩沖區(qū)的內(nèi)容將立即響應(yīng)給客戶端。
- 如果對(duì)response輸出流執(zhí)行close操作,那么后續(xù)的JSP語(yǔ)句將不會(huì)被執(zhí)行。這是因?yàn)殛P(guān)閉response輸出流會(huì)終止當(dāng)前的HTTP響應(yīng),導(dǎo)致后續(xù)的輸出無(wú)法發(fā)送給客戶端。
由于 jsp 翻譯之后,底層源代碼都是使用 out 來(lái)進(jìn)行輸出,所以一般情況下,我們?cè)?jsp 頁(yè)面中統(tǒng)一使用 out 來(lái)進(jìn)行輸出。避免打亂頁(yè)面輸出內(nèi)容的順序。
out.write() 輸出字符串沒(méi)有問(wèn)題,輸出其它數(shù)據(jù)類型會(huì)亂碼 。
out.print() 輸出任意數(shù)據(jù)都沒(méi)有問(wèn)題(都轉(zhuǎn)換成為字符串后調(diào)用的 write 輸出)。
<%
out.print(100);
out.print("哈哈");
%>
結(jié)論:在 jsp 頁(yè)面中,可以統(tǒng)一使用 out.print()來(lái)進(jìn)行輸出。
jsp 的常用標(biāo)簽
jsp 靜態(tài)包含
<%@ include file="/include/footer.jsp"%>
file 屬性指定你要包含的 jsp 頁(yè)面的路徑
地址中第一個(gè)斜杠 / 表示為 http://ip:port/工程路徑/ 映射到web項(xiàng)目的 web 目錄。
靜態(tài)包含是把包含的頁(yè)面內(nèi)容原封裝不動(dòng)的輸出到包含的位置。
靜態(tài)包含的特點(diǎn):
1、靜態(tài)包含不會(huì)翻譯被包含的 jsp 頁(yè)面。
2、靜態(tài)包含其實(shí)是把被包含的 jsp 頁(yè)面的代碼拷貝到包含的位置執(zhí)行輸出。
jsp 動(dòng)態(tài)包含
<jsp:include page="/include/footer.jsp">
<jsp:param name="username" value="bbj"/>
<jsp:param name="password" value="root"/>
</jsp:include>
page 屬性是指定你要包含的 jsp 頁(yè)面的路徑動(dòng)態(tài)包含也可以像靜態(tài)包含一樣。
把被包含的內(nèi)容執(zhí)行輸出到包含位置
動(dòng)態(tài)包含的特點(diǎn):
1、動(dòng)態(tài)包含會(huì)把包含的 jsp 頁(yè)面單獨(dú)翻譯成 servlet 文件,然后在執(zhí)行時(shí)再調(diào)用翻譯的 servlet 程序。并把計(jì)算的結(jié)果返回。 動(dòng)態(tài)包含是在執(zhí)行的時(shí)候,才會(huì)加載。所以叫動(dòng)態(tài)包含。
2、動(dòng)態(tài)包含底層代碼使用如下代碼去調(diào)用被包含的 jsp 頁(yè)面執(zhí)行輸出。
JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);
3、動(dòng)態(tài)包含,還可以傳遞參數(shù)
jsp 標(biāo)簽-轉(zhuǎn)發(fā)
<jsp:forward page="/scope2.jsp"></jsp:forward>
<jsp:forward> 轉(zhuǎn)發(fā)功能相當(dāng)于
request.getRequestDispatcher("/xxxx.jsp").forward(request, response); 的功能。
靜態(tài)包含和動(dòng)態(tài)包含的區(qū)別:
- 是否生成java文件
靜態(tài)包含在jsp底層java文件中不會(huì)被生成,動(dòng)態(tài)包含會(huì)被生成。 - service()方法的區(qū)別
靜態(tài)包含的內(nèi)容會(huì)被拷貝到底層service()中,動(dòng)態(tài)包含會(huì)調(diào)用JspRuntiemLibrary.include方法。 - 是否可以傳遞參數(shù)
靜態(tài)包含不可以傳遞參數(shù),動(dòng)態(tài)包含可以。 - 編譯次數(shù)
靜態(tài)包含1次,動(dòng)態(tài)包含的文件+1 - 適用范圍
靜態(tài)包含使用純靜態(tài)(CSS,HTML,JS)內(nèi)容,或沒(méi)有非常耗時(shí)操作,或大量的java代碼的jsp。
動(dòng)態(tài)包含需要傳遞參數(shù),含有大量java變量。
開(kāi)發(fā)經(jīng)驗(yàn):
實(shí)際工作中,幾乎都是使用靜態(tài)包含。理由很簡(jiǎn)單。因?yàn)?jsp 頁(yè)面雖然可以寫(xiě) java 代碼,做其他的功能操作。但是由于 jsp 在開(kāi)發(fā)過(guò)程中被定位為專門用來(lái)展示頁(yè)面的技術(shù)。也就是說(shuō)。jsp 頁(yè)面中,基
本上只有 html,css,js。還有一些簡(jiǎn)單的 EL,表達(dá)式腳本等輸出語(yǔ)句。所以我們都使用靜態(tài)包含。
JSP綜合練習(xí)
在 jsp 頁(yè)面中輸出九九乘法口訣表
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<style type="text/css">
table{
width: 650px;
}
</style>
</head>
<body>
<%-- 練習(xí)一:在 jsp 頁(yè)面中輸出九九乘法口訣表 --%>
<h1 align="center">九九乘法口訣表</h1>
<table align="center">
<%-- 外層循環(huán)遍歷行 --%>
<% for (int i = 1; i <= 9; i++) { %>
<tr>
<%-- 內(nèi)層循環(huán)遍歷單元格 --%>
<% for (int j = 1; j <= i ; j++) { %>
<td><%=j + "x" + i + "=" + (i*j)%></td>
<% } %>
</tr>
<% } %>
</table>
</body>
</html>