日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Struts2_3_国际化处理_自定义拦截器_文件上传及下载_OGNL

發(fā)布時(shí)間:2024/7/5 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Struts2_3_国际化处理_自定义拦截器_文件上传及下载_OGNL 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Struts2國(guó)際化處理

瀏覽器根據(jù)當(dāng)前的語(yǔ)言環(huán)境自動(dòng)查找對(duì)應(yīng)的語(yǔ)言環(huán)境資源包, 使jsp顯示合適的語(yǔ)言數(shù)據(jù)環(huán)境
Struts2實(shí)現(xiàn)國(guó)際化, 動(dòng)作類必須繼承ActionSupport

  • 創(chuàng)建資源包
  • 資源包由多個(gè)properties文件組成, properties文件的文件名必須滿足命名規(guī)范: 文件名_語(yǔ)言代碼_國(guó)家代碼.properties 語(yǔ)言代碼/國(guó)家代碼由iso規(guī)定 例: ms_zh_CN.properties 注:當(dāng)properties文件命名為: 文件名.properties表名它為默認(rèn)的資源包, 當(dāng)瀏覽器沒(méi)有找到對(duì)應(yīng)的語(yǔ)言資源包的時(shí)候, 就會(huì)使用默認(rèn)的資源包
  • 配置資源包
  • 1. 配置全局資源包覆蓋default.properties文件中的常量struts.custom.i18n.resources例:<constant name="struts.custom.i18n.resources" value="com.test.message"></constant><package name="p1" extends="struts-default"><action name="action1" class="com.action.DemoAction"></action></package>com.test.message代表資源包所在的位置 2. 配置包范圍的資源包命名規(guī)范: package_語(yǔ)言代碼_國(guó)家代碼.properties(固定命名格式)使用這種命名規(guī)范, 資源包只能被該包或子包的動(dòng)作類訪問(wèn) 3. 局部資源包命名規(guī)范: 動(dòng)作名稱_語(yǔ)言代碼_國(guó)家代碼.properties只為動(dòng)作類服務(wù) 注:資源包的搜索順序, 滿足就近原則: 局部 > 包 > 全局
  • 在jsp中讀取資源包中內(nèi)容
  • 借助struts2的標(biāo)簽進(jìn)行讀取 例:<%@ taglib uri="/struts-tags" prefix="s"%><s:text name="key"></s:text> 顯示的數(shù)據(jù)對(duì)應(yīng)的是properties文件中名為key的值, 此時(shí)輸出的內(nèi)容是全局資源包中的內(nèi)容 原因: 沒(méi)有經(jīng)過(guò)動(dòng)作類, 以及包, 直接搜索的是全局的資源包 當(dāng)經(jīng)過(guò)動(dòng)作類的時(shí)候, 就是按照搜素順序進(jìn)行搜索資源包
  • 獲取指定的資源包
  • 使用<s:i18n name="com.test.message"> 直接獲取message下面的properties文件

    Struts2中的攔截器

    Struts2中很多功能都是攔截器完成的, 并且都是AOP思想的一種體現(xiàn)

    自定義攔截器

    繼承AbstractInterceptor類或?qū)崿F(xiàn)Interceptor接口, 重寫(xiě)intercept方法 配置攔截器, 攔截器只有在配置的條件下才能使用

    例如:

    public class Demo1Interceptor extends AbstractInterceptor{public String intercept(ActionInvocation invocation) throws Exception{return null; } } //繼承AbstractInterceptor重寫(xiě)intercept方法 聲明攔截器: struts.xml: <interceptors><interceptor name="demo1Interceptor" class="com.interceptors.Demo1Interceptor" /> </interceptors> 使用攔截器: <action name="action1" class="com.interceptors.Demo1Interceptor" method="save"><interceptor-ref name="demo1Interceptor"></interceptor-ref><result>/success.jsp</result> </action> 在interceptors標(biāo)簽中可以配置多個(gè)攔截器聲明

    注:
    使用攔截器必須先聲明然后再使用, 并且一旦配置了任何一個(gè)攔截器, 默認(rèn)的攔截器就都失效了

    攔截器執(zhí)行順序

    下面通過(guò)例子說(shuō)明:

    Struts.xml: <struts><constant name="struts.devMode" value="true"></constant><package name="p1" extends="struts-default"><!--聲明攔截器列表--><interceptors><interceptor name="demo1Interceptor" class="com.interceptors.Demo1Interceptor" /></interceptors><action name="action1" class="com.interceptors.Demo1Interceptor" method="save"><!--使用攔截器--><interceptor-ref name="demo1Interceptor"></interceptor-ref><result>/success.jsp</result></action></package> </struts> 在攔截器類中的ntercept方法有如下操作: public String intercept(ActionInvocation invocation) throws Exception{System.out.println("攔截器執(zhí)行, 訪問(wèn)動(dòng)作方法之前");String result = invocation.invoke();System.out.println("攔截器執(zhí)行, 訪問(wèn)動(dòng)作方法后");return result; }Action類: public class Demo1Action extends ActionSupport{public String save(){System.out.println("動(dòng)作方法save執(zhí)行");return SUCCESS;} }success.jsp: <body><%System.out.println("success.jsp執(zhí)行了")%> </body> 當(dāng)訪問(wèn)save動(dòng)作的時(shí)候有如下的運(yùn)行順序:攔截器執(zhí)行了, 分文動(dòng)作之前動(dòng)作方法save執(zhí)行success.jsp執(zhí)行了攔截器執(zhí)行了, 訪問(wèn)動(dòng)作方法之后

    從上面的運(yùn)行順序可以得出一下結(jié)論:
    1.訪問(wèn)動(dòng)作方法之前一定會(huì)先執(zhí)行所有的攔截操作
    2.攔截操作執(zhí)行完,必須使用invocation的invoke方法做放行操作, 此處的操作類似于Filter中的doFilter操作
    3.當(dāng)動(dòng)作類, 以及結(jié)果視圖中的內(nèi)容執(zhí)行完之后又重新反向?qū)r截器都執(zhí)行一遍
    此處請(qǐng)看一下的Struts2的效果執(zhí)行圖:

    其實(shí)通過(guò)Struts2的執(zhí)行圖就可以看出, 多個(gè)攔截器的運(yùn)行過(guò)程, 在使用多個(gè)攔截器的時(shí)候, 它與單個(gè)攔截器的寫(xiě)法一樣

    intercept方法的返回值

    正如上面例子看到的一樣, intercept方法具有一個(gè)String類型的返回值
    String result = invocation.invoke();
    此時(shí)的result就是代表結(jié)果視圖, 代表動(dòng)作方法的返回值

    解決自定義攔截器條件下, 默認(rèn)攔截器出現(xiàn)無(wú)效的情況

    正如前面提到的, 當(dāng)我們使用自定義的攔截器的時(shí)候出現(xiàn)的問(wèn)題就是, 默認(rèn)系統(tǒng)提供的攔截器都會(huì)無(wú)效, 導(dǎo)致demo各種報(bào)錯(cuò)
    所以現(xiàn)在需要做的就是將Struts2提供的默認(rèn)的攔截器加載到我們的配置文件中
    有如下的解決方案:

  • 把默認(rèn)的攔截器加入到配置文件中
  • 將默認(rèn)的攔截器加入到配置文件, 需要做的就是在使用自定義攔截器之前, 在使用自定義的攔截器之前多加一個(gè)系統(tǒng)默認(rèn)的interceptor-ref使用 這里要注意的是, 系統(tǒng)默認(rèn)的攔截器不需要做聲明操作, 只需要在action標(biāo)簽中做修改 例:<action name="action1" class="com.interceptors.Demo1Interceptor" method="save"><!--使用系統(tǒng)默認(rèn)的攔截器--><interceptor-ref name="defaultStack"></interceptor-ref><!--使用自定義的攔截器--><interceptor-ref name="demo1Interceptor"></interceptor-ref><result>/success.jsp</result></action>

    但是上面的操作會(huì)暴露出一個(gè)問(wèn)題: 就是每當(dāng)我需要添加一個(gè)自定義的攔截器的時(shí)候都需要使用系統(tǒng)默認(rèn)的攔截器, 重復(fù)代碼過(guò)多, 所以下面采取的措施就是, 將每個(gè)action中的攔截器抽取出來(lái), 統(tǒng)一使用一個(gè)新的package管理, 然后在觸發(fā)action的時(shí)候使用攔截器
    例如:

    新建一個(gè)package <package name="mydefault" extends="struts-default"'><interceptors><!--聲明自定義的攔截器--><interceptor name="demo1Interceptor" class="com.interceptors.Demo1Interceptor"> </interceptor><!--聲明攔截器棧--><interceptor-stack name="myDefaultStack"><!--定義使用攔截器--><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="demo1Interceptor"></interceptor-ref></interceptor-stack></interceptors><!--覆蓋默認(rèn)攔截器定義使用參數(shù), 使用我們自定義的攔截器棧--><default-interceptor-ref name="myDefaultStack"></default-interceptor-ref> </package> 注: default-Interceptor-ref是struts-default中的標(biāo)簽, 它包含了struts2默認(rèn)的所有攔截器定義使用(ref) <package name="p2" extends="mydefault"><action name="A" class="com.test.action.Demo1Action" method="A"><result>/1.jsp</result> </action><action name="B" class="com.test.action.Demo1Action" method="B"><result>/2.jsp</result> </action> </package>

    經(jīng)過(guò)上面的修改之后, 在訪問(wèn)動(dòng)作A, B就不在需要進(jìn)行攔截器的定義聲明操作, 但是由此也暴露出一個(gè)問(wèn)題, 就是當(dāng)訪問(wèn)package p2下面的所有動(dòng)作, 都將會(huì)觸發(fā)攔截器, 如果有的動(dòng)作我們不想觸發(fā)攔截器, 那么就出現(xiàn)問(wèn)題, 所以針對(duì)上面的問(wèn)題, 有下面的解決方案
    2. 繼承AbstractInterceptor的抽象子類MethodFilterInterceptor
    MethodFilterInterceptor將AbstractInterceptor的抽象方法intercept重寫(xiě), 但是具有一個(gè)新的抽象方法doIntercept(ActionInvocation invocation);
    MethodFilterInterceptor中具有兩個(gè)屬性:
    Set< String> excludeMethods //哪些動(dòng)作不需要攔截
    Set< String> includeMethods //哪些動(dòng)作需要攔截
    上面的兩個(gè)屬性可以做注入操作, 通過(guò)配置struts.xml的方式做到配置攔截操作
    所以在自定義攔截器的時(shí)候, extends MethodFilterInterceptor類, 實(shí)現(xiàn)doIntercept(ActionInvocation invocation);

    //Interceptor中寫(xiě)法 public class CheckLogin2Interceptor extends MethodFilterInterceptor{protected String doIntercept(ActionInvocation invocation) throws Exception{HttpSession session = ServletActionContext.getRequest().getSession();Objective obj = session.getAttribute("user");if (obj != null){String result = invocation.invoke();return result; }else{return "error"; }} } //struts.xml寫(xiě)法 <package name="mydefault" extends="struts-default"'><interceptors><interceptor name="checkLogin2Interceptor" class="com.interceptors.CheckLogin2Interceptor"></interceptor><interceptor-stack name="myDefaultStack"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="checkLogin2Interceptor"><!--對(duì)A方法不攔截--><param name="excludeMethods">A</param></interceptor-ref></interceptor-stack></interceptors><default-interceptor-ref name="myDefaultStack"></default-interceptor-ref> </package> <package name="p2" extends="mydefault"><action name="A" class="com.test.action.Demo1Action" method="A"><result>/1.jsp</result> </action><action name="B" class="com.test.action.Demo1Action" method="B"><result>/2.jsp</result> </action> </package>

    注: 當(dāng)我們需要進(jìn)行方法攔截的時(shí)候, 就可以通過(guò)注入的方式, 進(jìn)行指定攔截, 但是也暴露了一個(gè)問(wèn)題, 如果只有在確定動(dòng)作類, 動(dòng)作方法之后才能確定param中的參數(shù)
    所以針對(duì)這個(gè)問(wèn)題, 有下面的解決方案:

    我們不在攔截器定義使用的時(shí)候, 而是在觸發(fā)action的時(shí)候?qū)μ囟ǖ姆椒ㄊ褂锰囟ǖ臄r截器 上面struts.xml有如下的修改: <package name="mydefault" extends="struts-default"'><interceptors><interceptor name="checkLogin2Interceptor" class="com.interceptors.CheckLogin2Interceptor"></interceptor><interceptor-stack name="myDefaultStack"><interceptor-ref name="defaultStack"></interceptor-ref><!--此處不配置param參數(shù)--><interceptor-ref name="checkLogin2Interceptor"></interceptor-ref></interceptor-stack></interceptors><!--自定義默認(rèn)攔截器棧--><default-interceptor-ref name="myDefaultStack"></default-interceptor-ref> </package> <package name="p2" extends="mydefault"><action name="A" class="com.test.action.Demo1Action" method="A"><!--在action中配置interceptor--><interceptor-ref name="myDefaultStack"><!--對(duì)自定義的checkLogin2Interceptor攔截器中的excludeMethods, 進(jìn)行參數(shù)注入操作, 在觸發(fā)A動(dòng)作的時(shí)候, 不攔截A操作--><param name="checkLogin2Interceptor.excludeMethods">A</param></interceptor-ref><result>/1.jsp</result></action><action name="B" class="com.test.action.Demo1Action" method="B"><result>/2.jsp</result> </action> </package>

    攔截器類圖
    // 從網(wǎng)上找的

    Struts2的文件上傳與下載

    文件上傳

    與Servlet中的文件上傳一樣, Struts2中的文件上傳必須明確:
    1.表單method為post
    2.enctype取值必須是multipart/form-data
    3.提供文件選擇域
    下面使用Struts2提供的標(biāo)簽進(jìn)行演示:

    <s:form action="upload" enctype="multipart/form-data"><s:textfield name="username" lable="用戶名"></s:textfield><s:file name="photo" lable="照片"></s:file><s:submit value="提交"></s:submit> <s:form>

    注: Struts2中使用file標(biāo)簽進(jìn)行文件上傳, Struts2文件上傳的底層實(shí)現(xiàn)還是commons-fileupload和commons-io
    動(dòng)作類:

    public class UploadAction extends ActionSupport{private String username;private File photo; //上傳字段private String photoFileName; //上傳文件名, 固定寫(xiě)法, 上傳字段名稱+FileName(區(qū)分大小寫(xiě))private String photoContentType; //上傳文件的MIME類型, 固定寫(xiě)法, 上傳文件名+ContentType(區(qū)分大小寫(xiě))//在上傳文件后, struts會(huì)自動(dòng)對(duì)這兩個(gè)屬性做注入處理public String upload(){String dir = ServletActionContext.getServletContext().getRealPath("/WEB-INF/files");//獲取files路徑File file = new File(dir);if (!file.exists()){file.mkdirs(); }photo.renameTo(new File(File, photoFileName));//將上傳的photo存入file中return null;}//下面一堆get, set方法, 我就不寫(xiě)了

    struts.xml:

    <!--覆蓋默認(rèn)的maxSize大小, 默認(rèn)大小為2M--> <constant name="struts.multipart.maxSize" value="5242880"></constant> <package name="upload" extends="struts-default"><action name="upload" class="com.action.UploadAction" method="upload"><interceptor-ref name="defaultStack"><!--使用默認(rèn)的fileUpload攔截器, 對(duì)extension做注入處理, 限制上傳文件擴(kuò)展名--><param name="fileUpload.allowedExtension">jpg.png</param><!--限制上傳文件類型--><param name="fileUpload.allowedTypes">image/jpg, image/pjpeg,image/png</param></interceptor-ref><result name="input">/upload.jsp</result></action> </package>

    修改上傳文件出現(xiàn)的錯(cuò)誤信息提示
    當(dāng)上傳文件的時(shí)候會(huì)出現(xiàn), 文件類型/大小/后綴名…錯(cuò)誤, 需要通過(guò)國(guó)際化的方式修改錯(cuò)誤提示信息
    有如下操作:
    1.創(chuàng)建資源文件, 例如: fileuploadmessage.properties 放在src下
    2.添加錯(cuò)誤信息, 例如: struts.messages.error.uploading=上傳錯(cuò)誤:{0}, 其余key查閱struts2-core.jar\org.apache.struts2\struts-message.properties, 只需要將value中英文值修改即可
    3.在struts.xml中使用< constant name=“struts.custom.i18n.resource” value=“com…fileuploadmessage”/>, value代表資源文件位置
    多文件上傳
    多文件上傳, 在jsp中, 只需多添加file標(biāo)簽, 在UploadAction中修改上傳字段, 上傳文件名, 上傳文件類型為數(shù)組/list類型即可, struts會(huì)自動(dòng)將上傳的file分配到數(shù)組/list中

    文件下載

    文件下載是一種結(jié)果類型(Stream)

    Action類: public class DownloadAction extends ActionSupport{private InputStream fileInputStream; //此處字段名不能寫(xiě)in, 會(huì)報(bào)錯(cuò)public String download() throws Exception{String filePath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/files/1.jpg");fileInStream = new FileInputStream(filePath);return SUCCESS;}//下面一堆get, set操作, 進(jìn)行注入 } struts.xml配置: <action name="download" class="com.action.DownloadAction" method="download"><result name="success" type="stream"><!--配置inputName屬性, 將action類中的輸入流--><param name="inputName">fileInputStream</param><!--設(shè)置響應(yīng)消息頭, 告知瀏覽器以下載的方式打開(kāi)--><param name="contentDisposition">attachment;filename=image.jpg</param><!--設(shè)置響應(yīng)消息頭, 告知瀏覽器, 響應(yīng)正文的MIME類型--><param name="contentType">application/octet-stream</param></result> </action> 注: 在寫(xiě)filename會(huì)出現(xiàn)文件名寫(xiě)死的情況, 所以采用OGNL表達(dá)式解決, 寫(xiě)成: filename=${filename}, 在action類中獲取filename屬性, 注入處理

    OGNL

    OGNL類似于EL表達(dá)式, Struts2表達(dá)式語(yǔ)言, 在Struts2中使用OGNL必須使用Struts2標(biāo)簽庫(kù)
    例:

    <s:property value="'OGNL_Expression'"> s:property類似于EL中<%=%>操作, value代表輸出的內(nèi)容, 雙引號(hào)中的內(nèi)容就是一個(gè)OGNL表達(dá)式

    在OGNL中可以調(diào)用普通方法, 靜態(tài)方法, 使用靜態(tài)變量, 但是在EL表達(dá)式中只能使用靜態(tài)方法
    調(diào)用方法的時(shí)候, 需要寫(xiě)出當(dāng)前方法的完整路徑, 并且在路徑以及方法名前加"@"符號(hào)
    當(dāng)調(diào)用靜態(tài)方法的時(shí)候, 需要開(kāi)啟OGNL靜態(tài)訪問(wèn): < constant name=“struts.ognl.allowStaticMethodAccess” value=“true”></ constant>
    此時(shí)才能在OGNL中調(diào)用靜態(tài)方法
    例:

    <s:property value="@java.lang.Math@random">

    在form表單中, radio以及check中就有OGNL的應(yīng)用
    例:

    <s:radio name="gender" list="{'男', '女'}"></s:radio> <s:radio name="gender" list="#{'1':'男', '0':"女"}"> 創(chuàng)建List集合使用"{}", List的value直接就是男 創(chuàng)建Map對(duì)象使用"#{}", 上面的'1'代表男的value, key作為標(biāo)簽的value

    contextMap

    contextMap主要用于存放每次動(dòng)作訪問(wèn)的數(shù)據(jù)
    每次執(zhí)行動(dòng)作之前, 核心控制器StrutsPrepareAndExecuteFilter都會(huì)創(chuàng)建一個(gè)ActionContext和ValueStack對(duì)象。且每次動(dòng)作訪問(wèn)都會(huì)創(chuàng)建, 這兩個(gè)對(duì)象存儲(chǔ)了整個(gè)動(dòng)作訪問(wèn)期間用到的數(shù)據(jù)。并且把數(shù)據(jù)綁定到了線程局部變量(ThreadLocal)上
    動(dòng)作類是多例的, 每次動(dòng)作訪問(wèn)都會(huì)實(shí)例化, 確保線程安全
    contextMap中存放的內(nèi)容

    1.valuestack(root) : java.util.List; list類型, 非map 2.application: java.util.Map<String, Object>; 存放ServletContext中所有屬性 3.session: java.util.Map<String, Object>; 存放HttpSession中所有屬性 4.request: java.util.Map<String, Object>; 存放ServletRequest中所有屬性 5.parameters: java.util.Map<String, Object>; 存放各種參數(shù) 6.attr: java.util.Map<String, Object>; 存放頁(yè)面, 請(qǐng)求, 會(huì)話, 應(yīng)用范圍內(nèi)的所有屬性

    注: 除valuestack是list, 其余都是map, contextMap也是map

    未完待續(xù)~~

    上面有錯(cuò), 還請(qǐng)指出, 如果認(rèn)為我寫(xiě)的還不錯(cuò), 還請(qǐng)點(diǎn)個(gè)贊, 多多支持一下, O(∩_∩)O~~

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

    總結(jié)

    以上是生活随笔為你收集整理的Struts2_3_国际化处理_自定义拦截器_文件上传及下载_OGNL的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。