JSP 內置對象(上)
JSP 內置對象是 Web 容器創建的一組對象,不使用 new 關鍵字就可以直接使用的對象。如上一章中使用腳本實現打印九九乘法表中的out對象
<%-- 腳本:out對象是JSPWriter類的實例,用於向客戶端輸出內容 --%> <% for (int i = 1; i <= 9; i++) { for (int j = 1; j <=i; j++) { out.print(i + "*" + j + "=" + (i*j) + " "); } out.println("</br>"); } %>
JSP 共有九大內置對象
常用(5個): out, request, response, session, application
不常用(4個): page, pageContext, execption, config
緩沖區(Buffer)
所謂緩沖區就是內存的一塊區域用來保存臨時數據。下圖中,可以把一粒一粒米飯想象成字節,把盛米飯的容器想象成緩沖區
out 對象
out 對象是 JspWriter 類的實例,是向客戶端輸出內容
常用方法如下:
1、void println() 向客戶端打印字符串
2、void clear() 清除緩沖區的內容,如果在 flush 之後調用會拋出異常
3、void clearBuffer() 清除緩沖區的內容,如果在 flush 之後調用不會拋出異常
4、void flush() 將緩沖區內容輸出到客戶端
5、int getBufferSize() 返回緩沖區以字節數的大小,如不設緩沖區則為0
6、int getRemaining() 返回緩沖區還剩余多少可用
7、boolean isAutoFlush() 返回緩沖區滿時,是自動清空還是拋出異常
8、void close() 關閉輸出流
<%@ 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> <% out.println("<h2>靜夜思<h2>"); out.println("床前明月光<br>"); out.println("疑是地上霜<br>"); out.println("舉頭望明月<br>"); out.println("低頭思故鄉<br>"); %> <hr> 獲取緩沖區大小:<%=out.getBufferSize() %> size; <br> 獲取緩沖區可用大小:<%=out.getRemaining() %> size; <br> 是否自動清空緩沖區:<%=out.isAutoFlush() %> </body> </html>
頁面輸出結果:
下面在靜夜思中間加入flush,雖然頁面輸出不受影響,但是可用剩余緩沖區變大。然後分別試圖在其後運行 out.clear() 和 out.clearBuffer()
<%@ 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> <% out.println("<h2>靜夜思<h2>"); out.println("床前明月光<br>"); out.println("疑是地上霜<br>"); out.flush(); // out.clear(); // Error: Attempt to clear a buffer that‘s already been flushed // out.clearBuffer(); out.println("舉頭望明月<br>"); out.println("低頭思故鄉<br>"); %> <hr> 獲取緩沖區大小:<%=out.getBufferSize() %> size; <br> 獲取緩沖區可用大小:<%=out.getRemaining() %> size; <br> 是否自動清空緩沖區:<%=out.isAutoFlush() %> </body> </html>
request 對象
客戶端的請求信息被封裝在request對象中,通過它才能了解到客戶的需求,然後做出響應。request是HttpServerletRequest類的實例。
request 對象具有請求域,即完成客戶端的請求之前,該對象一直有效。常用方法如下:
- String getParameters(String name): 返回name 指定參數的參數值
- String[] getParameterValues(String name): 返回包含參數name 的所有值的數組
- void setAtrribute(String, Object): 存儲此請求中的屬性
- Object getAttribute(String name): 返回指定屬性的屬性值
- String getContentType(): 得到請求體的MIME 類型
- String getProtocol(): 返回請求用的協議類型及版本號
- String getServerName(): 返回接受請求的服務器主機名
- int getServerPort(): 返回服務器接受此請求所用的端口號
- String getCharacterEncoding(): 返回字符編碼的方式
- void setCharacterEncoding(): 設置請求的字符編碼方式
- int getContentLength(): 返回請求體的長度(以字節數)
- String getRemoteAddr(): 返回發送此請求的客戶端IP地址
- String getRealPath(String path): 返回一虛擬路徑的真實路徑
- String request.getContextPath(): 返回上下文路徑
創建一個簡單用戶註冊表單: login.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> <form name="loginForm" action="request.jsp" method="post"> 用戶名:<input type="text" name="username"><br> 愛好:<input type="checkbox" name="favorite" value="reading">閱讀 <input type="checkbox" name="favorite" value="singing">唱歌 <input type="checkbox" name="favorite" value="basketball">籃球 <input type="checkbox" name="favorite" value="swimming">遊泳<br> <input type="submit" value="提交"> </form> </body> </html>
創建一個處理數據的 request.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> <% request.setCharacterEncoding("utf-8"); // 解決中文亂碼問題 %> 用戶名:<%=request.getParameter("username") %><br> 愛好:<% String[] favorites = request.getParameterValues("favorite"); for (String favorite:favorites) { out.println(favorite); } %> </body> </html>
頁面展示效果如圖:
現在查看下通過a鏈接跳轉頁面,不走form表單提交的情況,把login.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> <form name="loginForm" action="request.jsp" method="post"> 用戶名:<input type="text" name="username"><br> 愛好:<input type="checkbox" name="favorite" value="reading">閱讀 <input type="checkbox" name="favorite" value="singing">唱歌 <input type="checkbox" name="favorite" value="basketball">籃球 <input type="checkbox" name="favorite" value="swimming">遊泳<br> <input type="submit" value="提交"> </form> <a href="request.jsp?username=Kobe">測試URL傳參數</a> </body> </html>
由於a鏈接的帶參參數中只測試username,所以favorite為空的情況下會報錯的,要對request.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> <% request.setCharacterEncoding("utf-8"); // 解決中文亂碼問題 %> 用戶名:<%=request.getParameter("username") %><br> 愛好:<% if (request.getParameterValues("favorite") != null) { String[] favorites = request.getParameterValues("favorite"); for (String favorite:favorites) { out.println(favorite + " "); } } %> </body> </html>
查看頁面運行效果:
但是當 a 鏈接參數中傳參為中文時就會出現亂碼
雖然通過request.setCharacterEncoding() 為 utf-8,但是僅限於 request 作用域。要解決 url 中文亂碼問題,就要修改tomcat 的server.xml了
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> ----> 增加 URIEncoding屬性 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8" />
右鍵刪除 eclipse 控制臺 server下的服務器,重新啟動 Tomcat 服務器後,再次運行:
接下來測試其它的request方法:
<%@ 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> <% request.setCharacterEncoding("utf-8"); // 解決中文亂碼問題 request.setAttribute("password", "123456"); %> 用戶名:<%=request.getParameter("username") %><br> 愛好:<% if (request.getParameterValues("favorite") != null) { String[] favorites = request.getParameterValues("favorite"); for (String favorite:favorites) { out.println(favorite + " "); } } %><br> 密碼:<%=request.getAttribute("password") %><br> MIME類型:<%=request.getContentType() %><br> 協議類型及版本號:<%=request.getProtocol() %><br> 服務器主機名:<%=request.getServerName() %><br> 端口號:<%=request.getServerPort() %><br> 字符編碼方式:<%=request.getCharacterEncoding() %><br> 請求體長度:<%=request.getContentLength() %>bytes<br> 客戶端IP地址:<%=request.getRemoteAddr() %><br> 虛擬路徑的真實路徑:<%=request.getRealPath("request.jsp") %><br> 上下文路徑:<%=request.getContextPath() %> </body> </html>
頁面輸出結果:
response 對象
response對象包含了響應客戶請求的相關信息,但在JSP 中很少直接用到它,它是HTTPServletResponse 類的實例。
response對象具有頁面作用域,即訪問一個頁面時,該頁面內的response對象只能對這次訪問有效,其它頁面的response對象對當前頁面無效。
常用方法:
- String getCharacterEncoding(): 返回響應的是何種字符編碼方式
- void setContentType(String type): 設置響應的MIME 類型
- PrintWriter getWriter(): 返回可以向客戶端輸出字符的一個對象(註意比較:PrintWriter 與內置out對象的區別)
- sendRedirect(java.lang.String location): 重新定向客戶端的請求
<%@ page language="java" import="java.io.*" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <% response.setContentType("text/html; charset=utf-8"); // 設置響應的MIME類型 out.println("<h1>response 內置對象</h1>"); out.println("<hr>"); PrintWriter outer = response.getWriter(); // 獲得輸出流對象 outer.println("看看我的位置在哪裏"); %>
向客戶端輸出字符串對象,printWriter 輸出總是提前於 jspWriter 的內置 out 對象
如果想讓讓 jspWriter 優於 printWriter 向客戶端輸出字符串對象,可以使用 out.flush() 方法,flush的作用是強制把前面的內容輸入
<%@ page language="java" import="java.io.*" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <% response.setContentType("text/html; charset=utf-8"); // 設置響應的MIME類型 out.println("<h1>response 內置對象</h1>"); out.println("<hr>"); out.flush(); // 註意看頁面字符串的先後順序 PrintWriter outer = response.getWriter(); // 獲得輸出流對象 outer.println("看看我的位置在哪裏"); %>
註意與上面對比頁面字符串的輸出順序:
再來看下重定向方法:
<%@ page language="java" import="java.io.*" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <% response.setContentType("text/html; charset=utf-8"); // 設置響應的MIME類型 out.println("<h1>response 內置對象</h1>"); out.println("<hr>"); PrintWriter outer = response.getWriter(); // 獲得輸出流對象 outer.println("看看我的位置在哪裏"); response.sendRedirect("login.jsp"); // 請求重定向 %>
頁面跳轉了:
請求重定向 和 請求轉發的區別
請求重定向:
- 客戶端行為
- response.sendRedirect()
- 從本質上講,等同於兩次請求,前一次的請求對象不會保存,地址欄的URL地址會改變
請求轉發:
- 服務器行為
- request.getRequestDispatcher().forward(req, res)
- 是一次請求,轉發後請求對象會保存,地址欄的URL地址不會發生改變
JSP 內置對象(上)