java web複習 day08(jsp)

        過幾天要回家去筆試了,真緊張,這幾天不知道是複習java ee還是好好在牛客網上刷一下面試題。還是要趕緊做出打算了。

        day08主要講了jsp的應用,jsp全稱爲java server page,也是一種開發動態web資源的工具,從某種角度來說它也是servlet,但是這種技術主要用來展示數據,操作數據還是得用servlet。

一.入門

         視頻課上寫了一個顯示當前日期時間的jsp頁面作爲入門程序。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>My JSP '1.jsp' starting page</title>
  </head>
  
  <body>
    	<%
    		Date date = new Date();
    		out.write(date.toLocaleString());
    	 %>
  </body>
</html>

        上方代碼表現了jsp中內嵌java代碼的格式,即<%%>中添加代碼,細心的朋友可能發現不像在servlet中那樣,需要response去獲取writer,在jsp中直接調用了,這個問題我們等等再解答。

二.jsp腳本片段與腳本表達式

            

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>
  
  <body>
 		<%
 			int i=1;
 		 %>
 		 
 		 <%=i%>
 		 
 		 <!-- JSP引擎在翻譯腳本表達式時,會將程序數據轉成字符串,然後在相應位置用out.print(…) 將數據輸給客戶端 --> 
 		 <br/><br/><br/>	
 		 <%
 		 	for(int j=0;j<5;j++){
 		  %>
 		  <%=j %>
 		  <%} %>
 		  <%-- jsp內必須爲完整java代碼 --%>
  </body>
</html>

注意以下幾點:

1.JSP腳本片段中只能有java代碼,不能出現其他模板元素

2.一個JSP中可以有多個腳本片段,多個腳本片段的代碼可以互相訪問

3.單個腳本片段中的代碼可以是不完整的,但是所有腳本塊組合起來必須>是完整的

4. JSP頁面中編寫的所有代碼,默認會翻譯到servlet的service方法中, 而Jsp聲明中的java代碼被翻譯到_jspService方法的外面。語法:
<%!
    java代碼

%>

5.JSP中有兩種註釋,第一種是html中的註釋<!--註釋內容-->,第二種是JSP的註釋<%--註釋內容--%>,前者會被翻譯到servlet中去,後者直接被無視。

三.JSP指令

JSP指令是爲JSP引擎而設計的,它們並不直接產生任何可見輸出,而只是告訴引擎如何處理JSP頁面中的其餘部分。

JSP指令的基本語法格式:
    <%@ 指令 屬性名="值" %>
    舉例:<%@ page contentType="text/html;charset=gb2312"%>

JSP有三大指令page,include,taglib.

1.page

page指令用於定義JSP頁面的各種屬性,無論page指令出現在JSP頁面中的什麼地方,它作用的都是整個JSP頁面,爲了保持程序的可讀性和遵循良好的編程習慣,page指令最好是放在整個JSP頁面的起始位置。

其中黑體是比較重要的。

例1:通過errorPage與isErrorPage來彈出友好錯誤界面

1.比如出現運行時錯誤

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" session="false" errorPage="/errors.jsp"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
  </head>
  
  <body>
    	<%
    		int x = 1 / 0;
    	 %>
  </body>
</html>

在page指令中寫這個  errorPage="/errors.jsp,即可在發生錯誤時,轉到錯誤界面。

2.如果出現某種特定錯誤,可在web.xml中設置(這裏以算數錯誤爲例)

 <error-page>
      <exception-type>java.lang.ArithmeticException</exception-type>
      <location>/errors.jsp</location>
  </error-page>

在errors.jsp的page中要聲明isErrorPage="true"

如果是應對錯誤碼應該這樣設置:

  <error-page>
  	<error-code>404</error-code>
  	<location>/errors/404.jsp</location>
  </error-page>

解決中文亂碼問題:

設置:

pageEncoding="UTF-8"或

contentType="text/html; charset=UTF-8"

2.include

include指令用於引入其它JSP頁面,如果使用include指令引入了其它JSP頁面,那麼JSP引擎將把這兩個JSP翻譯成一個servlet。所以include指令引入通常也稱之爲靜態引入。

語法:
    <%@ include file="relativeURL"%>

細節:
被引入的文件必須遵循JSP語法。
被引入的文件可以使用任意的擴展名,即使其擴展名是html,JSP引擎也會按照處理jsp頁面的方式處理它裏面的內容,爲了見明知意,JSP規範建議使用.jspf(JSP fragments)作爲靜態引入文件的擴展名。
由於使用include指令將會涉及到2個JSP頁面,並會把2個JSP翻譯成一個servlet,所以這2個JSP頁面的指令不能衝突(除了pageEncoding和導包除外)。

例:

<body>
   	
  	<%@include file="/public/head.jsp" %>
  
    <br>當前頁面內容. <br>
    
    <%@include file="/public/foot.jsp" %>

3.taglib

過幾天更新自定義標籤的時候補上。



四.JSP九大隱式對象

     分別爲response,request,application,config,session,page,exception,out,pageContext

其中,out和pageContext比較特殊。

1.out

    out隱式對象用於向客戶端發送文本數據。

    out對象是通過調用pageContext對象的getOut方法返回的,其作用和用法與ServletResponse.getWriter方法返回的PrintWriter對象非常相似。

    JSP頁面中的out隱式對象的類型爲JspWriter,JspWriter相當於一種帶緩存功能的PrintWriter,設置JSP頁面的page指令的buffer屬性可以調整它的緩存大小,甚至關閉它的緩存。

    只有向out對象中寫入了內容,且滿足如下任何一個條件時,out對象纔去調用ServletResponse.getWriter方法,並通過該方法返回的PrintWriter對象

將out對象的緩衝區中的內容真正寫入到Servlet引擎提供的緩衝區中:
設置page指令的buffer屬性關閉了out對象的緩存功能
out對象的緩衝區已滿

整個JSP頁面結束

當同時使用response.getWriter()和out時,out所輸出的在前面。原因如圖:

使用jsp進行下載

<%@page import="java.io.OutputStream"%><%@page import="java.io.FileInputStream"%><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%
    		
    		String path = application.getRealPath("/1.jpg");
    		String fileName = path.substring(path.lastIndexOf("\\")+1);
    		
    		response.setHeader("content-disposition", "attachment;filename="+fileName);
    		
    		FileInputStream in = new FileInputStream(path);
    		
    		int len = 0;
    		byte buffer[] = new byte[1024];
    		
    		OutputStream sout = response.getOutputStream();
    		
    		while((len=in.read(buffer))>0){
    			sout.write(buffer, 0, len);
    		}
    	 

在這裏有一個問題,java.lang.IllegalStateException: getOutputStream() has already been called for this response這個錯誤會在out隱式對象生成時發生,如果想不生成out隱式對象,可以把空格全部刪掉。

2.pageContext

pageContext對象是JSP技術中最重要的一個對象,它代表JSP頁面的運行環境,這個對象不僅封裝了對其它8大隱式對象的引用,它自身還是一個域對象,可以用來保存數據。並且,這個對象還封裝了web開發中經常涉及到的一些常用操作,例如引入和跳轉其它資源、檢索其它域對象中的屬性等。
(1)getException方法返回exception隱式對象
(2)getPage方法返回page隱式對象
(3)getRequest方法返回request隱式對象
(4)getResponse方法返回response隱式對象
(5)getServletConfig方法返回config隱式對象
(6)getServletContext方法返回application隱式對象
(7)getSession方法返回session隱式對象
(8)getOut方法返回out隱式對象

例:在其他域設置屬性,取屬性

<body>
    
    <% 
    	pageContext.setAttribute("data","xxx2",PageContext.SESSION_SCOPE);
    	
    	
    	//String data = (String)session.getAttribute("data");
    	
    	//String data = (String)pageContext.getAttribute("data",PageContext.SESSION_SCOPE);
    	
    	String data = (String)pageContext.findAttribute("data");  //pageContext  request  session  servletContext
    	
    %>
    
    <%=data %>
    
    
  </body>
pageContext對象的方法
public void setAttribute(java.lang.String name,java.lang.Object value)
public java.lang.Object getAttribute(java.lang.String name)

public void removeAttribute(java.lang.String name)

pageContext對象中還封裝了訪問其它域的方法
public java.lang.Object getAttribute(java.lang.String name,int scope)
public void setAttribute(java.lang.String name, java.lang.Object value,int scope)

public void removeAttribute(java.lang.String name,int scope)

代表各個域的常量
PageContext.APPLICATION_SCOPE
PageContext.SESSION_SCOPE
PageContext.REQUEST_SCOPE
PageContext.PAGE_SCOPE


跳轉到其他界面:

pageContext.forward(url)

五.標籤

JSP標籤也稱之爲Jsp Action(JSP動作)元素,它用於在Jsp頁面中提供業務邏輯功能,避免在JSP頁面中直接編寫java代碼,造成jsp頁面難以維護。


<jsp:include>標籤用於把另外一個資源的輸出內容插入進當前JSP頁面的輸出內容之中,這種在JSP頁面執行時的引入方式稱之爲動態引入。

語法:

    <jsp:include page="relativeURL | <%=expression%>" flush="true|false" />

page屬性用於指定被引入資源的相對路徑,它也可以通過執行一個表達式來獲得。

flush屬性指定在插入其他資源的輸出內容時,是否先將當前JSP頁面的已輸出的內容刷新到客戶端。  


<jsp:include>與include指令的比較

<jsp:include>標籤是動態引入, <jsp:include>標籤涉及到的2個JSP頁面會被翻譯成2個servlet,這2個servlet的內容在執行時進行合併。
而include指令是靜態引入,涉及到的2個JSP頁面會被翻譯成一個servlet,其內容是在源文件級別進行合併。
不管是<jsp:include>標籤,還是include指令,它們都會把兩個JSP頁面內容合併輸出,所以這兩個頁面不要出現重複的HTML全局架構標籤,否則輸出給客戶端的內容將會是一個格式混亂的HTML文檔。

<jsp:forward>標籤用於把請求轉發給另外一個資源。
語法:
    <jsp:forward page="relativeURL | <%=expression%>" />
page屬性用於指定請求轉發到的資源的相對路徑,它也可以通過執行一個表達式來獲得。

當使用<jsp:include>和<jsp:forward>標籤引入或將請求轉發給其它資源時,可以使用<jsp:param>標籤向這個資源傳遞參數。
語法1:
    <jsp:include page="relativeURL | <%=expression%>">
        <jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
    </jsp:include>
語法2:
    <jsp:forward page="relativeURL | <%=expression%>">
        <jsp:param name="parameterName" value="parameterValue|<%= expression %>" />

    </jsp:include>


<jsp:param>標籤的name屬性用於指定參數名,value屬性用於指定參數值。在<jsp:include>和<jsp:forward>標籤中可以使用多個<jsp:param>標籤來傳遞多個參數。


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP '7.jsp' starting page</title>
  </head>
  
  <body>
    
    
    <jsp:include page="/public/head.jsp"/> 
    
   	<br/> 這是頁面內容 	<br/> 
    
    <jsp:include page="/public/foot.jsp"/>
    
    <% 
    	String url = "/public/head.jsp";
    %>
    
    <jsp:include page="<%=url %>"/>
    
    <jsp:forward page="/1.jsp">
    	<jsp:param name="xxx" value="yyyy"/>
    </jsp:forward>
    
  </body>
</html>

六.幾種域的差別

1、request:如果客戶向服務器發請求,產生的數據,用戶看完就沒用了,像這樣的數據就存在request域,像新聞數據,屬於用戶看完就沒用的
2、session:如果客戶向服務器發請求,產生的數據,用戶用完了等一會兒還有用,像這樣的數據就存在session域中,像購物數據,用戶需要看到自己購物信息,並且等一會兒,還要用這個購物數據結帳
3、servletContext:如果客戶向服務器發請求,產生的數據,用戶用完了,還要給其它用戶用,像這樣的數據就存在servletContext域中,像聊天數據







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章