Struts2干貨筆記——第三天

目錄

1. Struts2國(guó)際化
  • 1.1 資源包的編寫
  • 1.2 國(guó)際化配置
  • 1.3 在struts2中國(guó)際化操作可以在哪些位置使用?
  • 1.4 在struts2中操作國(guó)際化?
2. 攔截器
  • 2.1 怎樣使用攔截器
  • 2.2 常用攔截器
  • 2.3 怎樣解決只讓action中某些方法被攔截?
  • 2.4 關(guān)于interceptor與Filter區(qū)別
3. 文件上傳和下載
  • 3.1 在action中怎樣處理文件上傳?
  • 3.2 多個(gè)文件同時(shí)上傳
  • 3.3 控制上傳文件的大小以及上傳文件的類型
  • 3.4 struts2中文件的下載

Struts2國(guó)際化

國(guó)際化(Internationalization-i18N,以I開(kāi)始以N結(jié)束,共18個(gè)字母)是指Web應(yīng)用程序根據(jù)當(dāng)前機(jī)器的語(yǔ)言環(huán)境采用與當(dāng)前語(yǔ)言環(huán)境相符的消息資源文件來(lái)顯示W(wǎng)eb內(nèi)容,簡(jiǎn)單來(lái)說(shuō),就是一個(gè)程序在美國(guó)顯示"Hello world",而在中國(guó)顯示"你好 世界"。
實(shí)行國(guó)際化需要一個(gè)語(yǔ)言資源包(很多properties文件,每個(gè)properties文件 針對(duì)一個(gè)國(guó)家或者語(yǔ)言 ,通過(guò)java程序根據(jù)來(lái)訪者國(guó)家語(yǔ)言,自動(dòng)讀取不同properties文件 )

資源包的編寫
  1. properties文件命名 : baseName_language(小寫) _country(大寫).properties
    其中baseName是資源文件的基本名稱,可以自定義,language和country必須是java支持的語(yǔ)言和國(guó)家。
    例如 :
    messages_zh_CN.properties 中國(guó)中文
    messages_en_US.properties 美國(guó)英文
  2. ResourceBundle 根據(jù)不同Locale(地域信息),讀取不同國(guó)家 properties文件
    ResourceBundle bundle = ResourceBundle.getBundle("messages", Locale.US);

struts2中對(duì)國(guó)際化進(jìn)行了封裝,我們只需要根據(jù)其提供的API進(jìn)行訪問(wèn)就可以。

國(guó)際化配置
  1. 全局(頻繁)
    全局配置,所以的Action都可以使用,properties文件可以在任何包中,需要在struts.xml 中配置全局信息文件位置。
    struts.xml
<constant name="struts.custom.i18n.resources" value="messages"></constant>   messages.properties 在src根目錄
<constant name="struts.custom.i18n.resources" value="com.java.resources.messages"></constant>   messages.properties 在 com.java.resources 包中

配置完文件后就可以在jsp頁(yè)面或者action中訪問(wèn)國(guó)際化信息

  • 在jsp頁(yè)面中使用<s:test name=" " />標(biāo)簽輸出國(guó)際化信息,等價(jià)于<lable></lable>,name為資源文件中的key
  • 在Action類中,可以繼承ActionSupport,使用getTest()方法得到國(guó)際化信息,該方法的第一個(gè)參數(shù)用于指定資源文件中的key。
  • 在表單標(biāo)簽中,通過(guò)key屬性指定資源文件中的key,<s:textfield name="realname" key="user" />
  1. 局部
  • 針對(duì)于Action類
    當(dāng)一些顯示數(shù)據(jù)只會(huì)被某個(gè)action使用,這時(shí)候我們可以把這些顯示數(shù)據(jù)定義在只能被該action訪問(wèn)的Action范圍資源文件中,為某個(gè)action指定資源文件,如:在Action類所在的路徑下放置ActionClassName_language_country.properties資源文件,在ActionClassName為action類的簡(jiǎn)單名稱。當(dāng)查找指定key的消息時(shí),系統(tǒng)會(huì)先從ActionClassName_language_country.properties資源文件查找,如果沒(méi)有找到對(duì)應(yīng)的key,然后沿著當(dāng)前包往上查找基本名為package的資源文件,一直找到頂層包,如果還沒(méi)有找到對(duì)應(yīng)的key,最后會(huì)從常量struts.custom.i18n.resources指定的資源文件中尋找

  • 針對(duì)于一個(gè)package下的所有action
    在一個(gè)大型應(yīng)用中,整個(gè)應(yīng)用有大量的內(nèi)容需要實(shí)現(xiàn)國(guó)際化,如果我們把國(guó)際化的內(nèi)容都放置在全局資源屬性文件中,顯然會(huì)導(dǎo)致資源文件變得過(guò)于龐大、臃腫,不便于維護(hù),這個(gè)時(shí)候我們可以針對(duì)不同模塊,使用包范圍來(lái)組織國(guó)際化文件。
    在指定的包下放置package.properties文件,處于該包以及包下的action都可以訪問(wèn)該資源,當(dāng)查找指定key的消息時(shí),系統(tǒng)會(huì)先從package資源文件查找,當(dāng)找不到對(duì)應(yīng)的key時(shí),才會(huì)從常量struts.custom.i19n.resources指定的資源文件中尋找。

  • jsp頁(yè)面臨時(shí)使用某一個(gè)properties文件
    在Struts2中提供了<s:i18n>標(biāo)簽,使用<s:i18n>標(biāo)簽我們可以直接從類路徑下的某個(gè)資源文件中獲取國(guó)際化數(shù)據(jù),而無(wú)需任何配置:

<s:i18n name="com.java.action.welcome">
<s:text name="welcome" />  
<s:param>小王</s:param>
</s:text>
</s:i18n>

訪問(wèn)com.java.action包下基本名為welcome的資源文件。

在struts2中國(guó)際化操作可以在哪些位置使用?(在哪此位置上使用)
  1. action類中使用
  2. 配置文件中使用<validation.xml>
  3. 在jsp頁(yè)面上使用
在struts2中操作國(guó)際化?(怎樣使用)
  1. 在action類中使用
    前提:action類要繼承ActionSupport類。
    getText(String name)就可以獲取配置文件中對(duì)應(yīng)名稱的值。
  2. 在validation.xml文件中使用
    <message key="名稱"/>
  3. 在jsp頁(yè)面上使用
    <s:text name="名稱"> 如果沒(méi)有使用<s:i18n name="">來(lái)指定,會(huì)從全局配置文件中獲取。如果要從某一個(gè)配置文件中獲取,通過(guò)name屬性來(lái)指定, 包名.配置文件名稱 。

攔截器

Struts2的攔截器和Servlet過(guò)濾器比較類似,在執(zhí)行Action的execute方法之前,Struts2會(huì)首先執(zhí)行在struts.xml中引用的攔截器,在執(zhí)行完所有引用的攔截器的intercept方法后,會(huì)執(zhí)行Action的execute方法。

struts2攔截器使用的是AOP思想,AOP的底層實(shí)現(xiàn)就是動(dòng)態(tài)代理,攔截器采用責(zé)任鏈模式,在責(zé)任鏈模式里,很多對(duì)象由每一個(gè)對(duì)象對(duì)其下家的引用而連接起來(lái)形成一條鏈,責(zé)任鏈每一個(gè)節(jié)點(diǎn),都可以繼續(xù)調(diào)用下一個(gè)節(jié)點(diǎn),也可以阻止流程繼續(xù)執(zhí)行。
struts2中在struts-default.xml文件中聲明了所有的攔截器。
而struts2框架默認(rèn)使用的是defaultStack這個(gè)攔截器棧。
在這個(gè)攔截器棧中使用了18個(gè)攔截器。簡(jiǎn)單說(shuō),struts2框架在默認(rèn)情況下,加載了18個(gè)攔截器。

怎樣使用攔截器

攔截器的使用相對(duì)比較簡(jiǎn)單,只需要在struts.xml文件的Action中添加<interceptor-ref>標(biāo)記,用于指定具體使用哪一個(gè)定義好的攔截器即可。例如,有一個(gè)已經(jīng)配置好的攔截器hellointerceptor。

<action name="helloaction" class="com.action.HelloAction">
  <interceptor-ref name="helloInterceptor"></interceptor-ref>
</action>

當(dāng)用戶使用了一個(gè)自定義攔截器后,系統(tǒng)默認(rèn)的攔截器就會(huì)自動(dòng)失效,為了還能使用系統(tǒng)默認(rèn)的攔截器,需要在struts.xml文件中手動(dòng)添加系統(tǒng)默認(rèn)攔截器,系統(tǒng)默認(rèn)攔截器棧名稱是defaultStack。

<action name="helloaction" class="com.action.HelloAction">
  <interceptor-ref name="defaultStack"></interceptor-ref>
  <interceptor-ref name="helloInterceptor"></interceptor-ref>
</action>
常用攔截器

<interceptor-ref name="modelDriven"/> 模型驅(qū)動(dòng)
<interceptor-ref name="fileUpload"/>文件上傳
<interceptor-ref name="params"> 參數(shù)解析封裝
<interceptor-ref name="conversionError"/> 類型轉(zhuǎn)換錯(cuò)誤
<interceptor-ref name="validation"> 請(qǐng)求參數(shù)校驗(yàn)
<interceptor-ref name="workflow"> 攔截跳轉(zhuǎn) input 視圖

怎樣解決只讓action中某些方法被攔截?
  1. 創(chuàng)建類不在實(shí)現(xiàn)Interceptor接口,而是繼承其下的一個(gè)子類.MethodFilterInterceptor不用在重寫intercept方法,而是重寫 doIntercept方法。
  2. 在struts.xml文件中聲明
    <interceptors>
    <intercept name="" class="">
    <param name="includeMethods">add,update,delete</param>
    <param name="excludeMethods">search</param>
    </intercept>
    </interceptors>
關(guān)于interceptor與Filter區(qū)別
  1. 攔截器是基于java反射機(jī)制的,而過(guò)濾器是基于函數(shù)回調(diào)的。
  2. 過(guò)濾器依賴于servlet容器,而攔截器不依賴于servlet容器。
  3. 攔截器只能對(duì)Action請(qǐng)求起作用,而過(guò)濾器則可以對(duì)幾乎所有請(qǐng)求起作用。
  4. 攔截器可以訪問(wèn)Action上下文、值棧里的對(duì)象,而過(guò)濾器不能。
  5. 在Action的生命周期中,攔截器可以多次調(diào)用,而過(guò)濾器只能在容器初始化時(shí)被調(diào)用一次。

文件上傳和下載

要想使用HTML表單上傳一個(gè)或者多個(gè)文件,必須把HTML表單的enctype屬性設(shè)置為multipart/form-data,把它的method屬性設(shè)置為post,為了讓用戶能夠選擇一個(gè)文件進(jìn)行上傳,程序員必須提供一個(gè)<input type="file">字段。
默認(rèn)情況下struts2框架使用的就是commons-fileupload組件,struts2它使用了一個(gè)interceptor幫助我們完成文件上傳操作。
<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>

在action中怎樣處理文件上傳?
  1. 在JSP頁(yè)面的文件上傳表單里使用file標(biāo)簽,如果需要一次上傳多個(gè)文件,就必須使用多個(gè)file標(biāo)簽,但它們的名字必須是相同的。
  2. 在Action中新添加3個(gè)和文件上傳相關(guān)的屬性,這三個(gè)屬性的名字必須是以下各式
private File upload; //上傳的文件
private String uploadContentType; //上傳文件的類型
private String uploadFileName;  //上傳文件的名稱

其中upload是jsp頁(yè)面上file標(biāo)簽的name屬性值<input type="file" name="upload">
如果是上傳單個(gè)文件,upload屬性類型就是File,它代表被上傳的文件,第二個(gè)和第三個(gè)屬性類型是String,它們分別代表上傳文件的文件名和文件類型。定義的方式分別是jsp頁(yè)面file組件的name屬性值+ContentType和jsp頁(yè)面file組件的name屬性值+FileName,如果上傳多個(gè)文件,可以使用數(shù)組或者List。

  1. 在execute方法中使用commons-io包下的FileUtils完成文件復(fù)制.
FileUtils.copyFile(upload, new File("d:/upload",uploadFileName));
多個(gè)文件同時(shí)上傳

在服務(wù)器端只需要將action屬性聲明成List集合或數(shù)組就可以。

private List<File> upload;
private List<String> uploadContentType;
private List<String> uploadFileName;
控制上傳文件的大小以及上傳文件的類型

在fileupload攔截器中,通過(guò)其屬性進(jìn)行控制.
maximumSize---每一個(gè)上傳文件大小
allowedTypes--允許上傳文件的mimeType類型.
allowedExtensions--允許上傳文件的后綴名.

<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedExtensions">txt,mp3,doc</param>
</interceptor-ref>
struts2中文件的下載

定義一個(gè)action類繼承ActionSupport類
struts2提供了stream結(jié)果類型,該結(jié)果類型就是專門用于支持文件下載功能的
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
在StreamResult類中有三個(gè)屬性:

  • protected String contentType = "text/plain"; //用于設(shè)置下載文件的mimeType類型
  • protected String contentDisposition = "inline";//用于設(shè)置進(jìn)行下載操作以及下載文件的名稱
  • protected InputStream inputStream; //用于讀取要下載的文件。
    在action類中定義一個(gè)方法
public InputStream getInputStream() throws FileNotFoundException {
    FileInputStream fis = new FileInputStream("d:/upload/" + filename);
        return fis;
}

在配置時(shí)

<result type="stream">
    <param name="contentType">${contentType}</param>//會(huì)調(diào)用當(dāng)前action中的getContentType()方法。
    <param name="contentDisposition">attachment;filename=${downloadFileName}</param>
    <param name="inputStream">${inputStream}</param> //會(huì)調(diào)用當(dāng)前action中的getInputStream()方法。
</result>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容