2014-08-12|1774阅|作者:jun|举报 摘要:1.国际化(了解)
2.拦截器(重点)
3.文件上传与下载(次重点)
4.ognl与valueStack(重点)
==========================================================
1.国际化
1、 国际化原理 ? 什么是国际化 ?
同一款软件 可以为不同用户,提供不同语言界面 ---- 国际化软件
需要一个语言资源包(很多properties文件,每个properties文件 针对一个国家或者语言 ,通过java程序根据来访者国家语言,自动读取不同properties文件 )
2、 资源包编写
properties文件命名 : 基本名称_语言(小写)_国家(大写).properties
例如 :
messages_zh_CN.properties 中国中文
messages_en_US.properties 美国英文
3、 ResourceBundle 根据不同Locale(地域信息),读取不同国家 properties文件
ResourceBundle bundle = ResourceBundle.getBundle("messages", Locale.US);
4.国际化可以对日期,货币,动态文本进行操作.
DateFormat
NumberFormat
MessageFormat
5.struts2中的国际化
1.struts2中的国际化properties文件怎样定义(定义的位置)?
1.全局---将资源包放置在src下.
* properties文件可以在任何包中
* 需要在struts.xml 中配置全局信息文件位置
struts.xml
<constant name="struts.custom.i18n.resources" value="messages"></constant> messages.properties 在src根目录
<constant name="struts.custom.i18n.resources" value="cn.itcast.resources.messages"></constant> messages.properties 在 cn.itcast.resources 包
2.针对于包下的Action使用
在所在的包下创建一个package.properties文件.
3.针对于某个Action
在Action类所在的包下创建一个 ActionName.properties
4.针对于某个jsp页面中使用.
引入一个指定的国际化配置文件.需要使用struts2标签
<s:i18n name="cn.itcast.resource.text">
<s:text name="login.message"></s:text>
</s:i18n>
2.struts2中的国际化在哪些位置使用,怎样使用?
1.Action中使用
让Action类继承自ActionSupport类,可以使用它的 getText(String name)
2.视图使用(jsp)
<s:text name=""> 可以直接使用全局的国际化配置文件
3.配置文件(校验的xml文件)
<message key=""/>
问题:怎样控制动态文本
1.Action中操作
this.getText("login.message",new String[]{"用户名"})
2.视图中操作
<s:text name="login.message">
<s:param>username</s:param>
</s:text>
============================================================================================
struts2拦截器(interceptor)
在struts-default.xml文件中有一个<package> 叫struts-default
它里面定义了所有的拦截器。
<interceptor-stack name="defaultStack">是我们使用的默认的18个拦截器.
关于<interceptor> <interceptor-stack>标签的作用
<interceptor name="" class="">它用于声明一个拦截器
<interceptor-stack name=""> 拦截器栈
name属性是代表拦截器栈的名称
它有子元素
<interceptor-ref name="exception"/> 它用于引用一个拦截器.
拦截器作用?
拦截器是在访问Action之间或之后,可以进行一些处理.
它是可插拔式的,采用了AOP思想
AOP---面向切面的编程-----核心思想动态代理.
struts2的拦截器采用了责任链设计模式.
自定义拦截器
1.在struts2框架中所有的拦截器根接口com.opensymphony.xwork2.interceptor.Interceptor.
2.想要让拦截器向下访问通过 String intercept(ActionInvocation invocation) throws Exception;
的参数invocation.invoke()才能向下执行.
案例:权限控制,如果用户没有登录,不能访问操作.
用户登录成功后,将用户存储到session中.
如果用户没有登录,不能访问BookAction中的操作.
可以通过一个自定义的interceptor完成拦截操作.
1.创建一个PrivilegeInterceptor类继承 AbstractInterceptor(这个类是Interceptor接口的实现类)
2.重定方法
public String intercept(ActionInvocation invocation) throws Exception {
//session中存在用户,也就是说,用记登录了。
User user=(User) ServletActionContext.getRequest().getSession().getAttribute("user");
if(user==null){
//没有登录.
return Action.LOGIN;
}
return invocation.invoke();
}
3.将自己的interceptor注入到Action中.
1.声明拦截器---在<package>下
<interceptors>
<interceptor name="privilege" class="cn.itcast.utils.PrivilegeInterceptor" />
</interceptors>
2.在Action中引入拦截器
在<action>标签下
<interceptor-ref name="privilege" /> <!-- 引入一个拦截器 -->
注意:如果在某一个action中显示的声明了一个拦截器,那么默认的18个拦截器失效了。
问题:现在不想对BookAction中的select拦截。
可以通过继承一个MethodFilterInterceptor,它可以控制针对于哪些方法进行拦截.
可以在struts.xml文件中声明拦截器时指定参数来控制哪些方法被拦截,哪些不被拦截
<interceptor name="privilege" class="cn.itcast.utils.PrivilegeInterceptor">
<param name="excludeMethods">select,update</param>
<param name="includeMethods">add,del</param>
</interceptor> <!-- 声明一个拦截器 -->
------------------------------------------------------------------------------
struts2文件上传与下载
1.上传
struts2内置了commons-fileupload插件.
在它默认的18个拦截器中有一个叫fileupload拦截器
在页面上
1.method=post
2.enctype="multipart/form-data"
3.组件要有名称 <input type="file" name="upload">
在Action中
在Action中声明三个属性
private File upload;
private String uploadContentType;
private String uploadFileName;
提供get/set方法。
在execute方法中通过 FileUtils.copyFile(File src,File dest)完成文件复制.
问题:
1.配置input视图来控制上传失败时跳转的页面.
2.在default.properties
# struts.multipart.parser=cos
# struts.multipart.parser=pell
struts.multipart.parser=jakarta 使用的是commons-fileupload插件
用于设置当前上传时所使用的插件.
如果使用cos或pell必须导入相应的插件包
3.限定上传文件大小
通过 struts.multipart.maxSize 常量设置文件上传总大小限制
* struts.multipart.maxSize=2097152 默认上传文件总大小 2MB
* 超过文件总大小,跳转input 视图, 通过 <s:actionError /> 回显错误信息
在struts.xml 设置上传总大小
<constant name="struts.multipart.maxSize" value="20000000"></constant>
4.针对fileupload拦截器进行配置,也可以限定文件上传操作
在FileUploadInterceptor中有三个属性
protected Long maximumSize; 限定每一个上传文件大小
protected Set<String> allowedTypesSet = Collections.emptySet(); 限定上传文件的MimeType类型
protected Set<String> allowedExtensionsSet = Collections.emptySet(); 限定上传文件的后缀名
怎样设置这些属性?
<interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">20971520</param>
<param name="fileUpload.allowedExtensions">txt,jpg</param>
</interceptor-ref>
5.对错误信息进行国际化操作
1.针对于Action创建一个properties文件.
2.错误信息模板
配置如下:
struts.messages.error.uploading=Error uploading: {0}
struts.messages.error.file.too.large=File too large: {0} "{1}" "{2}" {3}
struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" "{2}" {3}
struts.messages.error.file.extension.not.allowed=File extension not allowed: {0} "{1}" "{2}" {3}
{0}:<input type=“file” name=“uploadImage”>中name属性的值
{1}:上传文件的真实名称
{2}:上传文件保存到临时目录的名称
{3}:上传文件的类型(对struts.messages.error.file.too.large是上传文件的大小)
3.在自己的properties文件中修改配置
修改为
struts.messages.error.uploading=上传错误: {0}
struts.messages.error.file.too.large=上传文件太大: {0} "{1}" "{2}" {3}
struts.messages.error.content.type.not.allowed=上传文件的类型不允许: {0} "{1}" "{2}" {3}
struts.messages.error.file.extension.not.allowed=上传文件的后缀名不允许: {0} "{1}" "{2}" {3}
多文件上传
第一步:在WEB-INF/lib下加入commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar。这两个文件可以从http://commons.apache.org/下载。
第二步:把form表的enctype设置为:“multipart/form-data“,如下:
<form enctype="multipart/form-data" action="${pageContext.request.contextPath}/xxx.action" method="post">
<input type="file" name="uploadImages">
<input type="file" name="uploadImages">
</form>
第三步:在Action类中添加以下属性,属性红色部分对应于表单中文件字段的名称:
public class uploadAction{
private File[] uploadImages;//得到上传的文件
private String[] uploadImagesContentType;//得到文件的类型
private String[] uploadImagesFileName;//得到文件的名称
//这里略省了属性的getter/setter方法
public String saveFiles() throws Exception{
ServletContext sc = ServletActionContext.getServletContext();
String realpath = sc.getRealPath("/uploadfile");
try {
if(uploadImages!=null&&uploadImages.length>0){
for(int i=0;i<uploadImages.length;i++){
File destFile = new File(realpath,uploadImageFileNames[i]);
FileUtils.copyFile(uploadImages[i], destFile);
}
}
} catch (IOException e) {
e.printStackTrace();}return "success";}}
----------------------------------------------------------------------------------------------
2.下载
文件下载方式:
1.超连接
2.服务器端以流的方式向浏览器写回数据.
struts2文件下载
文件下载注意事项:
1.response.setContentType(Stirng mimeType);
2.response.setHeader("Content-Disposition","attachment;filename=xxxx");
文件下载操作
1.donwload.jsp
<a href="${pageContext.request.contextPath}/download?filename=18.jpg">下载18.jpg</a>
<br>
<a href="${pageContext.request.contextPath}/download?filename=22.jpg">下载22.jpg</a>
<br>
2.DownloadAction
private String filename;
3.完成下载
1.在struts.xml文件中对应的DownloadAction的配置信息中配置
<result type='stream'>
</result>
在stream对应的类中org.apache.struts2.dispatcher.StreamResult
有三个属性
protected String contentType = "text/plain"; 设置响应的mimeType类型
protected String contentDisposition = "inline"; 设置响应content-dispostion值
protected InputStream inputStream; 设置响应数据
<action name="download" class="cn.itcast.action.DownloadAction">
<result type="stream"> <!-- 可以完成文件下载 -->
<param name="contentType">${contentType}</param> 代表在当前的Action类中去调用一个getContentType方法,这个方法的返回值就是用于赋值给contentType的.
<param name="contentDisposition">attachment;filename=${filename}</param>
<param name="inputStream">${inputStream}</param>
</result>
</action>
下载文件时乱码问题:
1.连接中文件名称包含中文处理.
解决:在setFilename方法中解决
this.filename = new String(filename.getBytes("iso8859-1"), "utf-8");
2.下载文件乱码问题
ie:utf-8码
firefox:base64编码
=======================================================================
ognl与valueStack介绍
ognl--对象导航图语言.
它比el更强大.
ognl是一个开源项目.
OGNL 提供五大类功能
1、支持对象方法调用,如xxx.doSomeSpecial();
<s:property value="'abc'.length()">
2、支持类静态的方法调用和值访问
静态方法调用必须开启
调用 静态方法 : @[类全名(包括包路径)]@[方法名] --- <s:property value="@java.lang.String@format('您好,%s','小明')"/>
* 使用 静态方法调用 必须 设置 struts.ognl.allowStaticMethodAccess=true
3、访问OGNL上下文(OGNL context)和ActionContext; (重点 操作ValueStack值栈 )
4、支持赋值操作和表达式串联
5、操作集合对象。
通过ognl访问上下文以及ActionContext
1.什么是值栈 ValueStack ?
它是一个容器.本质上是一个接口 ValueStack接口.这个接口有一个实现类 OgnlValueStack,
我们使用的其实就是OgnlValueStack。
每一个Action对应一个ValueStack.
将valueStack存储到了request范围内.
将valueStack对象以 "struts.valueStack"存储到了request范围内.
valueStack中有两部分:
root-----CompoundRoot 它继承了ArrayList
context----Map
root中存储了Action相关属性
context中存储了web相关对象.
2.valueStack内部结构
ValueStack由两部分组成:
1.List public abstract CompoundRoot getRoot();
2.Map public abstract Map<String, Object> getContext();
Struts 会把下面这些映射压入 ContextMap 中
parameters: 该 Map 中包含当前请求的请求参数
request: 该 Map 中包含当前 request 对象中的所有属性
session: 该 Map 中包含当前 session 对象中的所有属性
application:该 Map 中包含当前 application 对象中的所有属性
attr: 该 Map 按如下顺序来检索某个属性: request, session, application
Root下存储的是Action相关的信息.
通过ognl从valueStack中获取信息时,默认是从root中获取.
从root中获取数据直接写名称就可以.
如果要从map中获取,必须使用#来操作.
context 对应Map 引入 root对象
3.获取ValueStack
1.直接从request中获取.
ValueStack vs = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
2.通过ActionContext获取
关于ActionContext与ValueStack的关系
ActionContext ctx = new ActionContext(stack.getContext());
在ActionContext中存在context引用.
ValueStack vs=ActionContext.getContext().getValueStack();