javascript
《Head First Servlets JSP(中文版)》书摘
這本書不錯(cuò),正在看。
文章轉(zhuǎn)自:http://gemini.iteye.com/blog/81613
一直覺得自己Servlet的基礎(chǔ)還有待加強(qiáng),所以利用5.1七天假搞了本《Head First Servlets & JSP(中文版)》重新補(bǔ)一下基礎(chǔ),看的過程中摘錄了一些知識點(diǎn),羅列如下(括號中為知識點(diǎn)所在的頁號):
第4章 作為servlet:請求和響應(yīng)
★ 每個(gè)請求都在一個(gè)單獨(dú)的線程中運(yùn)行!
?? 容器運(yùn)行多個(gè)線程來處理對一個(gè)servlet的多個(gè)請求。
?? 對應(yīng)每個(gè)客戶請求,容器會(huì)生成一對新的HttpServletRequest和HttpServletResponse對象。
?? 任何特定servlet類都只有一個(gè)實(shí)例。(101)
★ 不要在servlet的構(gòu)造方法中放任何東西!
?? 初始化工作應(yīng)放在init()方法中。
?? servlet的構(gòu)造方法只是讓它成為一個(gè)普通的對象,容器調(diào)用它的init()方法后,它才成為了一個(gè)servlet。
?? init()方法使servlet可以訪問ServletConfig和ServletContext對象。(103)
★ 每個(gè)servlet有一個(gè)ServletConfig對象,每個(gè)Web應(yīng)用有一個(gè)ServletContext。(104)
★ HttpServletRequest和HttpServletResponse接口由容器來實(shí)現(xiàn)。
?? 具體怎么實(shí)現(xiàn)的不用我們操心。(107)
★ HTTP請求方法確定究竟是運(yùn)行doGet()還是doPost()。
?? 客戶的請求總是包括一個(gè)特定的HTTP方法。如果這個(gè)HTTP方法是GET,service()方法就會(huì)調(diào)用doGet()。如果這個(gè)HTTP方法是POST,service()方法就會(huì)調(diào)用doPost()。
?? 當(dāng)然,還有些其它的HTTP方法,包括HEAD、TRACE、OPTIONS、PUT、DELETE和CONNECT,但對于servlet開發(fā)人員,這些方法很少用到。(108)
★ GET和POST的區(qū)別除了有參數(shù)數(shù)據(jù)大小、安全性和書簽問題外,還有請求是否是冪等的問題。
?? GET請求本質(zhì)上講(根據(jù)HTTP規(guī)范)是冪等的。它們應(yīng)當(dāng)能多次而不會(huì)對服務(wù)器產(chǎn)生任何副作用。GET請求不應(yīng)該修改服務(wù)器上的任何東西,但是你也可以寫一個(gè)非冪等的doGet()方法(不過這是很糟糕的做法)。
?? POST本質(zhì)上講不是冪等的,所以要由你來適當(dāng)?shù)卦O(shè)計(jì)和編寫代碼,如果客戶錯(cuò)誤地把一個(gè)請求發(fā)送了兩次,你也能正確地加以處理。(111)
★ 表單的默認(rèn)方法是GET。(118)
★ HttpServletRequest的getServerPort()、getLocalPort()和getRemotePort()很容易搞混!
?? 如果是一個(gè)servlet請求,就意味著客戶是遠(yuǎn)程的,所以getRemotePort()是指“得到客戶的端口”。
?? getServerPort()說“請求原來發(fā)送到哪個(gè)端口?”,getLocalPort()則是說“請求最后發(fā)送到哪個(gè)端口?”。盡管請求要發(fā)送到一個(gè)端口(服務(wù)器所監(jiān)聽的端口),但是服務(wù)器會(huì)為每個(gè)線程找一個(gè)不同的本地端口。(123)
★ 對于輸出,你有兩個(gè)選擇:字符或者字節(jié)。
?? ServletResponse接口只提供了兩個(gè)可以選擇的流:ServletOutputStream用于輸出字節(jié),PrintWriter用于輸出字符數(shù)據(jù)。(132)
★ setHeader()和addHeader()的區(qū)別
?? 如果響應(yīng)中還沒有某個(gè)首部(方法的第一個(gè)參數(shù)),setHeader()和addHeader()就會(huì)增加一個(gè)首部和相應(yīng)的值。
?? 二者的區(qū)別是,如果有這樣一個(gè)首部,setHeader()會(huì)覆蓋現(xiàn)有的值,addHeader()會(huì)增加另外一個(gè)值(addHeader()的API DOC中提到:This method allows response headers to have multiple values)。(133)
?
第5章 作為Web應(yīng)用:屬性和監(jiān)聽者
★ 覆蓋init()方法
?? 容器調(diào)用的是init(ServletConfig)方法,而init(ServletConfig)方法會(huì)調(diào)用無參數(shù)的init()方法,所以如果需要覆蓋init()方法,只需覆蓋無參數(shù)的版本就行了。(151)
★ 要把初始化參數(shù)認(rèn)為是部署時(shí)常量!
?? 可以在運(yùn)行時(shí)得到這些初始化參數(shù),但是不能設(shè)置。根本沒有setInitParameter()。(160)
★ 上下文屬性和會(huì)話屬性都不是線程安全的。
?? 可以對上下文或會(huì)話同步來保護(hù)它們的屬性。
?? servlet的實(shí)例變量也不是線程安全的,所以一般servlet中不要放實(shí)例變量。
?? 只有請求屬性和servlet服務(wù)方法中的局部變量是線程安全的。(192-202)
★ 如果已經(jīng)提交了響應(yīng),就不能再轉(zhuǎn)發(fā)請求或重定向了!(205)
?
第6章 會(huì)話管理
★ 會(huì)話有3種死法:超時(shí);調(diào)用會(huì)話對象的invalidate()方法;應(yīng)用結(jié)束。
?? 在web.xml中指定超時(shí)是以分為單位,而在程序中調(diào)用會(huì)話對象的setMaxInactiveInterval()方法設(shè)置超時(shí)是以秒為單位!(243)
★ cookie.setMaxAge(-1)表示瀏覽器退出時(shí)cookie就會(huì)消失。
?? 而session.setMaxInactiveInterval(負(fù)數(shù))表示session永遠(yuǎn)不會(huì)到期。(249)
★ HttpSessionBindingListener不用在web.xml中注冊。
?? 如果一個(gè)類實(shí)現(xiàn)了HttpSessionBindingListener,當(dāng)這個(gè)類的一個(gè)實(shí)例增加到一個(gè)會(huì)話或從會(huì)話刪除時(shí),容器就會(huì)調(diào)用事件處理回調(diào)方法(valueBound()和valueUnbound())。(254)
★ 在分布式Web應(yīng)用中,除了HttpSession對象外,所有其它對象都會(huì)在另一個(gè)VM上復(fù)制!
?? 會(huì)話對象不會(huì)復(fù)制,而只是移動(dòng)。
?? 當(dāng)會(huì)話對象從一個(gè)VM移動(dòng)到另一個(gè)VM時(shí),如果某個(gè)會(huì)話屬性不是Serializable(或?qū)傩詫ο蟮哪硞€(gè)實(shí)例變量不是Serializable),可 以讓屬性對象類實(shí)現(xiàn)HttpSessionActivationListener,并使用激活/鈍化回調(diào)方法來解決會(huì)話屬性的串行化問題。 (255-258)
?
第7章 使用JSP
★ JSP元素:
?? scriptlet: <% %>??
?? 表達(dá)式:??? <%= %>
?? 聲明:????? <%! %>
?? 指令:????? <%@ %>
?? 注釋:????? <%-- --%>
?? 動(dòng)作:????? 標(biāo)準(zhǔn)動(dòng)作如<jsp:include>,其它動(dòng)作如<c:set>
?? EL表達(dá)式:? ${}???? (286,292,302,321)
★ JSP指令有3種:page、include和taglib。(285)
★ JSP隱式對象:
?????????? out --- JspWriter
?? pageContext --- PageContext (封裝了其它隱式對象,可以得到其它隱式對象的引用)
?????? request --- HttpServletRequest
????? response --- HttpServletResponse
?????? session --- HttpSession
?? application --- ServletContext
??????? config --- ServletConfig
???? exception --- JspException (只有指定為“錯(cuò)誤頁面”的頁面才能使用)
????????? page --- Object???? (296)
★ 容器將JSP轉(zhuǎn)換成一個(gè)servlet,這個(gè)servlet實(shí)現(xiàn)了HttpJspPage接口。
?? 這個(gè)servlet中有3個(gè)關(guān)鍵方法:
?? jspInit() -- 這個(gè)方法在servlet的init()方法中調(diào)用。可以覆蓋jspInit()。
?? jspDestroy() -- 這個(gè)方法在servlet的destroy()方法中調(diào)用。可以覆蓋jspDestroy()。
?? _jspService() -- 這個(gè)方法在servlet的service()方法中調(diào)用。不能覆蓋_jspService()。(303)
★ 在JSP頁面中禁用scriptlet或EL表達(dá)式:
?? 禁用scriptlet:在web.xml中設(shè)置<scripting-invalid>。
?? 禁用EL表達(dá)式:在web.xml中設(shè)置<el-ignored>或在JSP頁面中設(shè)置page指令的isELIgnored屬性。(319-320)
?
第8章 無腳本的JSP
★ EL隱式對象:
?? pageScope
?? requestScope
?? sessionScope
?? applicationScope?? (這4個(gè)是作用域?qū)傩缘腗ap)
?? param
?? paramValues??????? (這2個(gè)是請求參數(shù)的Map)
?? header
?? headerValues?????? (這2個(gè)是請求首部的Map)
?? cookie???????????? (cookie的Map)
?? initParam????????? (上下文初始化參數(shù)的Map)
?? pageContext??????? (pageContext對象的實(shí)際引用,不是Map)
?? 除了pageContext外,其它都是Map。(381)
★ EL運(yùn)算符和保留字:
?? 算術(shù)運(yùn)算符:
???? 加法:?? +
???? 減法:?? -
???? 乘法:?? *
???? 除法:?? /和div
???? 取模:?? %和mod
?? 邏輯運(yùn)算符:
???? 與:?? &&和and
???? 或:?? ||和or
???? 非:??? !和not
?? 關(guān)系運(yùn)算符:
???? 等于:???? ==和eq
???? 不等于:?? !=和ne
???? 小于:????? <和lt
???? 大于:????? >和gt
???? 小于等于: <=和le
???? 大于等于: >=和ge
?? 其它保留字:
???? true
???? false
???? null
???? instanceof
???? empty???? (392)
★ EL能妥善地處理null值
?? 如果找不到EL表達(dá)式中指定名的屬性/性質(zhì)/鍵,也會(huì)顯示頁面,而不會(huì)拋出異常。
?? 在算術(shù)表達(dá)式中,EL把null值看作是0。
?? 在邏輯表達(dá)式中,EL把null值看作是false。(395)
★ “[]”操作符比“.”操作符更強(qiáng)大
?? “.”的左邊只能是Map或bean,“[]”左邊除了可以是Map或bean外,還可以是List或數(shù)組;
?? “[]”里可以包含命名變量的表達(dá)式,而且可以做任意層次的嵌套,即如果中括號里的內(nèi)容沒有用引號引起來,容器就會(huì)進(jìn)行計(jì)算;
?? “[]”里的Map鍵可以是不遵循正常的Java命名規(guī)則的String,如包含點(diǎn)號的String。(370-376,396)
★ include指令在轉(zhuǎn)換時(shí)發(fā)生,<jsp:include>標(biāo)準(zhǔn)動(dòng)作在運(yùn)行時(shí)發(fā)生。(402)
?
第9章 使用JSTL
★ <c:set>有兩種不同的設(shè)置:var和target。
?? var“版本”用于設(shè)置作用域?qū)傩?#xff0c;target“版本”用于設(shè)置作用域?qū)傩缘淖侄位騇ap值。(445)
★ 容器會(huì)在4個(gè)位置查找TLD:
?? 直接在WEB-INF目錄中查找
?? 直接在WEB-INF的一個(gè)子目錄中查找
?? 在WEB-INF/lib下的JAR文件中的META-INF目錄中查找
?? 在WEB-INF/lib下的JAR文件中的META-INF目錄的子目錄中查找???? (476)
?
第10章 定制標(biāo)記開發(fā)
★ 容器會(huì)在4個(gè)位置查找.tag標(biāo)記文件:
?? 直接在WEB-INF/tags目錄中查找
?? 在WEB-INF/tags的子目錄中查找
?? 在WEB-INF/lib下的JAR文件的META-INF/tags目錄中查找
?? 在WEB-INF/lib下的JAR文件的META-INF/tags的子目錄中查找
?? 如果標(biāo)記文件部署在一個(gè)JAR中,這個(gè)標(biāo)記文件必須有一個(gè)TLD,相應(yīng)的TLD項(xiàng)只描述具體標(biāo)記文件的位置。(499)
?
第11章 Web應(yīng)用部署
★ 要成功地部署一個(gè)Web應(yīng)用,必須遵循以下目錄結(jié)構(gòu):
?? WEB-INF一定要直接放在應(yīng)用上下文之下;
?? classes目錄必須直接放在WEB-INF目錄中,classes目錄中必須是該類的包結(jié)構(gòu);
?? lib目錄要直接置于WEB-INF目錄下,JAR文件必須放在lib中;
?? META-INF目錄必須是JAR中的頂級目錄;
?? 不在JAR中的TLD必須放在WEB-INF下的某個(gè)位置,JAR中的TLD文件要放在META-INF目錄下的某個(gè)位置(可以在任何子目錄中,目錄名不必是TLDs);
?? 不在JAR中的標(biāo)記文件(擴(kuò)展名為.tag或.tagx的文件)必須放在WEB-INF/tags下的某個(gè)地方,JAR中的標(biāo)記文件必須放在META-INF/tags下的某個(gè)地方;
?? web.xml必須直接放在WEB-INF目錄下。(576)
★ 在META-INF/MANIFEST.MF文件中指定庫依賴性
?? 將Web應(yīng)用打包成WAR文件后,會(huì)生成這個(gè)文件。你的容器的類路徑(不是應(yīng)用的類路徑)上可能有一些可選的包,你也許會(huì)依賴于其中某些包,或者你可能會(huì) 依賴某個(gè)特定版本的庫!有了MANIFEST.MF文件,就能告訴容器你必須訪問哪些可選的庫。如果容器無法提供這些庫,就不能成功地部署應(yīng)用。 (583)
★ 在web.xml中配置servlet時(shí),根據(jù)每個(gè)servlet加載所需的時(shí)間和使用的頻度來決定是否使用<load-on-startup>元素。(596)
?
第12章 Web應(yīng)用安全
★ servlet安全的4大要素:認(rèn)證、授權(quán)、機(jī)密性和數(shù)據(jù)完整性。(621,630)
★ 4種認(rèn)證類型:基本(BASIC)、摘要(DIGEST)、客戶證書(CLIENT-CERT)、表單(FORM)。(645)
轉(zhuǎn)載于:https://my.oschina.net/liangzhenghui/blog/179639
總結(jié)
以上是生活随笔為你收集整理的《Head First Servlets JSP(中文版)》书摘的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用异步Servlet改进应用性能
- 下一篇: 关于Spring 声明式事务处理时,th