JSP在進行編譯的時候動態的創建了很多的內置對象,那么如果開發者知道,可以直接在JSP頁面中使用這些對象。我們將這些內置的對象稱之為JSP內置九大對象。
如果需要將以下的九大內置對象直接獲取出來,那么可以這樣做:
編寫一個錯誤處理頁面,那么請求查看翻譯好的jsp文件。
public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { PageContext pageContext = null; Httpsession session = null; Throwable exception = org.apache.jasper.runtime.JsPRuntimeLibrary.getThrowable(request); if (exception != null) { response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null; ......}
因為在JSP中編寫JSP腳本以及JSP輸出表達式都會默認翻譯在_jspService()那么以上該方法中定義的九大對象開發者可以任意使用。
JSP九大對象 | Servlet類型 |
request | HttpServletRequest |
response | HttpServletResponse |
session | HttpSession |
config | ServletConfig |
application | ServletContext |
out | JspWriter |
page | Object |
pageContext | PageContext |
exception | Throwable |
1 out對象
同時使用out和response的輸出字符流給頁面輸出數據。
<% out.write("jack<br/>"); response.getWriter().write("lucy<br/>");%>
輸出結果是lucy jack。因為以上兩個都是字符流且帶有自己的緩沖區,因此JSPWriiter的緩沖區數據在JSP執行完畢之后才將數據刷新給Response字符流的緩沖區,因此out對象輸出的數據在后面。如果需要提前輸出,那么需要進行緩沖區數據的強行刷新。
<% out.write("jack<br/>"); out.flush(); response.getWriter().write("lucy<br/>");%>
2 使用JspWriiter和response的字節流同時輸出數據。
<% out.write("jack<br/>"); out.flush(); response.getOutputStream().write("lucy<br/>".getBytes());%>
以上代碼運行結果是jack然后拋出異常getWriter() has already been called for this response。在JSP中不能同時使用字節流和字符流。
3. 如何使用JSP實現圖片的下載。
<%@ page language="java" import="java.util.*,java.io.*" pageEncoding="UTF-8"%><% // 獲取圖片資源 InputStream in = application.getResourceAsStream("/imgs/0004.jpg"); // 指定處理方式 response.setHeader("content-disposition","attachment;filename=0004.jpg"); // 獲取字節輸出流 byte [] b = new byte[1024]; int len = 0; // 邊讀邊寫 OutputStream output = response.getOutputStream(); while((len = in.read(b)) != -1){ output.write(b,0,len); } // 釋放資源 in.close();%>
為了避免頁面JSP中使用out對象,那么需要將JSP的所有的模板元素全部刪除掉包括頁面中的回車和換行。
4. 使用out隱含對象的write方法和println方法。
<% String str1 = "data"; String str2 = null; int a = 65; out.write(str1);// data out.write(str2);// 不顯示 out.write(a);// A out.write("<hr/>"); out.println(str1);// data out.println(str2);// null out.println(a);// 65%>
二 pageContext對象
PageContext類主要的描述的是的JSP頁面的上下文環境,可以獲取servlet的信息、也可以將當前JSP的上下文環境傳遞給指定的類實現對JSP頁面的操作。
1. 獲取JSP中所有的數據
<% out.write( (pageContext.getRequest() == request ) + "<br/>");out.write( (pageContext.getResponse() == response ) + "<br/>");out.write( (pageContext.getSession() == session ) + "<br/>");out.write( (pageContext.getServletConfig() == config ) + "<br/>");out.write( (pageContext.getServletContext() == application ) + "<br/>");out.write( (pageContext.getPage() == page ) + "<br/>");out.write( (pageContext.getException() == exception ) + "<br/>");out.write( (pageContext.getOut() == out ) + "<br/>");%>
思考:為什么SUN需要將其他八大對象通過pageContext也要進行獲???
因為以后如果需要一個普通的java類來處理JSP頁面數據那么直接將PageContext類傳遞過去即可。如:自定義標簽。
2. 常見的域
我們將可以使用setAttribvute()/getAttribute()方法存儲和獲取數據的對象稱之為域對象。
域對象 | 生命周期 |
page | 在當前頁面中有效 |
request | 請求轉發 |
session | 默認半小時 |
application | 服務器關閉的時候 |
3. 設置和獲取不同域屬性
<%-- 給不同的域對象設置屬性 --%><% pageContext.setAttribute("page","this is current page"); pageContext.setAttribute("name","lucy",PageContext.REQUEST_SCOPE);pageContext.setAttribute("age","38",PageContext.SESSION_SCOPE);String likes[] = {"football","sleep","basketball"}; pageContext.setAttribute("likes",likes,PageContext.APPLICATION_SCOPE);%><%-- 獲取域屬性 --%><%= pageContext.getAttribute("page") %><br/><%= pageContext.getAttribute("name",PageContext.REQUEST_SCOPE) %><br/><%= pageContext.getAttribute("age",PageContext.SESSION_SCOPE) %><br/><%= Arrays.toString( (String[])pageContext.getAttribute("likes",PageContext.APPLICATION_SCOPE) ) %><br/>
總結:
使用pageContext設置和獲取域屬性的時候可以顯示的指定域,如果沒有指定域,那么默認該域是page域。
問題:
在實際的開發中設置屬性和獲取屬性是分別由不同的程序員開發的程序,那么如果在獲取的時候開發者不明確這樣的屬性名到底存儲在哪一個域中,那么應該怎么辦?
解決方案:可以使用以下語句
<%= pageContext.findAttribute("test") %>
該語句默認從pageàrequestàsessionàapplication逐個查找需要的屬性,如果找到直接返回。
因此該語句就是EL表達式的底層實現原理。
新聞熱點
疑難解答