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