J2EE學習筆記(8) 真是知易行難 初試Struts
來源:互聯網
上載者:User
實在是好事多磨,折騰了兩個晚上才搞定了一個 HelloWorld Struts版,下面談談一點體會。
開發環境 Eclipse + MyEclipse (Struts 1.1)
Struts 1.1支援多模組開發,在myEclipse的Web Application Project裡先建立新module (New->Struts 1.1 Module),
再依次加Form Action ActionForward (New -> Struts 1.1 Action, Form & JSP).有時myEclipse會找不到自己剛剛加的Form,手動添加即可,沒什麼大不了的。myEclipse的web.xml模板不符合標準,需要手動更改。TLD檔案好像也不太對,可以用自己曾經做過項目的TLD代替。
下面是兩個折騰我很久的問題。
1) 如果在我們security模組裡有
<action
path="/UserSecurityCheck"
type="com.scs.presentation.security.UserSecurityCheckAction"
name="UserLoginForm" scope="request"
input="/init.do">
<forward name="loginSucceed" path="/mainmenu.jsp"/>
</action>
這個例子中,注意mainmenu.jsp前面有個/,ActionServlet會在當前module裡尋找這個jsp,也就是說mainmenu.jsp需要放在/%webroot%/security/的目錄下面,而不是直接在/%webroot%/下
2) struts的form標記定義了一個頁面的表單,但該struts標記需要根據action的值來尋找module config裡的action mapping,並根據action mapping的值來初始化action form。因此,在form標記中需要擷取一個module config。在這裡,擷取哪一個module config成為了form標記能否正常工作的關鍵,如果module config的擷取值不正確,將會造成Cannot retrieve mapping for {action name}的錯誤。尋找方法為首先從request中擷取當前的module config,如果沒有找到,就從servlet context中擷取預設的module config。
現在struts framework的實現是這樣的,只有ActionServlet正確地將module config對象賦值給request的屬性Globals.MODULE_KEY後,後來的含form tag的屬於該模組的jsp頁面才能被struts framework正確與對應此module config掛鈎。倘若編程人員/使用者試圖對某個模組發出的第一個請求是jsp而不是action,actionServlet就沒有機會做上述的準備工作(因為web container會直接處理jsp請求,不會轉寄給actionServlet),那麼接下來處理jsp中的form tag時,struts framework就會試圖從default module config中尋找該actionMapping(因為request裡的module specfic config依然為空白,所以只好從default裡找了),一般上這種尋找是沒有結果的,最後framework就會返回Cannot retrieve mapping for ThisAction的錯誤。
結論是,接入每個module的第一個頁面必須是由action請求(而不是jsp請求),以給actionServlet一個機會裝載對應的module config並cache.
非常感謝下面兩篇文章,它們協助我解決了這個奇怪的問題,也間接導致了這篇文章的誕生。