一. Struts2开发步骤:
1. 引入struts的jar包。
commons-fileupload-1.2.2.jar 文件上传相关包
commons-io-2.0.1.jar 文件上传相关包
commons-lang3-3.1.jar struts对java.lang包的扩展
freemarker-2.3.19.jar struts的标签魔般苦jar文件
javassist-3.11.0.GA.jar struts对子解码的处理相关jar
ognl-3.0.5.jar Ognl表达式功能支持表
struts2-core-2.3.4.1.jar struts2核心功能包
xwork-core-2.3.4.1.jar Xwork核心功能包
2. web.xml,引入structs的核心功能,配置过滤器
StrutsPrepareAndExecuteFilter,这是2.1.8以后的核心,要注意不同版本的过滤器,是不一样的。
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
tomcat启动—>加载自身的web.xml—>加载所有项目的web.xml—>通过在项目的web.xml中引入过滤器
--》Struts的核心功能,通过过滤器完成
--》filter『
init/ 启动执行
doFilter/ 访问执行
destory
』
3. 开发action
action类,也叫动作类,用来处理请求,一般继承ActionSupport类,也可以实现Action接口,也可以什么都不做
业务方法返回值,必须为String,而且方法必须没有参数。
// 开发action:处理请求
public class HelloAction extends ActionSupport {
@Override
public String execute() throws Exception {
System.out.println("访问到了action");
System.out.println("调用services");
return "success";
}
}
4. 配置action
在src/struts.xml配置
// 编码
// 访问路径 访问的类 访问的类的方法
二. struts2框架
预先实现功能:
1. 请求数据自动封装
如果在表单那里用的是对象的属性,比如user.userName,就可以将表单的数据封装成一个user对象
2. 文件上传功能
3. 对国际化功能的简化
4. 数据校验功能
。。。
struts执行流程:
- 服务器启动:
- 加载项目web.xml
- 创建struts核心过滤器对象,执行filter—>init()
struts-default.xml 核心功能的初始化
sturts-plugin.xml struts相关插件
struts.xml 用户编写的struts.xml
- 访问:
- 用户访问Action,服务器根据访问路径名称,访问相应的action类的相应方法
- 后面的每次访问,都会创建action实例
struts中struts.xml:
- include结点:引用其他文件,比如总配置文件中(struts.xml)将每一个包中的配置文件引进来
- package结点,定义一个包,用于管理action,通常一个业务模板用一个包。
- name:包名字,不能重复
- extends:当前包继承自哪个包,在struts中,包一定要继承struts-default,struts-default在struts-default.xml中定义
- abstruct:声明当前包为抽象包,只有当前包被继承的时候才使用,如果里面声明了action,则会在运行时报错
- namespace:名称空间,默认为“/”,作为请求路径的一部分
- action结点 配置请求路径与action类的映射关系
- name 请求路径名称
- class 请求处理的action类的全名
- method 求情处理的方法
- result
- name action处理方法返回值
- type 跳转的结果类型
三.struts的域操作
// 将数据保存到域
ActionContext context = ActionContext.getContext();
// 获得request的域的map
Map
// 获得session的域的map
Map
// 获得application的域的map
Map
// 将数据保存到域中
request.put("request_data", "request_data");
session.put("session_data", "session_data");
application.put("application_data", "application_data");
四.通配符
在struts.xml里配置action时使用
*表示匹配任意字符串,{1}表示第一个位置的*,{n}表示第n个位置的*,除了method,在name那里也可以使用,在选择跳转到哪个页面都可以使用
五.struts常量
struts1中的默认访问后缀是*.do
struts2中的默认访问后缀是*.action
如何修改struts的后缀?
1.首先得知道.action是在哪里定义的?
struts-core-2.3.4-1.jar/org.apache.struts/default.properties里面
2.修改方法
去struts.xml里配置
value="action,do," 可用后缀名为action,do,或者没有后缀名
value="action,do" 可用的后缀名只有action和do
value="action" 可用的后缀名只有action
常用常量:
指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出
自定义后缀修改常量
设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭
当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开
开发模式下使用,这样可以打印出更详细的错误信息
默认的视图主题
与spring集成时,指定由spring负责action对象的创建
该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性
为 false
在action里面没有指定使用的method的时候,在访问url的时候用!接方法名就行了
eg:http://127.0.0.1:8080/Fir_struts/user/user!logout
上传文件的大小限制
六. 默认值
配置全局跳转:
/success.jsp
要使用全局的跳转,必须在action那里没有配置跳转目的,这样才会去全局配置那里寻找,而且全局跳转必须放在每一个action的前面。
action的method的默认值:
当action不配置方法的时候,action会默认执行action类里面的execute方法
当action连执行class都没指定,会默认使用下面的action类
×××
但是什么情况下使用不指定类的action呢?
将action作为跳转中转站。可以用来访问WEB-INF下的页面啦。
但是要注意不能像下面那样
type不能设置为重定向,可以像下面这样
七.数据处理
// struts对数据的操作,方式一:直接拿到ServletApi,执行操作
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession();
ServletContext application = ServletActionContext.getServletContext();
request.setAttribute("request_data", "request_data");
session.setAttribute("session_data", "session_data");
application.setAttribute("application_data", "application_data");
// struts对数据的操作,方式二:通过ActionContext
ActionContext context = ActionContext.getContext();
// Struts对HttpServletRequest对象进行了封装,封装成一个map
Map request = context.getContextMap();
Map session = context.getSession();
Map application = context.getApplication();
request.put("request_data", "request_data");
session.put("session_data", "session_data");
application.put("application_data", "application_data");
方式一和方式二的不同在于,方式一用的是servlet的方式,需要引用servlet的包。但当遇到方式二实现不了的情况,就要用回第一种,比如获取当前项目目录
/**
* 方式三:实现接口
* @author root
*
*/
public class DataAction implements Action,RequestAware,SessionAware,ApplicationAware {
private Map request;
private Map session;
private Map application;
@Override
public void setRequest(Map request) {
this.request = request;
}
@Override
public void setSession(Map session) {
this.session = session;
}
@Override
public void setApplication(Map application) {
this.application = application;
}
第三种方式适合action中存在很多的业务方法。一般来说,我们可以弄一个basection,然后将接口实现,以后每一个继承baseaction的action,都可以直接使用那些对象。
八.文件上传及下载
文件上传
servlet的文件上传:
- 前端页面:
1.必须为post请求
2.表单类型为multipart/form-data
3.input type="file" - 后台:
使用FileUpLoad组件
核心类:
FileItemFactory FileItem的工厂
ServletFileUpload servlet中文件上传的核心类
FileItem 封装了上传的表单文件项的信息
struts的文件上传:
前端表单:
后台action:
public class FileUploadAction extends ActionSupport {
// 只有file1是不确定的,FIleName,ContentType都是固定的
private File file1;
private String file1FileName;
private String file1ContentType;
public void setFile1(File file1) {
this.file1 = file1;
}
public void setFile1FileName(String file1FileName) {
this.file1FileName = file1FileName;
}
public void setFile1ContentType(String file1ContentType) {
this.file1ContentType = file1ContentType;
}
@Override
public String execute() throws Exception {
// 获取上传的目录路径
String path =ServletActionContext.
getServletContext().getRealPath("/media");
// 创建目标文件对象
File destFile = new File(path,file1FileName);
// 把上传的文件,拷贝到目标文件中
FileUtils.copyFile(file1, destFile);
System.out.println(file1);
System.out.println(file1FileName);
return SUCCESS;
}
}
文件上传的细节:
- 文件大小限制
struts默认支持的最大的上传的文件大小为2M
要修改的话通过常量修改 - 错误提示
当上传文件出现错误,action就会返回一个“input”,这个时候我们应该配置一个input的错误页面
/error.jsp - 限制文件类型
在处理文件上传的action那里设置
jpg,txt
- 限制允许的文件类型
text/plain
一般这两个方法不一起使用
文件下载:
action里面的配置:
// 1. 获取要下载的文件的文件名
private String fileName;
public void setFileName(String fileName) {
// 处理传入的参数中问题(get提交)
System.out.println("fileName:"+fileName);
try {
fileName = new String(fileName.getBytes(),"utf-8");
} catch (UnsupportedEncodingException e) {
System.out.println(e.getMessage());
throw new RuntimeException(e);
}
// 把处理好的文件名,赋值
this.fileName = fileName;
}
//2. 下载提交的业务方法 (在struts.xml中配置返回stream)
public String down() throws Exception {
return "download";
}
// 3. 返回文件流的方法
public InputStream getAttrInputStream(){
return ServletActionContext.getServletContext().getResourceAsStream("/media/" + fileName);
}
// 4. 下载显示的文件名(浏览器显示的文件名)
public String getDownFileName() {
// 需要进行中文编码
String downFileName = fileName;
try {
downFileName = new String(downFileName.getBytes(), "ISO8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("downFileName"+downFileName);
return downFileName;
}
struts.xml里的配置:
application/octet-stream;charset=ISO8859-1
// 后面那个charset至关重要,就是因为没了这个东西,网页上能看见文件,但是下载显示的文件名一直都是乱码
attrInputStream
attachment;filename=${downFileName}
1024