Struts2国际化
同一款软件 可以为不同的用户 提供不同语言界面
需要一个语言资源包 (里面有properties文件,每个properties文件针对每一个语言)通过java程序根据来访者语言,自动读取不同的properties文件
资源包命名规则:基本名称_语言(小写)_国家(大写).properties
如 messages_zh_CN.properties message_en_US.properties
ResourceBundle根据不同locale,读取不同国家properties文件
定义properties文件
通过常量声明 在default_properties中有 struts.custom.i18n.resources=testmessages,testmessages2(被注释掉)
在struts.xml文件下定义 (properties配置文件可以放置在任意位置)
<constant name="struts.custom.i18n.resources"value="message"> 表明message.properties在src下
<constant name="struts.custom.i18n.resources"value="cn.demo.i18n.resource.message">表明message.properties在cn.demo.i18n,resource包下
局部定义
1 针对action类 (只对当前action有效)
位置:与action类在同一个包下
名称:ActionClassName.properties
2 针对package下所有action
位置:在指定的包下
名称:package.properties
3 jsp页面临时使用的某一个properties文件
<s:i18n name=" "></s:i18n>
使用 在struts2操作
在action中使用 action中继承ActionSupport类 getText(String name)可以获取配置文件中对应名称的值
在validation.xml中使用 <message key="名称"/>
在jsp页面上使用 <s:text name="名称"> 通过name属性指定 包名.配置文件名称
在action中使用动态文本msg=hello world {0}
this.getText("msg",new String[]{"tom"})
结果就是 hello world tom
在jsp页面中使用动态文本
msg=hello world {0}
<s:i18n name="cn.itcast.action.I18nDemo1Action">
<s:text name="msg">
<s:param>张三</s:param>
</s:text>
</s:i18n>
结果就是 hello world 张三.
拦截器
struts2中 可以定义很多拦截器 多个拦截器按照特定顺序 组成拦截器栈 默认加载18个拦截器 位于defaultStack
拦截器的使用 采用了责任链模式
由每一个对象对其下家的引用而连接形成一条链
责任链上的每一个节点 都可以继续调用下一个节点 也可以阻止流程继续执行
自定义拦截器
实现 com.opensymphony.xwork2.interceptor.interceptor接口
init() destory() intercept(ActionInvocation ai) 真正拦截的方法
ai.invoke(); 继续向下执行
在struts-default.xml中 声明
<interceptors>
<interceptor name=" "class=" "/>
</interceptors>
在sturts.xml 中的action配置
<interceptor-ref name="my"> 只要声明 使用了一个拦截器 默认的拦截器就不会加载
拦截器实现action中某些方法的拦截
常见类 继承 MethodFilterInterceptor 重写 doIntercept方法
在struts.xml文件中 声明
<interceptors>
<intercept name=" " class=" " >
<param name="includeMethods"> </param> 要拦截的方法
<param name="excludeMethod"> </param>
</intercept>
</interceptors>
拦截器原理
1 在StrutsPrepareAndExecuteFilter中 doFilter中 execute.executeAction (request, response, mapping) 执行action操作
2 在executeAction执行过程中会访问Dispatcher类中的serviceAction,在这个方法中会创建一个Action的代理对象
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext, true, false);
3 DefaultActionInvocation中 invoke 通过递归完成拦截操作 并且将interceptorMsg 压入栈中
拦截器与过滤器的区别
拦截器基于java反射机制 过滤器基于函数回调
拦截器不依赖于servlet容器 过滤器依赖servlet容器
拦截器只对action请求起作用 过滤器对所有请求起作用
拦截器可以访问Action上下文 值栈中的对象
在Action生命周期中,拦截器可以多次调用 过滤器只能在容器初始化时被调用一次
struts2文件上传与下载
常规上传
浏览器端:method=post <input type="file"name="XX" > encType="multipart/form-data";
服务器端:commons-fileupload组件 DiskFileItemFactory ServletFileUpload FileItem
struts2中文件上传
默认使用commons-fileupload组件 并且使用 FileUploadInterceptor 完成文件上传操作
在default.properties中 默认上传方式为 struts.multipart.multipart.paser=jakarta; 还有cos pell被注释掉了
默认大小为2mb 在default.properties文件中定义 struts.multipart.maxSize=2097152
上传步骤
页面上 <input type="file" name="upload">
页面上配置<s:actionerror>展示错误信息 要呈现为中文错误信息 可以使用国际化 定义struts.messages.properties并添加中文错误信息
在action上有三个属性
private File upload; private String uploadContentType; private String uploadFileName;
在execute方法中使用 commons-io包下的FileUtils
FileUtils.copyFile(upload,new File("d:/",uploadFileName)); 完成文件复制
多文件上传
服务器端:将action中的属性修改为list集合或者数组
private List<File> upload;
private List<String> uploadContentType;
private List<String> uploadFileName;
在FileUploadInterceptor中对其属性进行控制
maximumSize 每一个上传文件大小
allowedTypes 允许上传文件的mimeType类型
allowedExtensions 允许上传文件的后缀名
<action name=""upload"class="cn.demo.UploadAction">
<result name="input">/ .jsp</result>
<interceptor ref name="defaultStack">
<param name="fileUpload.allowedExtensions">txt,mp3,doc</param>
</interceptor-ref>
</action>
文件下载
常见下载方式:1 超链接 2 服务器编码 通过流向客户端写回
通过response 设置 setContentType(String mimetype) setHeader("Content-disposition;filename="xxx"") 获取流 将下载的信息写出
struts2文件下载
通过<result type="stream"class="org.apache.struts2.dispatcher.StreamResult">
protected String contentType="text/plain"; 用于下载文件的mimeType类型
protected String contentDisposition="inline"; 用于设置进行下载操作以及 下载文件的名称
protected InputStream inputStream; 用于读取要下载的文件
<action name="download"class="cn.demo.DownloadAction">
<result type="stream">
<param name="contentType">${contentType}</param> 调用action中的getContentType()方法
<param name="contentDisposition">attachment;filename=a.txt</param>
<param name="inputStream">${inputStream}</param> 调用action中的getInputSteam()方法
</result>
</action>
存在缺陷 客户端下载之后取消下载 服务器端会产生异常 解决方案:使用struts2下载插件