Web小結---Servlet,JSP,過濾器和監聽器,四個作用域和九個內建物件,EL表示式語言,自定義標籤,JSTL,國際化與漢字的編碼

fightplane發表於2007-08-21

一 Servlet
1、Servlet、ServletConfig:前者對應一個Servlet類,後者對應的是在web.xml中的配置資訊
(1)Servlet:
init(ServletConfig):只再類載入並例項化後會被呼叫一次。
service(ServletRequest,ServletResponse):會被呼叫多次
destroy():只有一次
getServletConfig()
getServletInfo()
(2)ServletCionfig
getServletName()
getInitParameter(String):---<servlet><init-param></init-param></servlet>
getInitParameterNames():
getServletContext
注意ServletContext中也有getInitParameter(String),它對應的是:<context-param>中巢狀的元素
這個<context-param>和<servlet>標籤是同級別的,初始化的是整個應用程式

2、兩個類:
GenericServlet/HttpServlet:
GenericServlet實現Servlet和ServletConfig,HttpServlet繼承自GenericServlet,而且它是和HTTP協議相關的。
(1)GenericServlet:具有一個無參的init方法,方便子類的覆蓋。
(2)HttpServlet:具有兩個service方法,並且有7個do方法。重寫的時候一般重寫do方法

3、Servlet配置
指的是web.xml中的資訊,
<servlet>
 <servlet-name></servlet-name>
 <servlet-class></servlet-class>
 <init-param></init-param>
</servlet>
//上面的配置對應的可以說就是ServletConfig中的東西
<servlet-mapping>
 <servlet-name></servlet-name>
 <url-pattern></url-pattern>
</servlet-mapping>

4、WEB應用程式資料夾的結構
--WEB-INF
  |
  |------------web.xml
  |------------lib資料夾      JAR檔案
  |------------classes       類檔案
  |------------tags          TagFile標籤檔案
--靜態資源與JSP檔案

5、請求和響應:
(1)請求ServletRequest->HttpServletRequest
getParameter(String)、
getHeader()、
getParameterValues(String)、用於核取方塊
getParameterNames、
getRemoteAddr、得到遠端地址
getLocalAddr、得到本地地址
getLocale、得到本地化資訊
getSession/getCookies
getRequestDispatcher

(2)響應ServletResponse->HttpServletResponse
sendRedirect
sendError
setHeader/addHeader/setIntHeader
getWriter/getOutputStream :這兩個方法絕對不可以同時被呼叫!!!!!
setContentType/setCharacterEncoding

6、請求的轉發和響應的重定向之間的區別要搞清楚
(1)轉發:
A、三種轉發的方法:
RequestDispatcher.forward/include
<jsp:include>
<jsp:forward> 等價於RequestDispatcher.forward();return;
也就是說使用RequestDispatcher.forward()後,下面的程式碼仍然要執行,但是<jsp:forward>執行後,下面的程式碼就不執行了。
pageContext.forward/include
B、如何得到RequestDispatcher:
request.getRequestDispatcher
ServletContext.getRequestDispatcher

RequestDispatcher的請求轉發、Jsp頁面中指令元素include、以及ServletContext中的getResourceAsStream(String path)
(用來讀出資料夾中的路徑資源)都可以訪問WEB-INF資料夾,
比如為了防止使用者訪問一些受保護的頁面(比如控制器Servlet),把它們放到WEB-INF中去,請求轉發的時候可以去訪問。
有的時候需要讀取WEB-INF中的一些配置資源,需要ServletContext中的getResourceAsStream方法。
而且有的網站的各個頁面具有相同的頭圖片和尾圖片,這些東東就可以放到WEB-INF資料夾中用page元素的include指令來包含進來。

注意如果使用ServletContext的RequestDispatcher,要從A應用程式轉發請求到B,必須設定A的crossContext值為true!

(2)重定向
response.sendRedirect:比如在註冊結束後轉到下一個頁面的時候,一定要使用重定向改變瀏覽器的URL地址!
請求的轉發不可能脫離Tomcat伺服器的範圍,如果想要脫離本伺服器的話,只能通過響應重定向的方式。重定向要生成一個臨時的響應,(響應
一旦生成請求就結束了)瀏覽器接到這個臨時的響應後不顯示任何東西而是傳送請求去找新的地址。


二、JSP
1、模板和元素:
對於JSP來說,它是不可執行的,必須翻譯成Servlet才能執行,必須要容器特殊處理的叫做元素,
直接列印到輸出流中去的是模板

元素分為以下幾種:
1指令碼元素
2指令元素
3動作元素

1指令碼元素:
(1)指令碼片斷:翻譯後原封不動的放到service方法裡面
(2)指令碼宣告:放在類裡面,但是是在service方法外面,
(3)指令碼表示式:原封不動的放到out.print裡面去,指令碼表示式不可以加分號。

內建物件絕對不可以在指令碼宣告中去用!因為它們的作用是在service方法裡面的。

2指令元素:
Page指令:
include指令<%@include file=""%>,包含的這個檔案一定是按照純文字的格式去讀取,讀取檔案的時候就有編碼的問題,這時候就是pageEncoding
的設定問題了。
taglib指令

3頁面亂碼:pageEncoding/contentType
前者設定jsp頁面讀取的形式,後者設定一個響應的報頭,告訴瀏覽器以什麼編碼格式去顯示
如果沒有設定pageEncoding而是隻設定了contentType的話,那麼pageEncoding要受contentType影響,反之亦然。
也就是兩者只設一者的話都會按照一個編碼去顯示!

無論請求還是響應,遞交的時候預設都是按照iso-8859-1去解碼的。一定要保證讀寫和顯示時候的編碼都是一致的

4 動作元素:
<jsp:useBean>:主要作用:開放一個指令碼變數並且向作用域裡面存一個屬性
<jsp:setProperty>
<jsp:getProperty>
<jsp:forward>
<jsp:include>
<jsp:param>
前六個比較重要!
<jsp:invoke>
<jsp:doBody>
<jsp:plugin>
<jsp:fallback>
<jsp:params>

三、過濾器和監聽器
1、Filter/FilterConfig
init(FilterConfig)
doFilter(ServletRequest,ServletResponse,FilterChain)
destroy()

<filter>
 <filter-name>
 <filter-class>
</filter>

<filter-mapping>
 <filter-name>
 <url-pattern>|<servlet-name>
</filter-mapping>

url-pattern相同的過濾器處於一個過濾器鏈上,執行的順序完全按照web.xml中的先後順序進行。

2、監聽器->ServletContext/HttpSession/ServletRequest
(1)生命週期
ServletContextListener:初始化(從BBS中讀取全部討論區並儲存在應用程式的作用域中或是將全部封殺的IP讀出來儲存)和銷燬
HttpSessionListener/HttpSessionActivationListener
ServletRequestListener
(2)屬性的增刪改
一般是AttributeListener去作的
<listener>
 <listener-class>包名.類名</listener-class>
</listener>

四、四個作用域和九個內建物件
1、頁面作用域對應的是pageContext,而不是page
2、內建物件:
pageContext/request/session/application
out->是JspWriter的例項,它有快取,而PrintWriter沒有快取,在頁面結束的時候一定會通過響應生成PrintWriter去寫出快取的內容!
  如果快取滿了的話,要看:如果<%@page autoFlush="true"%>,則會自動重新整理,如果是false,會丟擲異常的!response.getWriter()
  返回的是PrintWriter,不是JspWriter。
exception->isErrorPage=true的時候才有用
session:兩種跟蹤機制:一種是通過客戶端的cookie儲存,另外一種是將sessionId存在伺服器端,
config->ServletConfig
page->Object->this
response:

五、EL表示式語言:
${}
1、常量、函式、變數的表示式
2、變數是儲存在某一作用域中的同名的屬性值
3、函式是在tld檔案中宣告的引用一個類的公共且靜態的方法
4、11個內建物件
(1)作用域:pageScope/requestScope/sessionScope/applicationScope
(2)和頁面通訊:pageContext
(3)請求引數的:param/paramValues
(4)報頭:header/headerValues
(5)Cookies/initParam ---<context-param>
5、點操作符和[]操作符和empty
對javaBean,是呼叫getter方法,
對map,是呼叫get(Object)方法,
對作用域,是呼叫getAttribute(String)
對pageContext,也是呼叫getter方法,可以得到所有的內建物件
對param,是去取得引數
對header,是去拿報頭
對initParam,是去拿初始化引數
[]操作符主要是針對陣列


六 自定義標籤
1、Tag介面(傳統介面系列)

JspTag
(1)Tag : doStartTag(返回值是SKIP_BODY/EVAL_BODY_INCLUDE)/doEndTag(返回SKIP_PAGE或是EVAL_PAGE)
(2)IterationTag->TagSupport
doAfterBody:EVAL_BODY_AGAIN/SKIP_BODY
(3)BodyTag->BodyTagSupport
doInitBody
doAfterBody:EVAL_BODY_BUFFERED->BodyContent:pageContext裡面有一個pushBody,用來將體包起來,這時候再用getOut方法得到
的不再是JspWriter了,而是bodyContent了。BodyContent的生成是呼叫了pushBody方法,這裡面又涉及一個getEnclosingWriter(),它
是BodyContent的一個方法,可以得到它裡面包的輸出流JspWriter,但是要注意要是進行了一次以上的pushBody但是沒有進行popBody的話,那麼
拿出來的就是裡面包的BodyContent了,但是由於BodyContent是JspWriter的子類,所以也是符合方法宣告的


2、SimpleTag介面(簡單介面系列)
setJspContext()
setParent()
setJspBody(JspFragment) 注意JspFragment是標籤體,裡面絕對不可以有指令碼元素的!註冊的時候content元素中要麼設定為empty,
要麼設定為scriptless,也就是簡單標籤的標籤體是不可以有指令碼元素的!
doTag()

JspFragment.invoke(null):直接弄到輸出流中去
JspFragment.invoke(StringWriter out):將輸出流弄到StringWriter中去,然後呼叫out.toString可以將體變成字串的形式

3、Tag File標籤檔案
.tag
可以放在/WEB-INF/tags裡面或者/META-INF/tags裡面也可以
至於標籤檔案的tld可以放在WEB-INF中也可以放在META-INF中去,都是沒有問題的
標籤檔案描述的是標籤處理類,jsp描述的是Servlet,二者都是不可執行的,注意標籤檔案中有<%@tag%>,裡面可以設定不少標籤的屬性
還有<%@attribute %>,<%@taglib%>和<%@include%>也可以用,屬性可以是JspFragment

比如:<my:first>
  <jsp:attribute>
  </jsp:attribute>
  <jsp:body>
  </jsp:body>
  </my:first>

<jsp:invoke name=var>運算結果就放在了var裡面
<jsp:doBody>  處理體

七、JSTL
一共5個庫,我們說了core、sql、i18n、fn標記庫(就是表示式語言的函式庫)
我們沒有講xml的標籤庫

八、國際化與漢字的編碼
ResourceBundle
兩種形式:
1、ListResourceBundle
2、寫一個Properties檔案,裡面有一個nativetoacsii命令進行,參照前面的筆記轉碼
基名和副檔名:起名字都是要有標準的
Locale:本地化物件
getBundle方法可以通過傳入基名和本地化物件來處理
<fmt:bundle>
<fmt:setBundle>
<fmt:message>
漢字編碼:GB2312/GB13000(GBK)/GB18030
Unicode UCS/UTF-8 

相關文章