- stuts2入门
- struts2数据操作
Struts2 概述
struts2框架应用javaee三层结构中的web层框架
struts2 是struts1和webwork基础上发展全新的框架、
struts2解决问题

struts2 版本
struts2-2.3.24web层常用框架
- struts2
- springMVC
struts2 框架入门
第一个例子
- 老规矩导入jar包

- 创建action
1 | public class HelloAction { |
- 配置action类访问路径
(1)、创建struts2核心配置文件
核心配置文件必须是固定名称和位置
位置必须是再src下面,名称必须是struts.xml
(2)、引入dtd约束
1 | <!DOCTYPE struts PUBLIC |
(3)、action配置
1 | <package name="hellodemo" extends="struts-default" namespace="/"> |
访问路径
http://127.0.0.1:8080/struts2/hello.action
(4) 配置struts2过滤器
在Tomcat上面运行的时候,发现一直各种报错
1 | 严重: Exception starting filter struts2 |
估计是在idea的时候,运行Tomcat时,maven依赖那里出现了问题。导入缺少了jar包,Tomcat运行不起来。最后在项目结构Artifacts里available Elements右键把里面的jar包导入到lib文件夹里。
!!还有就是一定要把struts2.xml文件放到resources文件夹里
基本流程:

查看源码
class StrutsPrepareAndExecuteFilter implements StrutsStatics, Filter
过滤器在服务启动的时候创建,创建过滤器时候执行init方法
- 在init方法中主要是加载配置文件
包含自己创建的配置文件和struts2自带的配置文件
主要注意struts.xml和web.xml
struts 配置
struts2核心配置文件
名称和位置是固定的
固定是在src里面,名字是struts.xml
但是由于用了maven,所以位置是在src的resources里面在配置文件中主要三个标签 package、action、result,标签里面的属性
标签package
1、 类似于代码包,区别不同的action,要配置action,必须首先写package标签,在package里面才能 配置action
2、 package标签属性
(1)name属性
- name属性值跟功能本身没有关系的,
- 在一个配置文件中可以写多个package标签,name属性值不能相同的
(2)extends属性
extends = “struts-default”
属性值固定的,struts-default
写了这个属性之后,在package里面配置的类具有action功能
(3)namespace属性
- namespace属性值和action标签里面的name属性值构成访问路径
标签action
1、action标签配置action访问路径
2 、action标签属性
(1)name属性
namespace属性值和action标签里面的name属性值构成访问路径
在package标签里面写多个action标签,但是action的name属性值不能相同的
(2)class属性
- action全路径
(3)method属性
比如在action里面默认执行的方法execute方法,但是在action里面写其他的方法
让action里面多个方法执行,使用method进行配置
标签result
1 、根据action的方法返回值,配置到不同的路径里面
2 、result标签属性
(1)name属性
- 和方法返回值一样
/hello.jsp
(2)type属性
配置如何到路径中(转发或者重定向)
type属性默认值 做转发操作
struts2常量配置
struts2框架,帮我们实现一部分功能,struts2里面有常量,在常量里面封装一部分功能
struts2默认的常量位置(记住)
xxxxxxx/org\apache\struts\struts2-core\2.3.24\struts2-core-2.3.24.jar!\org\apache\struts2\default.properties
修改struts2默认常量值
(1)常用的方式
- 在struts.xml中进行配置
(2)还有两种方式(了解)
在src下面创建 struts.properties,进行修改
在web.xml进行配置
- 介绍最常用常量
struts.i18n.encoding=UTF-8
(1)表单提交数据到action里面,在action可以获取表单提交数据,
(2)表单提交数据有中文,有乱码问题,解决:
post提交直接设置编码
get提交做编码转换
(3)如果在action获取表单通过post方式提交中文,中文乱码问题帮解决了,不需要自己处理问题
分模块开发
- 单独写配置文件hello.xml,把配置文件引入到核心配置文件中
1 | <!-- 引入hello.xml --> |
这样就可以在工作的时候,大家一起协同办公
action编写方式
- action编写有三种方式
第一种 创建普通类,这个不继承任何类,不实现任何接口
1 | public class HelloAction{} |
第二种 创建类,实现接口 Action1
2
3
4
5
6//实现接口
public class UserAction implements Action {
public String execute() throws Exception {
return null;
}
}
第三种 创建类,继承类 ActionSupport(一般使用)
1 | //继承类 |
访问action里面的方法
- 有三种方式实现
第一种 使用action标签的method属性,在这个属性里面写执行的action的方法
第二种 使用通配符方式实现
第三种 动态访问实现(不用)
- 演示错误
(1)如果action方法有返回值,在配置文件中没有配置,出现错误
Message No result defined for action cn.shelhon.action.HelloAction and result success
(2)在action里面的方法有返回值,如果有返回值时候类型必须是String
(3)action里面的方法可以没有返回值,没有返回值时候,在result标签不需要配置
把方法写成void
让返回值,返回 ”none”
在idea创建新的模块的时候,放到Tomcat上面一直没办法运行新的struts.xml的配置,然后在运行设置里面的把原来的给移除了,加上新创建的就能运行了
- 使用action标签method属性
(1). 创建action,创建多个方法
1 | public class BookAction extends ActionSupport { |
(2). 使用method配置
1 | <!-- 配置action的方法访问 --> |
缺陷:action每个方法都需要配置,如果action里面有多个方法,配置很多的action
- 使用通配符实现(重点)
(1) 在action标签里面name属性,name属性值里面写 符号 * 星号
*理解: 表示匹配任意内容
比如访问hello,* 可以匹配到
比如访问add,* 可以匹配到
1 | <!-- 配置通配符方法 --> |
这种方法的话,访问就是用book_add.action ,或者book_update.action来实现
如果name的属性值=”*”的话,那么访问就是输入add.action,或者update.action就可以实现。

结果页面配置
result标签配置action方法的返回值到不同的路径里面
创建两个action,执行默认的方法execute方法,让两个action的方法都返回success,返回success之后,配置到同一个页面里面
(1)如果多个action,方法里面返回值相同的,到页面也是相同的,这个时候可以使用全局结果页面配置
1 | <package name="demo1" extends="struts-default" namespace="/"> |
修改后代码1
2
3
4
5
6
7
8
9
10<package name="demo1" extends="struts-default" namespace="/">
<!-- 全局结果页面配置 -->
<global-results>
<result name="success">hello.jsp</result>
</global-results>
<action name="book" class="cn.shelhon.action.BookAction" method="execute">
</action>
<action name="orders" class="cn.shelhon.action.OrdersAction" method="execute">
</action>
</package>
但是要注意的是,这个全局变量是在package里面用的
- 局部结果页面
1 | <action name="book" class="cn.shelhon.action.BookAction" method="execute"> |
如果同时配置了局部和全局结果页面,最后以局部变量为准
Result标签的type属性
result标签里面除了name属性之外,还有一个属性 type属性
type属性:如何到路径里面(转发还是重定向)type属性值
(1)默认值,做转发操作,值是 dispatcher
就是说在浏览器上面的地址还是看到
http://localhost:8080/struts2Day02/book.action
但是实际内容是hello.jsp的内容
(2)做重定向操作,值是 redirect
输入http://localhost:8080/struts2Day02/book.action
然后链接变成了http://localhost:8080/hello.jsp
(3)上面两个值dispatcher、redirect,这两个值一般针对到页面中配置配置到其他的action里面
- chain:转发到action,一般不用,缓存问题
输入http://localhost:8080/struts2Day02/book.action
链接不变,但是实际内容已经是orders的内容 - redirectAction:重定向到action
比如输入http://localhost:8080/struts2Day02/book.action
链接变成http://localhost:8080/orders.action
- chain:转发到action,一般不用,缓存问题
Action获取表单提交数据
之前web阶段,提交表单到servlet里面,在servlet里面使用request对象里面的方法获取,getParameter,getParameterMap
提交表单到action,但是action没有request对象,不能直接使用request对象
action获取表单提交数据主要三种方式
(1)使用ActionContext类
(2)使用ServletActionContext类
(3)使用接口注入方式(一般不用)
使用ActionContext类获取
Map
- 因为这方法不是静态的方法,所以需要创建ActionContext类的对象
- 这个ActionContext不是new出来的
static ActionContext getContext() :获取当前线程的ActionContext对象
- 具体演示
(1)创建表单,提交表单到action里面
(2)在action使用ActionContext获取数据
1 | public String execute() throws Exception { |
1 | <package name="demo2" namespace="/" extends="struts-default"> |
使用ServletActionContext类获取

调用类里面静态方法,得到request对象
1 | public String execute() throws Exception { |
使用接口注入(了解)
1 | public class Form3Demo extends ActionSupport implements ServletRequestAware { |
在action操作域对象
1 | //操作三个域 // 1 request域 |
Struts2封装获取表单数据方式
原始方式获取表单封装到实体类对象
1 | public String execute() throws Exception { |
1 | public class User { |
属性封装
- 实现过程
(1)使用表达式封装可以把表单数据封装到实体类对象里面
第一步 在action里面声明实体类1
<action name="data1" class="cn.shelhon.data.DataDemo1Action"> </action>
第二步 生成实体类变量的set和get方法
1 | public class DataDemo1Action extends ActionSupport { |
模型驱动封装(重点)
使用模型驱动方式,可以直接把表单数据封装到实体类对象里面
实现步骤
(1)action实现接口 ModelDriven
1 | public class DataDemo2Action extends ActionSupport implements ModelDriven<User> {} |
(2)实现接口里面的方法 getModel方法
- 把创建对象返回
1 | public class DataDemo2Action extends ActionSupport implements ModelDriven<User> { |
(3)在action里面创建实体类对象
1 | public User getModel() { |
- 使用模型驱动和属性封装注意问题:
在一个action中,获取表单数据可以属性封装,使用模型驱动封装,不能同时使用属性封装和模型驱动封装获取同一个表单数据。如果同时使用,执行模型驱动。
表达式封装(会用)
- 实现过程
(1)使用表达式封装可以把表单数据封装到实体类对象里面
第一步 在action里面声明实体类
private User user;
第二步 生成实体类变量的set和get方法
1 | public User getUser() { |
第三步 在表单输入项的name属性值里面写表达式形式1
2
3
4
5username:<input type="text" name="user.username"/>
<br/>
password:<input type="text" name="user.password"/>
<br/>
address:<input type="text" name="user.address"/>
比较表达式封装和模型驱动封装
使用表达式封装和模型驱动封装都可以把数据封装到实体类对象里面
不同点:
(1)使用模型驱动只能把数据封装到一个实体类对象里面
在一个action里面不能使用模型驱动把数据封装到不同的实体类对象里面
(2)使用表达式封装可以把数据封装到不同的实体类对象里面
1 | public class DataDemo3Action extends ActionSupport { |
1 | <form action="${pageContext.request.contextPath}/data3.action" method="post"> |
封装到集合里面
- 封装数据到List集合
第一步 在action声明List1
private List<User> list;
第二步 生成list变量的set和get方法
第三步 在表单输入项里面写表达式1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<form action="${pageContext.request.contextPath}/list.action" method="post">
username:<input type="text" name="list[0].username"/>
<br/>
password:<input type="text" name="list[0].password"/>
<br/>
address:<input type="text" name="list[0].address"/>
<br/>
<br/>
username:<input type="text" name="list[1].username"/>
<br/>
password:<input type="text" name="list[1].password"/>
<br/>
address:<input type="text" name="list[1].address"/>
<br/>
<input type="submit" value="提交"/>
- 封装数据到Map集合
第一步 声明map集合
private Map
第二步 生成get和set方法
1 | public Map<String,User> getMap() { |
第三步 在表单输入项的name属性值里面写表达式1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<form action="${pageContext.request.contextPath}/map.action" method="post">
<!-- 设置key的值 ['key值']
设置value值 -->
username:<input type="text" name="map['one'].username"/>
<br/>
password:<input type="text" name="map['one'].password"/>
<br/>
address:<input type="text" name="map['one'].address"/>
<br/>
<br/>
username:<input type="text" name="map['two'].username"/>
<br/>
password:<input type="text" name="map['two'].password"/>
<br/>
address:<input type="text" name="map['two'].address"/>
<br/>
<input type="submit" value="提交"/>
</form>