1. 程式人生 > >第二十八章:JSP動態頁面

第二十八章:JSP動態頁面

作者:java_wxid

1.什麼是Jsp?
jsp是java server page,java的伺服器頁面。
2.為什麼要學習jsp技術
因為jsp技術可以很好的解決在Servlet程式中回傳資料是html內容,這個問題。

在Servlet程式中回傳html資料,為什麼是個問題?

public class PrintHtml extends HttpServlet {
	private static final long serialVersionUID = 1L;    
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// 解決響應亂碼
		response.setContentType("text/html; charset=UTF-8");    		
		// 回傳一個html頁面的資料
		PrintWriter writer = response.getWriter();
		writer.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
		writer.write("<html>\r\n");
		writer.write("	<head>\r\n");
		writer.write("		<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
		writer.write("		<title>Insert title here</title>\r\n");
		writer.write("	</head>\r\n");
		writer.write("	<body>\r\n");
		writer.write("		這是hello的html頁面\r\n");
		writer.write("	</body>\r\n");
		writer.write("</html>");
	}
}

可以看到建立一個html頁面非常繁瑣

3.如何建立一個jsp動態頁面。
在這裡插入圖片描述
4.如何修改jsp頁面的預設編碼?
在這裡插入圖片描述
小結:
html和jsp一樣。都在放在webContent目錄下
WebContent
a.html =====>>>> http://ip:port/工程名/a.html
b.jsp =====>>>> http://ip:port/工程名/b.jsp

5.jsp的本質是什麼。
jsp本質上,也是一個Servlet程式。

當我們第一次訪問jsp頁面的時候,Tomcat伺服器會把jsp翻譯成為java原始檔,然後儲存到Tomcat伺服器的work目錄下。
雙擊Tomcat v7.0 Server at localhost [Started ,Synchronized],彈出如下視窗
在這裡插入圖片描述


jsp生成的class檔案和java原始檔
在這裡插入圖片描述
我們開啟a_jsp.java原始檔,不難發現生成的這個類繼承了HttpJspBase類。
在這裡插入圖片描述
然後我們再通過檢視原始碼發現,HttpJspBase又繼承了HttpServlet程式。所以生成的類本質上也是一個Servlet程式。
在這裡插入圖片描述
jsp翻譯成為Servlet原始檔,全名規則(瞭解大概):
a.jsp 翻譯之後命名的全名為:a_jsp.java
b.jsp 翻譯之後命名的全名為:b_jsp.java

原始檔名.jsp 翻譯之後是: 原始檔名_jsp.java

6.jsp的三種語法
a)jsp頭部的page指令

<%@ page language=“java” contentType=“text/html; charset=UTF-8”
pageEncoding=“UTF-8”%>

i.language屬性 值只能是java。表示jsp翻譯之後是java原始檔。
ii.contentType屬性 返回的內容型別。response.setContentType的引數值。
iii.pageEncoding屬性 是當前jsp頁面的字符集
iv.import屬性 可以在jsp頁面中匯入需要的包和類。
v.autoFlush屬性 設定jsp中的out輸出流是否自動重新整理 預設是true(一般都不會修改自動重新整理為false),
當jsp中out輸出流的緩衝區滿了之後,就會自動重新整理。
vi.buffer屬性 設定jsp中的out輸出流的緩衝區大小。預設是8kb
在這裡插入圖片描述
vii.errorPage屬性 設定當jsp執行時出錯,就自動跳轉的頁面。
viii.isErrorPage屬性 設定當前jsp是否是錯誤頁面,預設是false,表示不啟動異常物件。設定為true,可以啟用Exception異常物件
ix.session 屬性 設定訪問jsp的時候,是否建立Session會話物件。預設是true.
x.extends 屬性 extends繼承屬性是預留給伺服器廠商使用的。(基本都不會動)

b)jsp中的三種指令碼
i.宣告指令碼(幾乎不用)
宣告指令碼的格式: <%! 宣告程式碼 %>

宣告指令碼可以宣告在類的內部定義的程式碼。

1.我們可以定義全域性變數。
2.定義static靜態程式碼塊
3.定義方法
4.定義內部類

測試程式碼:

	<body>
<!-- 1.我們可以定義全域性變數。 -->
		<%! 
			int i = 0;
			private static Map<String,Object> map = new HashMap<String,Object>();
		%>
<!-- 2.定義static靜態程式碼塊 -->
		<%!
			static {
				map.put("key1", "value1");
				map.put("key2", "value2");
				map.put("key3", "value3");
			}
		%>
<!-- 3.定義方法 -->
		<%!
			public void abc(){
				System.out.println("國哥真帥!");
			}
		%>
<!-- 4.定義內部類 -->
		<%!
			private static class A {
				private String name;
			}
		%>
	</body>

在這裡插入圖片描述
ii.表示式指令碼
表示式指令碼的格式:<%=表示式 %>

表示式指令碼可以在jsp頁面中輸出資料。
表示式指令碼都會被翻譯到_jspService方法中
表示式指令碼翻譯之後都是out.print進行輸出
表示式指令碼中的表示式不能以分號結尾
由於表示式指令碼翻譯之後都在_jspService方法中,所以在_jspService方法中的物件都可以在表示式指令碼中直接使用。

1.輸出整型
2.輸出浮點型
3.輸出字串
4.輸出物件
在這裡插入圖片描述
iii.程式碼指令碼
程式碼指令碼的格式是: <% 程式碼指令碼 %>
程式碼指令碼可以寫以方法中可以寫的任何程式碼。
程式碼指令碼翻譯之後都在_jspService方法中

1.程式碼指令碼----if 語句
2.程式碼指令碼----for 迴圈語句
3.翻譯後java檔案中_jspService方法內的程式碼都可以寫
在這裡插入圖片描述
c)jsp中的三種註釋
i.html註釋
<!-- html註釋 -->
翻譯之後是out.write輸出到客戶端。

ii.java註釋
// 單行註釋
/* 多行註釋 */
Java 註釋 翻譯之後會原封不動翻譯到原始碼中

iii.jsp註釋
<%-- 這是jsp註釋 --%>
jsp註釋 在翻譯的時候,會被忽略掉

7.jsp九大內建物件

在這裡插入圖片描述
8.jsp四大域物件
pageContext ====>>>> request ====>>>>> session =====>>>>> application
域物件 資料操作範圍
pageContext 當前jsp頁面
request 同一次請求
session 同一次會話(開啟瀏覽器,訪問伺服器之後會話就打開了,只要瀏覽器不關。會話都在)
application 一個web工程

四個域的資料操作範圍從小到大分別是:pageContext====>>>request====>>>session=====>>>>application

四個域都可以用來儲存資料,如何挑選使用?
四個域從小到大進行優先選擇。

Context1.jsp頁面

	<body>
		<h1>Context1.jsp頁面</h1>
		<%
			pageContext.setAttribute("key", "pageContextData");
			request.setAttribute("key", "requestData");
			session.setAttribute("key", "sessionData");
			application.setAttribute("key", "applicaionData");
		%>	
		pageContext域:<%=pageContext.getAttribute("key") %><br/>
		request域:<%=request.getAttribute("key") %><br/>
		session域:<%=session.getAttribute("key") %><br/>
		application域:<%=application.getAttribute("key") %><br/>
		<%
// 			request.getRequestDispatcher("/Context2.jsp").forward(request, response);
		%>
	</body>

Context2.jsp頁面

<body>
	<h1>Context2.jsp頁面</h1>
	pageContext域:<%=pageContext.getAttribute("key") %><br/>
	request域:<%=request.getAttribute("key") %><br/>
	session域:<%=session.getAttribute("key") %><br/>
	application域:<%=application.getAttribute("key") %><br/>
</body>

9.jsp中的out輸出和response.getWriter輸出的區別
在這裡插入圖片描述
現在我們都知道out和response都可以往頁面上輸出資料。
通過觀察jsp翻譯之後的原始碼我們發現,都是使用out進行輸出。所以我們以後也是統一使用out進行輸出操作。
out.write 可以輸出字串
out.print 可以輸出任意資料
深入淺出:統一使用out.print進行輸出

10.jsp的常用標籤
a)jsp靜態包含

<%--
	<%@ include file="" %> 是靜態包含。
		靜態包含地址中打頭的斜槓,
		表示http://ip:port/工程名/	對映到程式碼的WebContent目錄
		
		
	靜態包含,其實本質上,只是把被包含的jsp頁面的內容。原封不動的拷貝到被包含的位置執行。
	靜態包含,不會翻譯被包含的jsp檔案。
 --%>
<%@ include file="/include/footer.jsp" %>

b)jsp標籤-動態包含

<%--
		<jsp:include page=""></jsp:include> 是動態包含
			動態包含地址中打頭的斜槓,
			表示http://ip:port/工程名/	對映到程式碼的WebContent目錄			  			
		動態包含,會把被包含的jsp頁面也翻譯成為servlet程式。
		動態包含,會翻譯成為如下語句:
		JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);
		等價於把request,response,out物件傳遞給footer.jsp所翻譯出來的Servlet去執行使用。
		動態包含,還可以傳遞引數
	 --%>
	<jsp:include page="/include/footer.jsp">
		<jsp:param value="wzg168" name="username"/>
		<jsp:param value="123456" name="password"/>
</jsp:include>

動態包含底層原理:
在這裡插入圖片描述

c)jsp標籤-轉發
<jsp:forward page="/Context2.jsp"></jsp:forward>
請求轉發功能,
跟request.getRequestDispatcher("/Context2.jsp").forward(request, response);程式碼功能完全一樣
11.靜態包含和動態包含的區別
在這裡插入圖片描述隨著整個javaEE技術的不斷升級,那麼jsp這種技術,在整個javaEE體系中的定位慢慢發生變化。
jsp的定位慢慢就變成了,只是用來輸出html頁面資料而已。所以一般情況下。都使用靜態包含。

jsp的練習題
練習一:在jsp中輸出10*10的表格

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Insert title here</title>
<style type="text/css">
	table{
		width: 500px;
		border: 1px solid red;
		border-collapse: collapse;
	}
	th , td{
		border: 1px solid red;
	}
</style>
	</head>
	<body>
		<table>
		<%	for (int i = 1; i <= 10; i++) { %>
			<tr>
			<%	for (int j = 1; j <= 10; j++) { %>
				<td><%=i + "," + j %></td>
			<%  } %>
			</tr>
		<%  } %>
		</table>
	</body>
</html>

練習二:在jsp中輸出九九乘法口訣表

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Insert title here</title>
	</head>
	<body>
		<center>
			<h1>九九乘法口訣表</h1>
			<table width="600">
			<% for(int i = 1; i < 10; i++){ %>
				<tr>
				<% for(int j = 1; j <= i ; j++){ %>
					<td><%=j + "x" + i + "=" + (j*i) %></td>
				<% } %>
				</tr>
			<% } %>
			</table>
		</center>
	</body>
</html>

練習三:jsp輸出一個表格,裡面有20個學生資訊。
請求轉發的流程示例:
在這裡插入圖片描述
Student類

public class Student {

	private Integer id;
	private String name;
	private String phone;
	private String email;

	public Student(Integer id, String name, String phone, String email) {
		super();
		this.id = id;
		this.name = name;
		this.phone = phone;
		this.email = email;
	}

	public Student() {
		super();
	}

SearchStduent程式

public class SearchStudent extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// 獲取請求引數
		// 查詢學生資訊
		// 得到多個學生資訊
		List<Student> stus = new ArrayList<Student>();
		for (int i = 1; i < 21; i++) {
			stus.add(new Student(i,"name"+i, "phone"+i,"email"+i));
		}
		// 把學生資訊儲存到request域中
		request.setAttribute("stus", stus);
		// 請求轉發到jsp頁面中輸出資料
		request.getRequestDispatcher("/test/showStudent.jsp").forward(request, response);
	}

}

showStudent.jsp頁面

<%@page import="java.util.ArrayList"%>
<%@page import="com.atguigu.pojo.Student"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Insert title here</title>
<style type="text/css">
	table{
		width: 500px;
		border: 1px solid red;
		border-collapse: collapse;
	}
	th , td{
		border: 1px solid red;
	}
</style>
	</head>
	<body>
		<%
			List<Student> stus = (List<Student>) request.getAttribute("stus");
		%>
		<table>
			<tr>
				<th>編號</th>
				<th>姓名</th>
				<th>電話</th>
				<th>郵箱</th>
				<th>操作</th>
			</tr>
		<% for (int i = 0; i < stus.size(); i++) { %>
			<%	Student stu = stus.get(i); %>
			<tr>
				<td><%=stu.getId() %></td>
				<td><%=stu.getName() %></td>
				<td><%=stu.getPhone() %></td>
				<td><%=stu.getEmail() %></td>
				<td>修改、刪除</td>
			</tr>
		<% } %>
		</table>
	</body>
</html>

12、什麼是Listener監聽器?
Listener監聽器是JavaWeb的三大元件之一,
三大元件分別是:Servlet程式、Filter過濾器、Listener監聽器

Listener監聽器,顧名思義,它監聽某個事物狀態變化,然後反饋給使用者資訊。
1、監聽事物狀態變化
2、反饋使用者結果

12.1、ServletContextListener監聽器
ServletContextListener監聽器,監聽ServletContext物件的建立和銷燬。

ServletContext是在web工程啟動的時候建立,在web工程停止的時候銷燬

如何使用ServletContextListener監聽器,步驟如下:
1、編寫一個類去實現ServletContextListener監聽器介面
2、到web.xml中去配置監聽器

ServletContextListenerImpl 程式碼:

public class ServletContextListenerImpl implements ServletContextListener {
	/**
	 * ServletContext物件建立並初始化就馬上呼叫此contextInitialized方法
	 */
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		System.out.println("ServletContext物件被建立啦啦啦…………");
	}

	/**
	 * 當ServletContext物件被銷燬之後,就會馬上呼叫contextDestroyed方法
	 */
	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		System.out.println("ServletContext物件被銷燬啦啦啦…………");
	}
}

web.xml中的配置:

<!-- listener標籤配置監聽器 -->
<listener>
	<!-- listener-class配置監聽器的全類名 -->
	<listener-class>com.atguigu.listener.ServletContextListenerImpl</listener-class>
</listener>