Struts2干货笔记——第三天

目录

1. Struts2国际化
  • 1.1 资源包的编写
  • 1.2 国际化配置
  • 1.3 在struts2中国际化操作可以在哪些位置使用?
  • 1.4 在struts2中操作国际化?
2. 拦截器
  • 2.1 怎样使用拦截器
  • 2.2 常用拦截器
  • 2.3 怎样解决只让action中某些方法被拦截?
  • 2.4 关于interceptor与Filter区别
3. 文件上传和下载
  • 3.1 在action中怎样处理文件上传?
  • 3.2 多个文件同时上传
  • 3.3 控制上传文件的大小以及上传文件的类型
  • 3.4 struts2中文件的下载

Struts2国际化

国际化(Internationalization-i18N,以I开始以N结束,共18个字母)是指Web应用程序根据当前机器的语言环境采用与当前语言环境相符的消息资源文件来显示Web内容,简单来说,就是一个程序在美国显示"Hello world",而在中国显示"你好 世界"。
实行国际化需要一个语言资源包(很多properties文件,每个properties文件 针对一个国家或者语言 ,通过java程序根据来访者国家语言,自动读取不同properties文件 )

资源包的编写
  1. properties文件命名 : baseName_language(小写) _country(大写).properties
    其中baseName是资源文件的基本名称,可以自定义,language和country必须是java支持的语言和国家。
    例如 :
    messages_zh_CN.properties 中国中文
    messages_en_US.properties 美国英文
  2. ResourceBundle 根据不同Locale(地域信息),读取不同国家 properties文件
    ResourceBundle bundle = ResourceBundle.getBundle("messages", Locale.US);

struts2中对国际化进行了封装,我们只需要根据其提供的API进行访问就可以。

国际化配置
  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页面或者action中访问国际化信息

  • 在jsp页面中使用<s:test name=" " />标签输出国际化信息,等价于<lable></lable>,name为资源文件中的key
  • 在Action类中,可以继承ActionSupport,使用getTest()方法得到国际化信息,该方法的第一个参数用于指定资源文件中的key。
  • 在表单标签中,通过key属性指定资源文件中的key,<s:textfield name="realname" key="user" />
  1. 局部
  • 针对于Action类
    当一些显示数据只会被某个action使用,这时候我们可以把这些显示数据定义在只能被该action访问的Action范围资源文件中,为某个action指定资源文件,如:在Action类所在的路径下放置ActionClassName_language_country.properties资源文件,在ActionClassName为action类的简单名称。当查找指定key的消息时,系统会先从ActionClassName_language_country.properties资源文件查找,如果没有找到对应的key,然后沿着当前包往上查找基本名为package的资源文件,一直找到顶层包,如果还没有找到对应的key,最后会从常量struts.custom.i18n.resources指定的资源文件中寻找

  • 针对于一个package下的所有action
    在一个大型应用中,整个应用有大量的内容需要实现国际化,如果我们把国际化的内容都放置在全局资源属性文件中,显然会导致资源文件变得过于庞大、臃肿,不便于维护,这个时候我们可以针对不同模块,使用包范围来组织国际化文件。
    在指定的包下放置package.properties文件,处于该包以及包下的action都可以访问该资源,当查找指定key的消息时,系统会先从package资源文件查找,当找不到对应的key时,才会从常量struts.custom.i19n.resources指定的资源文件中寻找。

  • jsp页面临时使用某一个properties文件
    在Struts2中提供了<s:i18n>标签,使用<s:i18n>标签我们可以直接从类路径下的某个资源文件中获取国际化数据,而无需任何配置:

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

访问com.java.action包下基本名为welcome的资源文件。

在struts2中国际化操作可以在哪些位置使用?(在哪此位置上使用)
  1. action类中使用
  2. 配置文件中使用<validation.xml>
  3. 在jsp页面上使用
在struts2中操作国际化?(怎样使用)
  1. 在action类中使用
    前提:action类要继承ActionSupport类。
    getText(String name)就可以获取配置文件中对应名称的值。
  2. 在validation.xml文件中使用
    <message key="名称"/>
  3. 在jsp页面上使用
    <s:text name="名称"> 如果没有使用<s:i18n name="">来指定,会从全局配置文件中获取。如果要从某一个配置文件中获取,通过name属性来指定, 包名.配置文件名称 。

拦截器

Struts2的拦截器和Servlet过滤器比较类似,在执行Action的execute方法之前,Struts2会首先执行在struts.xml中引用的拦截器,在执行完所有引用的拦截器的intercept方法后,会执行Action的execute方法。

struts2拦截器使用的是AOP思想,AOP的底层实现就是动态代理,拦截器采用责任链模式,在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链,责任链每一个节点,都可以继续调用下一个节点,也可以阻止流程继续执行。
struts2中在struts-default.xml文件中声明了所有的拦截器。
而struts2框架默认使用的是defaultStack这个拦截器栈。
在这个拦截器栈中使用了18个拦截器。简单说,struts2框架在默认情况下,加载了18个拦截器。

怎样使用拦截器

拦截器的使用相对比较简单,只需要在struts.xml文件的Action中添加<interceptor-ref>标记,用于指定具体使用哪一个定义好的拦截器即可。例如,有一个已经配置好的拦截器hellointerceptor。

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

当用户使用了一个自定义拦截器后,系统默认的拦截器就会自动失效,为了还能使用系统默认的拦截器,需要在struts.xml文件中手动添加系统默认拦截器,系统默认拦截器栈名称是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"/> 模型驱动
<interceptor-ref name="fileUpload"/>文件上传
<interceptor-ref name="params"> 参数解析封装
<interceptor-ref name="conversionError"/> 类型转换错误
<interceptor-ref name="validation"> 请求参数校验
<interceptor-ref name="workflow"> 拦截跳转 input 视图

怎样解决只让action中某些方法被拦截?
  1. 创建类不在实现Interceptor接口,而是继承其下的一个子类.MethodFilterInterceptor不用在重写intercept方法,而是重写 doIntercept方法。
  2. 在struts.xml文件中声明
    <interceptors>
    <intercept name="" class="">
    <param name="includeMethods">add,update,delete</param>
    <param name="excludeMethods">search</param>
    </intercept>
    </interceptors>
关于interceptor与Filter区别
  1. 拦截器是基于java反射机制的,而过滤器是基于函数回调的。
  2. 过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。
  3. 拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请求起作用。
  4. 拦截器可以访问Action上下文、值栈里的对象,而过滤器不能。
  5. 在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次。

文件上传和下载

要想使用HTML表单上传一个或者多个文件,必须把HTML表单的enctype属性设置为multipart/form-data,把它的method属性设置为post,为了让用户能够选择一个文件进行上传,程序员必须提供一个<input type="file">字段。
默认情况下struts2框架使用的就是commons-fileupload组件,struts2它使用了一个interceptor帮助我们完成文件上传操作。
<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>

在action中怎样处理文件上传?
  1. 在JSP页面的文件上传表单里使用file标签,如果需要一次上传多个文件,就必须使用多个file标签,但它们的名字必须是相同的
  2. 在Action中新添加3个和文件上传相关的属性,这三个属性的名字必须是以下各式
private File upload; //上传的文件
private String uploadContentType; //上传文件的类型
private String uploadFileName;  //上传文件的名称

其中upload是jsp页面上file标签的name属性值<input type="file" name="upload">
如果是上传单个文件,upload属性类型就是File,它代表被上传的文件,第二个和第三个属性类型是String,它们分别代表上传文件的文件名和文件类型。定义的方式分别是jsp页面file组件的name属性值+ContentType和jsp页面file组件的name属性值+FileName,如果上传多个文件,可以使用数组或者List。

  1. 在execute方法中使用commons-io包下的FileUtils完成文件复制.
FileUtils.copyFile(upload, new File("d:/upload",uploadFileName));
多个文件同时上传

在服务器端只需要将action属性声明成List集合或数组就可以。

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

在fileupload拦截器中,通过其属性进行控制.
maximumSize---每一个上传文件大小
allowedTypes--允许上传文件的mimeType类型.
allowedExtensions--允许上传文件的后缀名.

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

定义一个action类继承ActionSupport类
struts2提供了stream结果类型,该结果类型就是专门用于支持文件下载功能的
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
在StreamResult类中有三个属性:

  • protected String contentType = "text/plain"; //用于设置下载文件的mimeType类型
  • protected String contentDisposition = "inline";//用于设置进行下载操作以及下载文件的名称
  • protected InputStream inputStream; //用于读取要下载的文件。
    在action类中定义一个方法
public InputStream getInputStream() throws FileNotFoundException {
    FileInputStream fis = new FileInputStream("d:/upload/" + filename);
        return fis;
}

在配置时

<result type="stream">
    <param name="contentType">${contentType}</param>//会调用当前action中的getContentType()方法。
    <param name="contentDisposition">attachment;filename=${downloadFileName}</param>
    <param name="inputStream">${inputStream}</param> //会调用当前action中的getInputStream()方法。
</result>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容