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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

Struts2國際化處理

瀏覽器根據當前的語言環境自動查找對應的語言環境資源包, 使jsp顯示合適的語言數據環境
Struts2實現國際化, 動作類必須繼承ActionSupport

  • 創建資源包
  • 資源包由多個properties文件組成, properties文件的文件名必須滿足命名規范: 文件名_語言代碼_國家代碼.properties 語言代碼/國家代碼由iso規定 例: ms_zh_CN.properties 注:當properties文件命名為: 文件名.properties表名它為默認的資源包, 當瀏覽器沒有找到對應的語言資源包的時候, 就會使用默認的資源包
  • 配置資源包
  • 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. 配置包范圍的資源包命名規范: package_語言代碼_國家代碼.properties(固定命名格式)使用這種命名規范, 資源包只能被該包或子包的動作類訪問 3. 局部資源包命名規范: 動作名稱_語言代碼_國家代碼.properties只為動作類服務 注:資源包的搜索順序, 滿足就近原則: 局部 > 包 > 全局
  • 在jsp中讀取資源包中內容
  • 借助struts2的標簽進行讀取 例:<%@ taglib uri="/struts-tags" prefix="s"%><s:text name="key"></s:text> 顯示的數據對應的是properties文件中名為key的值, 此時輸出的內容是全局資源包中的內容 原因: 沒有經過動作類, 以及包, 直接搜索的是全局的資源包 當經過動作類的時候, 就是按照搜素順序進行搜索資源包
  • 獲取指定的資源包
  • 使用<s:i18n name="com.test.message"> 直接獲取message下面的properties文件

    Struts2中的攔截器

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

    自定義攔截器

    繼承AbstractInterceptor類或實現Interceptor接口, 重寫intercept方法 配置攔截器, 攔截器只有在配置的條件下才能使用

    例如:

    public class Demo1Interceptor extends AbstractInterceptor{public String intercept(ActionInvocation invocation) throws Exception{return null; } } //繼承AbstractInterceptor重寫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標簽中可以配置多個攔截器聲明

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

    攔截器執行順序

    下面通過例子說明:

    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("攔截器執行, 訪問動作方法之前");String result = invocation.invoke();System.out.println("攔截器執行, 訪問動作方法后");return result; }Action類: public class Demo1Action extends ActionSupport{public String save(){System.out.println("動作方法save執行");return SUCCESS;} }success.jsp: <body><%System.out.println("success.jsp執行了")%> </body> 當訪問save動作的時候有如下的運行順序:攔截器執行了, 分文動作之前動作方法save執行success.jsp執行了攔截器執行了, 訪問動作方法之后

    從上面的運行順序可以得出一下結論:
    1.訪問動作方法之前一定會先執行所有的攔截操作
    2.攔截操作執行完,必須使用invocation的invoke方法做放行操作, 此處的操作類似于Filter中的doFilter操作
    3.當動作類, 以及結果視圖中的內容執行完之后又重新反向將攔截器都執行一遍
    此處請看一下的Struts2的效果執行圖:

    其實通過Struts2的執行圖就可以看出, 多個攔截器的運行過程, 在使用多個攔截器的時候, 它與單個攔截器的寫法一樣

    intercept方法的返回值

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

    解決自定義攔截器條件下, 默認攔截器出現無效的情況

    正如前面提到的, 當我們使用自定義的攔截器的時候出現的問題就是, 默認系統提供的攔截器都會無效, 導致demo各種報錯
    所以現在需要做的就是將Struts2提供的默認的攔截器加載到我們的配置文件中
    有如下的解決方案:

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

    但是上面的操作會暴露出一個問題: 就是每當我需要添加一個自定義的攔截器的時候都需要使用系統默認的攔截器, 重復代碼過多, 所以下面采取的措施就是, 將每個action中的攔截器抽取出來, 統一使用一個新的package管理, 然后在觸發action的時候使用攔截器
    例如:

    新建一個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><!--覆蓋默認攔截器定義使用參數, 使用我們自定義的攔截器棧--><default-interceptor-ref name="myDefaultStack"></default-interceptor-ref> </package> 注: default-Interceptor-ref是struts-default中的標簽, 它包含了struts2默認的所有攔截器定義使用(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>

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

    //Interceptor中寫法 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寫法 <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"><!--對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>

    注: 當我們需要進行方法攔截的時候, 就可以通過注入的方式, 進行指定攔截, 但是也暴露了一個問題, 如果只有在確定動作類, 動作方法之后才能確定param中的參數
    所以針對這個問題, 有下面的解決方案:

    我們不在攔截器定義使用的時候, 而是在觸發action的時候對特定的方法使用特定的攔截器 上面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參數--><interceptor-ref name="checkLogin2Interceptor"></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"><!--在action中配置interceptor--><interceptor-ref name="myDefaultStack"><!--對自定義的checkLogin2Interceptor攔截器中的excludeMethods, 進行參數注入操作, 在觸發A動作的時候, 不攔截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>

    攔截器類圖
    // 從網上找的

    Struts2的文件上傳與下載

    文件上傳

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

    <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標簽進行文件上傳, Struts2文件上傳的底層實現還是commons-fileupload和commons-io
    動作類:

    public class UploadAction extends ActionSupport{private String username;private File photo; //上傳字段private String photoFileName; //上傳文件名, 固定寫法, 上傳字段名稱+FileName(區分大小寫)private String photoContentType; //上傳文件的MIME類型, 固定寫法, 上傳文件名+ContentType(區分大小寫)//在上傳文件后, struts會自動對這兩個屬性做注入處理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方法, 我就不寫了

    struts.xml:

    <!--覆蓋默認的maxSize大小, 默認大小為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"><!--使用默認的fileUpload攔截器, 對extension做注入處理, 限制上傳文件擴展名--><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>

    修改上傳文件出現的錯誤信息提示
    當上傳文件的時候會出現, 文件類型/大小/后綴名…錯誤, 需要通過國際化的方式修改錯誤提示信息
    有如下操作:
    1.創建資源文件, 例如: fileuploadmessage.properties 放在src下
    2.添加錯誤信息, 例如: struts.messages.error.uploading=上傳錯誤:{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標簽, 在UploadAction中修改上傳字段, 上傳文件名, 上傳文件類型為數組/list類型即可, struts會自動將上傳的file分配到數組/list中

    文件下載

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

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

    OGNL

    OGNL類似于EL表達式, Struts2表達式語言, 在Struts2中使用OGNL必須使用Struts2標簽庫
    例:

    <s:property value="'OGNL_Expression'"> s:property類似于EL中<%=%>操作, value代表輸出的內容, 雙引號中的內容就是一個OGNL表達式

    在OGNL中可以調用普通方法, 靜態方法, 使用靜態變量, 但是在EL表達式中只能使用靜態方法
    調用方法的時候, 需要寫出當前方法的完整路徑, 并且在路徑以及方法名前加"@"符號
    當調用靜態方法的時候, 需要開啟OGNL靜態訪問: < constant name=“struts.ognl.allowStaticMethodAccess” value=“true”></ constant>
    此時才能在OGNL中調用靜態方法
    例:

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

    在form表單中, radio以及check中就有OGNL的應用
    例:

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

    contextMap

    contextMap主要用于存放每次動作訪問的數據
    每次執行動作之前, 核心控制器StrutsPrepareAndExecuteFilter都會創建一個ActionContext和ValueStack對象。且每次動作訪問都會創建, 這兩個對象存儲了整個動作訪問期間用到的數據。并且把數據綁定到了線程局部變量(ThreadLocal)上
    動作類是多例的, 每次動作訪問都會實例化, 確保線程安全
    contextMap中存放的內容

    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>; 存放各種參數 6.attr: java.util.Map<String, Object>; 存放頁面, 請求, 會話, 應用范圍內的所有屬性

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

    未完待續~~

    上面有錯, 還請指出, 如果認為我寫的還不錯, 還請點個贊, 多多支持一下, O(∩_∩)O~~

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美黑人多人双交 | 滋润少妇h高h | 久久久久久久久久久影院 | 性欧美video另类hd尤物 | 久久99精品久久久久久琪琪 | 人人超碰97| av成人免费观看 | 欧美精品亚洲精品 | 欧美色亚洲色 | 亚洲熟妇毛茸茸 | 最新中文字幕第一页 | 九九爱爱视频 | 九色porny原创自拍 | 日日爽爽 | 国产偷拍一区二区三区 | 少妇被躁爽到高潮 | 九九九免费视频 | 日韩专区一区 | 日韩一区二区在线观看 | 狂野欧美性猛交blacked | 涩色网| 美女插插 | 亚洲最大成人在线视频 | 六月婷婷av | 特级毛片在线播放 | 人人妻人人澡人人爽欧美一区双 | 500福利视频导航 | 一区二区小说 | 国产成人免费片在线观看 | 三级中文字幕在线 | 欧美中日韩在线 | 91精品国产91久久久久福利 | 久久国产网 | 日本少妇喷水视频 | 欧美一区二区三区婷婷 | 亚洲第8页 | 天天鲁 | 激情草逼 | 亚洲精品乱码久久久久久蜜桃麻豆 | 亚洲人xxx日本人18 | 深夜影院深a | 一区二区在线不卡 | 一级伦理农村妇女愉情 | av中亚| 九七精品 | 国产男男网站 | 日韩人妻精品一区二区三区 | wwwxxx在线观看 | 伊人五月天 | 国产美女久久久 | 国产精品毛片久久久久久 | 伊人网视频在线 | 日韩在线观看视频一区 | 一本一道久久a久久精品综合 | 在线观看v片 | 日韩av资源网 | 无码精品黑人一区二区三区 | 成人欧美精品一区二区 | 91在线视频免费看 | 国产一区二区三区色淫影院 | 国产免费又粗又猛又爽 | 久久久在线观看 | 永久免费视频网站直接看 | 性爱动漫| 国产中文字幕一区二区 | 污污的网站在线观看 | 美国黄色一级视频 | 婷婷激情五月综合 | 国产成人一区二区在线 | 亚洲日本一区二区三区 | 99在线视频精品 | 亚洲综合色自拍一区 | 91丨国产丨捆绑调教 | 色小姐综合网 | 成人做爰的视频 | 国产成人影视 | 亚洲色图另类小说 | 国产一区二区三区在线看 | 国产一级片免费 | www.男人天堂| 亚洲熟妇毛茸茸 | 亚洲精品视屏 | 久久精品黄aa片一区二区三区 | 亚洲精选一区二区三区 | 国产高清精品在线观看 | 91免费看大片 | 亚洲综合在线视频 | 性高潮久久久久 | 日韩爱爱片 | 夜夜躁很很躁日日躁麻豆 | 天天摸天天 | 中文字幕电影av | 我要看免费毛片 | 一区二区三区免费看视频 | 日韩精品一区二 | 在线观看国产亚洲 | 亚洲一区二区三区蜜桃 | 在线黄色网 | 欧美日韩国产色 |