Struts 2 知識筆記

1、struts.properties配置常量等同於struts.xml中配置(置於類加載路徑下面)
struts.multipart.maxSize 文件上傳最大大小
struts.action.extension 默認struts處理的請求後綴
struts.enable.DynamicMethodInvocation 是否支持動態方法調用,默認爲true支持
struts.devMode 開啓開發模式
struts.ui.theme 指定視圖標籤默認的視圖主題
struts.custom.i18n.resources 指定struts應用所需要的國際化資源文件如果有多個國際化資源,則多個資源文件名以,隔開
2、struts.xml、struts.properties、web.xml文件均能配置常量
3、在struts.xml文件中,通過<include file="">來包含其它配置文件,避免配置文件臃腫
4、在action中系統不會嚴格區分哪個是封裝請求參數的屬性,哪個是封裝處理結果的屬性,這兩個都是平等的。
同樣,在jsp中輸出action屬性時,它也不會嚴格區分該屬性是封裝請求參數的屬性還是封裝請求結果的屬性。
struts2的action接口中定義了5個字符串常量,分別是:INPUT、SUCCESS、ERROR、NONE、LOGIN
5、如果用戶沒有配置action的class屬性,那麼系統自動使用ActionSupport類作爲處理類。


6、Action訪問Servlet API的方法:
struts2提供了一個ActionContext類,struts2的action可以通過該類訪問Servlet API。下面是常見方法:
1)static ActionContext getContext()   //靜態方法,訪問系統的ActionContext實例
2)Object get(Object key) //類似於HttpServletRequest的getAttribute(String name)方法。
3)Map getApplication() //返回一個Map對象,該對象模擬了該應用的ServletContext實例
4)Map getParameters() //類似於HttpServletRequest的getParameterMap()方法。
5)Map getSession() //返回一個Session對象
6)void setApplication() //設置一個Application實例
7)void setSession() //設置一個Session實例
7、Action直接訪問Servlet API
爲了實現該功能,struts2提供了幾個接口:
1)ServletContextAware,實現該接口的action可以訪問Web應用的ServletContext實例
2)ServletRequestAware,實現該接口的action可以訪問Web應用的ServletRequest實例
3)ServletResponseAware,實現該接口的action可以訪問Web應用的ServletResponse實例
8、通過ServletActionContext工具類靜態方法訪問:
1)static PageContext getPageContext() //獲取web應用的PageContext對象
2)static HttpServletRequest getRequest() //獲取HttpServletRequest對象
3)static HttpServletResponse getResponse() //獲取HttpServletResponse對象
4)static ServletContext getServletContext() //獲取ServletContext對象

9、struts.xml中的命名空間
命名空間有一個級別,假設請求的url爲"/bookservice/search/get.action",系統將先在/bookservice/search下面尋找名爲get的action,如果查找不到的話
則直接去默認命名空間裏面查找,而不會在/bookservice下面繼續查找,如果默認命名空間查找不到的話,則直接報錯。
10、配置默認Action
<package>
<default-action-ref name="xx" />
<action name="" class="xx" >

</action>
</package>
11、struts2的result元素
2種結果:
1)全局result   將<result..作爲<global-results../>的子元素配置
2)局部result 將<result...作爲<action.../>子元素配置
struts2支持的結果類型:
chain 結果類型,Action鏈式處理的結果類型
dispatcher 默認結果類型
freemarker 指定freemarker模板作爲視圖的結果類型
httpheader 用於控制特殊的http行爲的結果類型
redirect 用於直接跳轉到其它url的結果類型
redirecAction 用於跳轉到其它action的結果類型
stream 用於向瀏覽器返回一個InputStream(一般用於文件下載)
velocity 用於指定vecolity模板作爲視圖的結果類型
xslt 用於與xml/xslt整合的結果類型
plainText 用於顯示某個頁面原始代碼的結果類型

<result name="xxx" type="xxx">
<param name="location" >/xxx.jsp</param>
<param name="parse" >true</param>
</result>

dispatcher結果類型參數:location指定視圖資源 parse指定是否允許使用OGNL表達式
plainText結果類型包含參數:location指定視圖資源 charSet指定頁面輸出時使用的字符集
redirect包含參數:同dispatcher

12、使用Action的屬性值決定物理視圖資源
<action name="save_*" class="com.action.SaveAction">
<result name="success" >/${target}.jsp</result>
<result type="redirect" name="input">edit.action?skillName=${currentSkill.name}</result>
</action>

13、PreResultListener接口——它可以在Action完成邏輯處理之後,系統轉入實際物理視圖資源之前調用
可以在任意Action類的方法中添加:
ActionInvocation invocation = ActionContext.getContext().getActionInvocation();
invocation.addPreResultListener(new PreResultListener(){
public void beforeResult(ActionInvocation invocation,String resultCode){    //resultCode即爲邏輯視圖名稱,如success,input等
System.out.println(resultCode);
}
});


14、struts2的異常處理
Struts2的異常處理機制是在struts.xml文件中配置<exception-mapping../>元素完成的。該元素包含兩個屬性:
->exception:指定異常類型
->result:指定邏輯視圖名
根據<exception-mapping.../>元素出現的位置不同,異常映射又分爲全局映射、局部映射:
->局部異常映射:在<action.../>元素的子元素中配置,僅對所在action有效
->全局映射:在<global-exception-mappings.../>中作爲子元素配置,對所有action均有效

15、struts2環境下,在頁面中輸出異常信息:
<s:property value="exception" />:輸出異常對象本身,等同於<s:property value="exception.message" />,因爲exception對象內置了message屬性
<s:property value="exceptionStack" />:輸出異常堆棧信息

16、使用struts2的國際化
struts2中加載全局資源文件的方式:
<constant name="strust.custom.i18n.resources" value="baseName" />
struts2訪問國際化消息有如下3種方式:
1)爲了在jsp中輸出國際化消息,應該使用struts2的<s:text  name="" .../>標籤,該標籤中可以指定一個name屬性,其屬性值對應於國際化資源文件中的key
2)爲了在action中訪問國際化消息,可以使用ActionSupport的getText方法,該方法可以接受一個name參數,該參數對應於國際化資源文件中的key
3)爲了在該表單元素的其它標籤裏輸出國家化消息,可以爲表單標籤指定一個key屬性,該key對應於國際化資源文件中的key
mess_en_US.properties //該國際化資源文件的baseName爲mess,屬於美國英語的資源文件
mess_zh_CN.properties //簡體中文的資源文件(對於包含非西歐字符的國際化資源文件必須使用native2ascii工具進行處理)
....
提供了上面的資源文件後,系統會根據瀏覽者所在的Locale來加載對應的語言資源文件
資源文件內容舉例,實際就是一些鍵值對,以簡體中文爲例:
loginPage = 登錄界面
errorPage = 錯誤界面
succPage = 成功界面
failTip = 對不起,您不能登錄!
succTip = 歡迎,您已成功登錄!
user = 用戶名
pass = 密  碼
login = 登錄

17、輸出帶佔位符的國際化消息,這些佔位符一般由參數來代替
failTip = {0},Sorry,you can not log in!
succTip = {0},Welcome,you has logged in!
welcomeMsg = {0},Hello,now is{1}!

在action中:ctx.getSession.put("tip",getText("sucTip"),new String[]{getUserName()});  //也可以使用list對象實現
在jsp中:
<jsp:useBean id="d" class="java.util.Date" scope="page" />
<s:text name="welcomeMsg">
<s:param><s:property name="username"/></s:param>   //username爲action中的屬性
<s:param>${d}</s:param>
</s:text>

18、struts2加載資源文件的方式
struts2還提供包括包範圍、Action範圍、臨時指定資源文件的方式加載資源文件

19、struts2的標籤庫
<%@ taglib prefix="s" uri="/strusts-tags" %>
分類:UI標籤(表單標籤+非表單標籤)、非UI標籤(數據訪問標籤+邏輯控制標籤)、Ajax標籤

20、OGNL表達式
使用OGNL表達式,在傳統的OGNL求值中,系統會假設只有一個”根“對象,假設爲bar,如下:
#bar.blash //返回bar.getBlash()
#foo.blash //foo.getBlash()
blash //默認執行bar.getBlash(),因爲bar爲”根“對象,只有”根“對象纔可以直接省略#訪問
struts2使用標準的Context來進行OGNL表達式的求值,OGNL的頂級對象是一個Context,這個Context是一個Map實例,其根對象就是一個ValueStack,如果需要訪問
ValueStack裏面屬性,直接通過${bar}即可,當系統創建好action實例後,該action實例已經被封裝到ValueStack中,因此無需書寫#,可以直接訪問。
除此之外,struts2的一些命名對象,非”根“對象:
parameters:相當於HttpServletRequest的getParameter("user")
request對象:相當於HttpServletRequest的getAttribute("user")
session對象:相當於HttpSession的getAttribute("user")
application對象:相當於ServletContext的getAttribute("user")
attr對象:該對象依次搜索如下對象中的屬性:PageContext、HttpServletRequest、HttpSession、ServletContext


21、OGNL中的集合操作
創建list集合:{e1,e2,...}
創建Map集合:#{key1:value1,key2:value2,...}
取得子集操作符:
取出所有符合選擇邏輯的元素
^ 取出符合選擇邏輯的第一個元素
$ 取出符合選擇邏輯的最後一個元素
如:person.relatives.{?  #this.gender == 'male'}  //取出person下的relative,條件是gender爲male,?表示取出所有,#this代表當前集合中的元素

22、struts2的局部類型轉換器(非自定義)
局部類型轉換文件應該命名爲ActionName-conversion.properties,其中ActionName是Action的類名,後面的-conversion.properties是固定部分。類型轉換文件應該放在和Action的
類文件相同的位置下面。
List集合在局部類型轉換文件中的寫法:Element_<ListPropName> = <ElementType>
Map集合在局部類型轉換文件中的寫法(Map類型需要在裏面同時指定key&value):key:Map_<MapPropName> = <KeyType>  value:Element_<MapPropName> = <ValueType>

23、自定義類型轉換器
OGNL提供的類型轉換器接口TypeConverter接口,實現類爲DefaultTypeConverter,複寫其中的convertValue(Map context,Object value,Class toType)方法
context,類型轉化的上下文環境
value,需要轉換的參數
toType,轉換後的目標類型

實現了類型轉換器類還不夠,還必須在web應用中註冊該類型轉換器:
1)註冊局部類型轉換器:局部類型轉換器僅對,某個action的屬性起作用
在局部類型轉換文件中添加一行:<propName> = <ConverterClass>,局部類型轉換文件命名同上:ActionName-conversion.properties,且要在同一個包下面

2)註冊全局類型轉換器:對所有action的屬性均起作用
全局類型轉換文件命名:xwork-conversion.properties,文件放在類加載路徑下面。
文件中可以添加多行:<propName> = <ConverterClass>,這時屬性名、轉換器類都要使用完整類名,包括包名。

3)使用JDK1.5用註釋方式來註冊類型轉換器


24、DefaultTypeConverter類的子類——StrutsTypeConverter類
DefaultTypeConverter做轉換時只有一個convertValue方法,該方法內部需要進行toType類型判斷,而StrutsTypeConverter類是DefaultTypeConverter的子類,該類已經實現了
DefaultTypeConverter的convertValue,它將兩個不同的轉換方向替換成了兩個不同的方法,分別是:Object convertFromString(Map context,String[] values,Class toType)、
String convertToString(Map context,Object o)方法。


25、struts2類型轉換中的錯誤處理
Struts 2提供了一個名爲conversionError的攔截器,該攔截器被註冊在默認的攔截器棧中,查看struts-default.xml文件如下:
<interceptor-stack name="defaultStack">
<!-- 省略其它攔截器 -->
<interceptor-ref name="conversionError" />
<interceptor-ref name="validation" >
<param name="excludeMethods" >input,back,cancel,browse</param> 
</interceptor-ref>
</interceptor-stack>
上面的默認攔截其中提供了conversionError攔截器的引用,如果struts類型轉換出現錯誤,該攔截器會將對應的錯誤封裝成表單域錯誤(FieldError),並將這些錯誤信息放入ActionContext中。
如果出現轉換錯誤,則struts2自動轉入名爲input的邏輯視圖。爲了讓struts的類型轉換錯誤處理機制生效,都必須讓action類繼承ActionSupport基類,因爲ActionSupport負責收集類型轉換錯誤、
輸入校驗錯誤,並將它們封裝成爲FieldError對象,添加到ActionContext中。
在input邏輯視圖對應的實際視圖中使用:<s:fielderror />標籤會輸出形如Invalid field value for field xxx的錯誤提示信息,xxx是Action的屬性名。

26、Struts 2的輸入校驗
Action中的屬性進行校驗,編寫校驗文件ActionName-validation.xml文件,該文件包含一個根元素<validators.../>,而根元素下面包含多個
字段校驗器(字段優先)
<validators>
<field name="propName">
<field-validator type="int">
<param name="xx"></param>
<param name="xx"></param>
<message>字段出錯提示</message>
</field-validator>
<field-validator>
...
</field-validator>
</field>

<field name="propName">
<field-validator type="int">
<param name="xx"></param>
<param name="xx"></param>
<message>字段出錯提示</message>
</field-validator>
<field-validator>
...
</field-validator>
</field>
...
</validators>

非字段校驗器(校驗器優先)
<validators>
<validator type="int">
<param name="fieldName">name</param>
<param name="trim">true</param>
<message key="name.min">5</message>
</validator>
<validator type="int">
...
</validator>
...
</validators>


struts2的輸入校驗錯誤同類型轉換,同樣將錯誤信息封裝至FieldError,並放入StackContext中,失敗時同樣返回input邏輯視圖。
客戶端校驗只需要在<s:form../>元素中添加validate="true"屬性
添加短路校驗器(即一個字段有多種校驗方式時會有多種提示信息,如果一種校驗沒有通過,只會顯示該校驗下的message錯誤提示,不會全部顯示):
只要在<validator.../>或者<field-vaklidator.../>添加屬性short-circuit="true"即可。

struts 2校驗器type:
1)required,必填校驗器 <param name="fieldName"/>username</param>
 <message></message>
2)requiredstring,必填字符串校驗器,比required多了<param name="trim"></param>
3)int、long、short,整數校驗器,param中name值:fieldName、min、max
4)date,日期校驗器,param中:fieldName、min、max
5)expression,表達式校驗器,屬於非字段校驗器,不能用於字段校驗器。param中包含:expression屬性,指定表達式。
6)fieldexpression,字段表達式校驗器,param中包含:fieldName、expression。
7)email,郵件地址校驗器
8)url,網址校驗器
9)visitor,符合類型校驗器,例如action中的User類型校驗
10)stringlength,字符串長度校驗器,param包含:fieldName、minLength、maxLength
11)regex,正則表達式校驗器,param包含:fieldName、expression、caseSensitive(是否區分大小寫)


27、手動完成校驗
重寫ActionSupport繼承類中的validateXxx()方法,其中Xxx爲Action下面的xxx方法名。
在方法中可以使用addFieldError("userError","您的用戶名必須包含.org"),通過這種方式添加的FieldError不會自動顯示,必須通過<s:fielderror/>標籤來顯示。

28、struts 2文件上傳
<s:form action="upload" enctype="multipart/form-data">
<s:file name="upload" label="choose file" /> 
</s:form>


Action中寫法:
private File upload;//上傳文件name屬性
private String uploadFileName;
private String uploadContentType;
private String savePath;


FileOutputStream fos = new FileOutputStream(getSavePath() + "\\" + getUploadFileName());
FileInputStream fis = new FileInputStream(getUpload());
byte[] buffer = new byte[1024];
int len = 0;
while( (len = fis.read(buffer) > 0){
fos.write(buffer,0,len);
}
return success;


Action的屬性savePath的值可在struts.xml文件中直接進行配置
<action ..>
...
<!-- 動態設定Action中的屬性值 -->
<param name="savePath">/upload</param>
...
</action>


29、攔截器實現文件過濾
struts.xml文件中,在需要處理文件上傳的Action下面配置fileUpload攔截器,指定參數:
->allowedTypes:指定允許上傳的文件類型
->maximumSize:指定允許上傳的文件大小,單位是字節


<action>
<interceptor-ref name="fileUpload">
<param name="alowedTypes">image/jpg,image/gif,image/jpeg</param>
<param name="maximumSize">200000</param>
</interceptor>
<interceptor-ref name="defaultStack"/>
<param name="savePath">/uploadFiles</param>
</action>
改變文件上傳失敗的提示信息(在國際化資源文件中配置):
struts.message.error.content.type.not.allowed = 您上傳的文件格式不符合!
struts.message.error.file.too.large = 您上傳的文件太大!


struts.multipart.maxSize屬性,設置整個表單請求內容的最大字節數


30、struts實現文件下載
struts提供下載的Action與普通的Action是相同的,只不過在普通Action的基礎上加了一個返回InputStream流的方法,該輸入流代表了被下載文件的入口。
<action name="" class="org.cz.action.DownloadAction">
<param name="inputPath">\images\a.jpg</param>

<result name="success" type="stream">
<param name="inputName">TargetFile</param>
<param name="contentType">image/jpg</param>
<param name="contentDisposition">filename="a.jpg"</param>
<param name="bufferSize">4096</param>
</result>
</action>


private String inputPath;


public String getInputPath() {
return inputPath;
}


public void setInputPath(String inputPath) {
this.inputPath = inputPath;
}

//定義一個返回InputStream的方法,方法名爲struts.xml配置文件中的inputName參數值加一個get
public InputStream getTargetFile() throws Exception{
return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
}

<body>
    <ul>
    <li>
    下載a.jpg文件:
    <a href="images/a.jpg">下載</a>
    </li>
    </ul>
  </body>

31、攔截器
<interceptor name="" class="">
...
<param name="" ..></param>
...
</interceptor>
<interceptors>
...
<interceptor name="" class="" />
...
<interceptor-stack>
...
</interceptor-stack>
...
</interceptors>
<action name="" class="">
...
<interceptor-ref name="" />
...
</action>
配置攔截器棧:
<interceptor-stack name="">
<interceptor-ref name="攔截器一" ../>
<interceptor-ref name="攔截器二" ../>
<interceptor-ref name="攔截器三" ../>
...
</interceptor-stack>
攔截器棧和攔截器作用是一模一樣的,可以看成是一個大的攔截器。攔截器或攔截器棧的行爲將會在Action的execute方法執行之前被執行。
爲某個package配置默認攔截器(一個package中只允許出現一個默認攔截器):
在<package../>根元素中配置:<default-interceptor-ref name="" .../>

自定義攔截器:
實現interceptor接口,一般直接繼承AbstractInterceptor實現類,方法:
->init()
->destroy()
->intercept(ActionInvocation invocation),invocation代表被攔截的Action的引用,可以通過該參數的invoke方法將控制權交給下個攔截器或者Action的execute方法(如果有下一個攔截器則交給攔截器,沒有的話直接執行Action的execute方法),getAction()方法直接返回被攔截Action的實例,這樣的話可以直接獲取Action中的參數並加以修改等等。


32、攔截方法的攔截器
默認情況下,如果爲Action制定攔截器後,該攔截器會攔截Action中的所有方法,如果只需要攔截Action中的特定方法,則可以使用MethodFilterInterceptor攔截器,該攔截器是AbstractInterceptor的子類,該類重寫了父類中的intercept方法,但提供了一個doIntercept方法,繼承該類的攔截器會實現方法攔截,然後需要在Action配置文件中指定參數:
<param name="excludeMethods">execute,haha,iawd</param>  //指定不攔截executehaha,iawd方法


33、攔截器的執行順序
Action的方法執行之前:配置越靠前的攔截器,越先執行
Action的方法執行之後:配置越靠後的攔截器,越先執行


34、攔截結果的監聽器
實現接口PreResultListener,改接口下有多個方法,如:beforeResult(ActionInvacation invocation,String resultCode), resultCode爲被攔截Action的execute方法的返回值。
beforeResult中定義的操作先於invocation.invoke()方法執行之後的操作。


35、使用攔截器完成權限控制
ActionContext ac = invocation.getInvocationContext();
Map session = ac.getSession();
String user = (String)session.get("user");
if(user != null && user.equals("crazit")){
return invocation.invoke();
}else{
return Action.LOGIN;
}


36、使用struts的Ajax支持
Ajax,異步javascript和xml技術,當服務端的響應成功返回至瀏覽器時,瀏覽器使用DOM(文檔對象模型)將服務端響應裝載到當前頁面的指定位置。


public class LoginAction implements Action{
private String user;
private String pass;
private InputStream inputstream;
...
public InputStream getResult(){
return inputStream;
}
public String execute(){
inputStream = user.equals("crazit") ? new ByteArrayInputStream("恭喜你,登錄成功!".getBytes("utf-8")) : new ByteArrayInputStream("對不起,請重新登錄!".getBytes("utf-8"));
return SUCCESS;
}
}


<result type="stream" name="success">
<param name="contentType">text/html</param>
<param name="inputName">result</param>
</result>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章