?
將
servlet
和
JSP
結(jié)合使用,可以把應(yīng)用程序的邏輯和外觀呈現(xiàn)部分清楚的分開(kāi)。
?
servlet API
由兩個(gè)程序包組成
??????
a
javax.servlet
??????
a
javax.servlet.http
?
servlet
的實(shí)質(zhì)是實(shí)現(xiàn)了借口
javax.servlet.Servlet
的類(lèi)
?
web
容器管理
servlet
生命周期的所有方面,它根據(jù)需要?jiǎng)?chuàng)建
servlet
類(lèi)的實(shí)例,將請(qǐng)求傳
??????
遞給實(shí)例進(jìn)行處理,最終刪除實(shí)例。
?
容器會(huì)在
servlet
生命周期的適當(dāng)時(shí)間調(diào)用下列方法
??????
a
public void init() throws ServletException
??????
??????
在發(fā)送第一個(gè)請(qǐng)求之前調(diào)用一次。
??????
a
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException
反復(fù)調(diào)用以使
servlet
處理
GET
請(qǐng)求。
??????
a
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException
反復(fù)調(diào)用以使
servlet
處理
POST
請(qǐng)求。
??????
a
public void destroy()
?????????????
在
servlet
停止服務(wù)前調(diào)用一次。
a
容器只為每個(gè)
servlet
創(chuàng)建一個(gè)實(shí)例,這意味著
servlet
必須是線程安全的,即,能夠同時(shí)
??????
處理多個(gè)請(qǐng)求,每個(gè)處理都通過(guò)
servlet
代碼作為單獨(dú)的線程來(lái)處理。
?
編譯和安裝
servlet
??????
a
要編譯
servlet
,首先必須確保
servlet.jar
文件在
CLASSPATH
中
??????
a
編譯完后,將類(lèi)文件放在
WEB-INF/classes
目錄中(容器自動(dòng)在
WEB-INF/classes
目
?????????????
錄中查找類(lèi));也可以用程序包形式出現(xiàn),此時(shí)目錄結(jié)構(gòu)為
????????????? WEB-INF/classes/com/mycompany
;還可以將類(lèi)打包到一個(gè)
JAR
文件中,拷貝到
????????????? WEB-INF/lib
目錄中。
??????
a
測(cè)試
?????????????
http://localhost:8080/servlet/com.mycompany.HelloWorld
?
將
servlet
作為所有應(yīng)用程序請(qǐng)求的公共入口點(diǎn)時(shí),可以獲得對(duì)應(yīng)用程序頁(yè)面流的整體控
??????
制。
?
當(dāng)使用
servlet
作為控制器時(shí),必須處理下列基本要求
??????
a
所有請(qǐng)求處理都必須傳遞到單獨(dú)的控制器
servlet
中。
??????
a
servlet
必須能夠區(qū)分請(qǐng)求,以便進(jìn)行不同類(lèi)型的處理。
??????
a
可以使用現(xiàn)成的
struts servlet
a
struts servlet
根據(jù)請(qǐng)求
URI
中的一部分來(lái)斷定請(qǐng)求的類(lèi)型,查找對(duì)應(yīng)的行為類(lèi)(使用
??????
配制信息),并調(diào)用
execute()
方法。
a
execute()
方法不顯示應(yīng)答,只關(guān)心商務(wù)邏輯。該方法返回一個(gè)
struts ActionForward
實(shí)
??????
例,其中包含應(yīng)答應(yīng)該調(diào)用以顯示應(yīng)答的
JSP
頁(yè)面的相關(guān)信息。該頁(yè)面由邏輯名稱(chēng)
??????
進(jìn)行標(biāo)示,并影射到配置文件中的實(shí)際頁(yè)面邏輯上。因此可以通過(guò)重新配置,而不
??????
是改變代碼,從而至少在某種程度上控制頁(yè)面流。
?
使用
servlet
的最佳解決方案是定義
servlet
的映射規(guī)則
??????
而不是使用:
/myapp/servlet
開(kāi)頭的調(diào)用
??????
或是使用
<form action=”/ora/servlet/controller/someAction”>
??????
以上方式的調(diào)用
servlet
將會(huì)導(dǎo)致安全問(wèn)題和程序部署的問(wèn)題。
?
struts
中
??????
a
配置描述符中映射規(guī)則確保了所有請(qǐng)求都可以到達(dá)
struts servlet
??????
a
struts-config.xml
中的行為映射提供了區(qū)分不同請(qǐng)求時(shí)所需的信息。
??????
a
最后則有實(shí)現(xiàn)一些老式的編碼并實(shí)現(xiàn)行為類(lèi)。
??????
a
struts Action
中的
execute()
方法執(zhí)行請(qǐng)求處理,
execute()
方法返回后,
struts servlet
調(diào)
?????????????
用指定的資源,一般情況下是
JSP
頁(yè)面,內(nèi)容是針對(duì)該請(qǐng)求的應(yīng)答。
??????
a
ActionMapping
類(lèi)封裝了所有可以在
Struts
配置文件中定義的映射信息。里面完成邏
?????????????
輯頁(yè)面名稱(chēng)和實(shí)際頁(yè)面名稱(chēng)之間的映射。可以同
<forward>
元素設(shè)置這些映射
?????????????
可以用如下方法取得
ActionForward
的實(shí)例:
????????????? ActionForward nextPage=(ActionMapping)mapping.findForward(“main”);
????????????? nextPage = new ActionForward(next,true);
????????????? ActionForward
構(gòu)造函數(shù)中的第
2
個(gè)參數(shù):
????????????? True:
使用重定向
????????????? False:
使用轉(zhuǎn)發(fā)
??????
a
<global-forwards>
定義可以用于所有行為的映射,而
<action>
中的
<forward>
則定義了
?????????????
僅可用于該行為的映射。
??????
a
當(dāng)
struts servlet
收到一個(gè)請(qǐng)求時(shí),首先使用
processPath()
方法來(lái)提取映射到行為類(lèi)的
?????????????
部分,然后查處匹配行為類(lèi)的實(shí)例,并調(diào)用
execute()
方法。
??????
a
execute()
方法返回的
ActionForward
實(shí)例由
prcessActionForward()
方法處理。該方法實(shí)
?????????????
現(xiàn)了如何轉(zhuǎn)發(fā)控制。
??????
a
ActionForward
包含了
struts
將控制傳遞給下一個(gè)組件時(shí)需要的所有信息。
??????
a
servlet
重定向
API
:
response.sendRedirect(response.encodeRedirectURL(path));
??????
a
servlet
轉(zhuǎn)發(fā)
API: RequestDispatcher rd = getSevletContext().getRequestDispatcher(path);
?????????????????????????????????? rd.forward(request,response);
?????????????
此行為與
<jsp:forward>
行為相同,永久的獎(jiǎng)控制傳遞個(gè)目標(biāo)。
?????????????
a
它還包括另一個(gè)
include()
方法:該方法相同與
<jsp:include>
行為:臨時(shí)將控制傳
????????????????????
遞給目標(biāo),生產(chǎn)一部分應(yīng)答,但是不設(shè)置應(yīng)答首部。
??????
a
encodeRedirectURL(path) API
:如果瀏覽器不支持
cookie
,該方法將在
URL
中插入會(huì)
?????????????
話(huà)
ID
。
?
所有請(qǐng)求處理都必須傳遞到單獨(dú)的控制器
servlet
中
web
應(yīng)用程序的配置描述符中可以定義
3
種映射規(guī)則:
??????
a
完全匹配:是
URI
匹配與該
URI
完全相同的模式路徑,
?????????????
例:請(qǐng)求
/contextPath/exactMatch
與模式
/exactMatch
向匹配
??????
a
路徑前綴匹配規(guī)則:使
URI
匹配與該
URI
一樣具有最多路徑元素的模式路徑
?????????????
例:
/contextPath/pathPrefix
和
//contextPath/pathPrefix/pathInfo
都與模式
???????????????????? /pathPrefix/*
匹配
??????
a
擴(kuò)展名匹配規(guī)則:使
URI
匹配與該
URI
具有相同擴(kuò)展名的擴(kuò)展模式
?????????????
例:
/contextPath/name.extension
和
/contextPath/aPath/name.extension
都與
*.extension
????????????????????
匹配
??????
a
web
容器以“完全匹配”、“路徑前綴規(guī)則”、“擴(kuò)展名規(guī)則”的順序查找匹配項(xiàng)。
??????
a
“完全匹配”規(guī)則很少使用,
struts servlet
只使用“路徑前綴匹配規(guī)則”和“擴(kuò)展名
?????????????
匹配規(guī)則”
??????
例:
?????????????
<wep-app>
???
???
...
...
???
???
<servlet>
???????
???
<servlet-name>
action
</servlet-name>
???????
???
<servlet-calss>
???????????
???
org.apache.struts.action.ActionServlet
???????
???
</servlet-calss>
??
???
???
</servlet>
???
???
<servlet-mapping>
???
???????
<servlet-name>
action
</servlet-name>
???
???????
<url-patterb>
*.do
</url-pattern>
???
???
</servlet-mapping>
???
???
...
...
</wep-app>
此時(shí)匹配<form action=
”
someAction.do
”
>
a
也可以使用
路徑前綴匹配規(guī)則
???
???
<servlet-mapping>
???
???????
<servlet-name>
action
</servlet-name>
???
???????
<url-patterb>
/ch18/do/*
</url-pattern>
???
???
</servlet-mapping>
此時(shí)匹配
/ch18/do
a
在這里容器會(huì)為所有以
.do
結(jié)尾的請(qǐng)求調(diào)用
struts servlet
?
servlet
必須能夠區(qū)分請(qǐng)求,以便進(jìn)行不同類(lèi)型的處理
??????
a
Struts sevlet
使用配置文件(
sruts-config.xml
),將具體請(qǐng)求映射到具體的行為類(lèi)上來(lái)
?????????????
完成該任務(wù)。
??????
a
/ora/ch18/protected/do/storeMsg
?????????????
使用路徑前綴匹配規(guī)則,經(jīng)過(guò)
struts processPath API
處理后為
????????????? /storeMsg
?????????????
這樣處理會(huì)有安全問(wèn)題,所以應(yīng)該堅(jiān)持使用擴(kuò)展名匹配規(guī)則
??????
a
/ora/ch18/protected/storeMsg.do
?????????????
使用擴(kuò)展名匹配規(guī)則,經(jīng)過(guò)
struts processPath API
處理后為
????????????? /ch18/protected/storeMsg
??????
a
cookies
中
setMaxAge
(
maxAge
)
,
如果
maxAge-=0
則告訴瀏覽器刪除
cookie
??????
a
servlet
規(guī)范將保存
throwable
對(duì)象的請(qǐng)求屬性命名為
????????????? Javax.servlet.error.exception
??????
a
JSP
規(guī)范將保存
throwable
對(duì)象的請(qǐng)求屬性命名為
????????????? Javax.servlet.jsp.jspException