非本人总结的笔记,抄点笔记复习复习。感谢传智博客和黑马程序猿
Struts2国际化
什么是国际化
比如做一个软件,但是做软件,不仅中国人可以使用,其他国家的人也可以使用。根据操作系统的语言,自动识别显示的语言类型。
现在使用国际化,完成的功能是:比如如果进行表单校验功能,校验失败提示错误信息,系统是英文则提示英文;中文则提示中文。
国际互基本实现(配置全局国际化)
创建一系列配置资源文件,命名规范:基本名称_小写的语言_大写的国家.properties
比如:messaage_zh_CN.properties和message_en_US.properties
本地系统是中文系统,读取到message_zh_CN.properties文件的内容
Struts2实现国际化
前提:创建一系列资源文件
所有的资源文件key值要相同
第一种:全局国际化(重点)
配置全局国际化,在项目中的action、jsp页面中、校验文件中,都可以获取国际化内容
实现的方式:通过Struts2的常量配置全局国际化
struts.custom.i18n.resources常量配置的值是资源文件的基本名称。如果资源文件在src下,直接写基本名称;如果资源文件在包里面,加上包路径com/xxx/xxx
-
在action里面读取国际化资源文件内容
//方法中的值 资源文件中key的名称 String value = this.getText("namekey");
-
在jsp中读取国际化资源文件内容
text标签,name属性值,资源文件中key的名称
-
在xml校验文件中读取
第二种:action范围国际化
只能在某一个action中获取到资源文件内容
在action所在包里面创建资源文件,命名:action类名_小写语言_大写语言.properties
获取示例
String value = this.getText("actionkey");
第三种:package范围国际化
在包里面的所有的action可以获取到资源文件内容
在包里面创建资源文件,命名 基本名称必须是package
第四种:临时国际化(jsp获取资源文件内容)
在jsp页面中,获取package.properties资源文件内容
Struts2的拦截器
介绍
使用Struts2操作发送请求,首先到过滤器里面,过滤器解析xml,acting匹配操作,在执行action之前,做执行一系列的拦截器,这些拦截器是Struts2帮实现的一些功能的封装,在Struts2里面默认执行的拦截器在struts-default.xml,273行配置默认值执行的拦截器
Struts2的拦截器底层使用两部分原理
第一个:aop思想(Aop面向方面编程(切面))
比如有登录的功能,基本操作是输入表单数据,提交到Servlet中,判断用户名密码是否正确,最终如果正确到主页面,如果错误到登录页面,上面是登录到基本逻辑。
Aop表示在基本功能之上添加一个额外的功能,实时添加功能,这个功能如果不添加,基本功能也可以运行。
第二种 责任链模式
学过过滤器,有过滤链,一个请求可以有多个过滤器进行过滤,每个过滤器只有做放行才能到下一个过滤器
责任链模式:在一条线有一组操作,执行这些操作,但是每个操作执行完成之后,做类似于放行操作,才能执行下一个方法。
查看Struts2关于拦截器源代码
查看Struts2的过滤器
StrutsPrepareAndExecuteFilter
过滤器里面有init方法,加载配置文件
doFilter方法,做过滤操作
execute.executeAction(request, response, mapping);
要执行action
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createAction(namespace, name, method, extraContext, true, false);
生成action代理对象
ActionContext previous = ActionContext.getContext();
ActionContext.setContext(invocation.getInvocationContext());
try{
return invocation.invoke();
}
执行action之前,执行一系列的拦截器
执行下一个操作
return invocation.invoke();
执行该过程描述:
发送请求时候,首先到过滤器里面,在过滤器doFilter方法中执行action,首先生成action代理对象,执行,执行action之前,执行一系列默认的拦截器(把默认的拦截器拿过来),执行每一个拦截器之后做执行下一个操作,最终执行action逻辑
拦截器构成
类继承AbstractInterceptor,AbstractInterceptor类实现Interceptor接口
AbstractInterceptor implements Interceptor
在Interceptor接口里面有三个方法
void init(); //初始化操作
String intercept(ActionInvocation invocation) throw Exception;//写拦截器逻辑
void destroy();//销毁操作
自己写拦截器:
- 写类继承AbstractInterceptor类,重写类里面的方法Intercept方法,写拦截器逻辑
- 配置拦截器(注册拦截器)
几个重要概念比较
拦截器和过滤器比较
过滤器:在到达目标资源之前进行的操作,过滤器可以过滤的内容有servlet、action、jsp、图片,过滤器理论上可以过滤任何的内容/*
拦截器:在到达目标资源之前进行的操作,拦截器不能拦截jsp、图片。只能拦截action
Action和Servlet比较
Servlet:servlet默认在第一次访问时候创建,创建一次,servlet实例只有一个
Action:action在访问时候创建,创建多次,每次访问action时候都会创建action实例
自定义拦截器
需求:登录拦截器
- 在页面中输入用户名和密码,提交数据到action中
- 在action中获取用户名和密码,判断用户名和密码是否正确
- 如果用户名和密码正确,到主页面中
- 登录成功后,把用户信息放到session里面,跳转到主页面
- 在主页面里面,写超链接,到另一个添加的action里面
- 如果用户名和密码不正确,到登录页面
如果用户直接访问主页面,点击超链接到action中,如果没有登录,不能到action中页面,直接返回登录页面。
实现的基本过程步骤:
第一步 创建类,继承类
public class MyInterceptor extends AbstracrInterceptor {
//写拦截器逻辑
@Override
publicc String intercept(ActionInvocation invocation) throws Exception{
//判断是否登录
//判断session里面是否有数据
ActionContext context = invocation.getInvocationContext();
Object obj = context.getSession().get("user");
if(obj != null) {
//登录
return invocation.invoke();
} else {
//不是登录
return Action.LOGIN;
}
}
}
第二步 注册拦截器
第一种方式:
声明拦截器,在要拦截的action所在的包里面
在action标签里面使用声明的拦截器
/login/add.jsp
/login/login.jsp
第二种方式:
声明拦截器栈
在action里面直接使用声明的栈
Struts2实现文件上传
Javaweb文件上传
使用FileUpload组件,首先导入jar包
步骤:
- 创建磁盘文件项工厂
- 创建核心上传类
- 解析request对象
- 解析之后返回List
集合 - 遍历list集合,判断是普通输入项,还是文件上传项
- 如果是文件上传项,写上传代码
Struts2里面在fileupload的基础之上做进一步封装
要求:
- 提交方式post
- form标签里面属性enctype,属性值multipart/form-data
- 表单里面有文件上传项,type="file",必须有name属性
实现过程
第一步 声明几个变量
第一个变量是上传文件private File文件上传项里面name的值
第二个变量是上传文件的名称private String文件上传里面name属性值Filename
第三个变量是上传文件的mime类型
第一个变量是必须有的,但是第二个和第三个不是必须的
private File upload;
private String uploadFileName;
第二步 生成声明变量的set和get方法
public File getUpload() {
return upload;
}
public void setUpload(File upload) {
this.upload = upload;
}
public String getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
第三步 在action的方法写上传的操作
- 获取到上传到服务器的文件夹路径
- 在服务器的文件夹中创建文件
- 把上传的文件内容复制到服务器上创建的文件中去
//获取服务器上面文件夹的路径
//使用servlet里面的ServletContext对象
ServletContext context = ServletActionContext.getServletContext();
String path = context.getRealPath("/img");
//在服务器的文件夹里面创建文件
File serverFile = new File(path+"/"+uploadFileName);
//把上传的文件复制到服务器文件中
FileUtils.copyFile(upload, serverFile);
上传问题解决
Struts2做上传,默认的上传的大小限制是2M,如果上传文件超过2M,返回提示信息,到页面中获取提示信息
设置上传文件的大小,设置常量
struts.multipart.maxSize=2097152
默认上传文件总大小是2M,常量的值是字节的单位
Struts2实现多文件上传
实现步骤
第一步
满足上传的三个要求,但是上传多个文件,在表单里面写多个文件上传项,多个文件上传项里面都有name属性,name属性值必须一样
选择文件1:
选择文件2:
选择文件3:
第二步
声明几个变量,因为有多个值,使用数组形式声明
private File[] uploadimg;
private String[] uploadimgFileName;
第三步 生成set和get方法
public File[] getUploadimg() {
return uploadimg;
}
public void setUpload(File[] uploadimg) {
this.uploadimg = uploadimg;
}
public String[] getUploadimgFileName() {
return uploadimgFileName;
}
public void setUploadimgFileName(String[] uploadimgFileName) {
this.uploadimgFileName = uploadimgFileName;
}
第三步 在action方法中实现上传的操作
变量数组,得到每一个文件的信息,一个一个的上传到服务器中
//遍历得到每一个文件内容,一个个上传到服务器中
for(int i = 0; i < uploadimgFileName; i++) {
File uploadFile = uploadimg[i];
String filename = uploadimgFileName[i];
//实现上传
String path = ServletActionContext.getServletContext().gerRealPath("/img");
File serverFile = new File(path+"/"+filename);
FileUtils.copyFile(uploadFile, serverFile);
}
Struts2实现文件下载
Javaweb实现文件下载
第一步:获取服务器上的文件
第二步:把文件通过流的方式写到浏览器中
设置头 Content-Disposition,无论什么格式都是下载,而不是直接打开
实现过程
首先 在配置文件中配置下载的信息
attachment;filename=${filename}
${inputStream}
配置contentDisposition和inputStream
这两个值通过action传递过来
第二步 在action提供这个值的get方法
//提供fileName的get方法
String filename = "2.jpg";
public String getFileName() {
return filename;
}
public InputStream getInputStream() throws FileNotFoundException() {
String path = ServlerActionContext.getServletContext().getRealPath("/img/"+filename);
InputStream in = new FileInputStream(path);
return in;
}
Struts下载中文名称文件乱码
不同的浏览器有不同的编码,ie采用url编码,火狐采用base64编码
首先,区分不同的浏览器
Request对象,有方法getHeader(),使用头获取浏览器类型,头信息 User-Agent
Request.getHeader(“User-Agent”);
判断不同的浏览器,做不同编码
如果是火狐,使用base64编码
如果是ie及其他浏览器,使用url编码