天天看點

struts2随筆

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>

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>

<message>字段出錯提示</message>

</field-validator>

<field-validator>

...

</field>

</validators>

非字段校驗器(校驗器優先)

<validator type="int">

<param name="fieldName">name</param>

<param name="trim">true</param>

<message key="name.min">5</message>

</validator>

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>

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>

改變檔案上傳失敗的提示資訊(在國際化資源檔案中配置):

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>

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>

<interceptors>

<interceptor name="" class="" />

<interceptor-stack>

</interceptors>

<action name="" class="">

<interceptor-ref name="" />

配置攔截器棧:

<interceptor-stack name="">

<interceptor-ref name="攔截器一" ../>

<interceptor-ref name="攔截器二" ../>

<interceptor-ref name="攔截器三" ../>

攔截器棧和攔截器作用是一模一樣的,可以看成是一個大的攔截器。攔截器或攔截器棧的行為将會在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>

繼續閱讀