標籤:
JSP內建對象
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運算式的底層實現原理。
java學習筆記—JSP3(34)