1、Action的一些注意点:
自己编写的Action类一般需要继承ActionSupport
Servet是单例存在的,也就是说servlet的实现类只会创建一次对象,但是Struts2中的Action是多例的,也就是说每一次请求都会有一个action实例,不需要担心共享数据的问题,可以在action中定义成员属性。
如果在配置文件中不指定action执行的方法,那么其会执行execute方法。
2、Action获取请求数据的方式
方式一:通过ActionContext对象来实现获取请求数据
/**
* Servlet的API的访问方式一:解耦合的方式
* * 只能用于接收参数 和 操作域中的数据
* @author jt
*/
public class RequestDemo1Action extends ActionSupport{
@Override
public String execute() throws Exception {
// 接收数据:
/**
* 在ActionContext中提供了一些方法:操作域对象的数据
* * Map<String,Object> getParameters();
* * Map<String,Object> getSession();
* * Map<String,Object> getApplication();
*/
// 接收参数:
ActionContext actionContext = ActionContext.getContext();
Map<String,Object> map = actionContext.getParameters();
for (String key : map.keySet()) {
String[] arrs = (String[]) map.get(key);
System.out.println(key+" "+Arrays.toString(arrs));
}
// 向request域中存值:
actionContext.put("reqName", "req如花");
// 向session域中存值:
actionContext.getSession().put("sessName", "sess凤姐");
// 向application域中存值:
actionContext.getApplication().put("appName","app石榴");
}
}
方式二:通过实现接口来实现获取请求数据
在Struts2中提供了一些接口:ServletRequestAware,ServletResponseAware,ServletContextAware
/**
* Servlet的API的访问方式二:
* @author jt
*
*/
public class RequestDemo2Action extends ActionSupport implements ServletRequestAware,ServletContextAware{
private HttpServletRequest request;
private ServletContext application;
@Override
public String execute() throws Exception {
// 接收数据:使用request对象。
Map<String, String[]> parameterMap = request.getParameterMap();
for (String key : parameterMap.keySet()) {
String[] arrs = parameterMap.get(key);
System.out.println(key+" "+Arrays.toString(arrs));
}
// 向域中保存数据;
// 向request域中保存数据
request.setAttribute("reqName", "r郝三");
// 向session域中保存数据
request.getSession().setAttribute("sessName", "s李四");
// 向application域中保存数据
application.setAttribute("appName", "a王五");
return NONE;
}
@Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
@Override
public void setServletContext(ServletContext application) {
this.application = application;
}
}
方式三:通过ServletActionContext的静态方法获取数据
/**
* Servlet的API访问方式三:通过ServletActionContext的静态方法访问
* @author jt
*
*/
public class RequestDemo3Action extends ActionSupport{
@Override
public String execute() throws Exception {
// 接收参数:
/**
* ServletActionContext在Struts2的API中的:
* * HttpServletRequest getRequest();
* * HttpServletResponse getResponse();
* * ServletContext getServletContext();
*/
HttpServletRequest request = ServletActionContext.getRequest();
Map<String, String[]> parameterMap = request.getParameterMap();
for (String key : parameterMap.keySet()) {
String[] value = parameterMap.get(key);
System.out.println(key+" "+Arrays.toString(value));
}
// 向域中存值:
request.setAttribute("reqName", "r郝宝强");
request.getSession().setAttribute("sessName", "s郝喆");
ServletActionContext.getServletContext().setAttribute("appName", "a郝蓉");
return super.execute();
}
}
3、Struts2封装页面数据的方法
属性驱动的方式封装数据:
a、提供对应属性的set方法的方式:
页面:
<h3>数据封装的方式一:提供属性的set方法的方式</h3>
<form action="${ pageContext.request.contextPath }/employee1Action.action" method="post">
姓名:<input type="text" name="name"/><br/>
年龄:<input type="text" name="age"/><br/>
性别:<input type="text" name="sex"/><br/>
工资:<input type="text" name="salary"/><br/>
<input type="submit" value="提交"/>
</form>
编写Action:
/**
* 数据封装的方式一:提供set方法的方式
* @author jt
*
*/
public class Employee1Action extends ActionSupport{
private String name;
private Integer age;
private String sex;
private Double salary;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String execute() throws Exception {
System.out.println("员工姓名:"+name);
System.out.println("员工年龄:"+age);
System.out.println("员工性别:"+sex);
System.out.println("员工工资:"+salary);
// 手动封装数据:
Employee employee = new Employee();
employee.setName(name);
employee.setAge(age);
employee.setSex(sex);
employee.setSalary(salary);
return NONE;
}
}
这种方式不是特别常用,因为需要手动封装数据,而且如果属性很多,提供很多的set方法,导致Action类易读性变差。
b、页面中提供表达式的方式:
页面:
<h3>数据封装的方式二:页面提供表达式的写法</h3>
<form action="${ pageContext.request.contextPath }/employee2Action.action" method="post">
姓名:<input type="text" name="employee.name"/><br/>
年龄:<input type="text" name="employee.age"/><br/>
性别:<input type="text" name="employee.sex"/><br/>
工资:<input type="text" name="employee.salary"/><br/>
<input type="submit" value="提交"/>
</form>
编写Action:
/**
* 数据封装的方式二:页面提供表达式的方式
* @author jt
*
*/
public class Employee2Action extends ActionSupport{
// 提供成员的属性employee,必须提供属性的get和set方法
private Employee employee;
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
@Override
public String execute() throws Exception {
System.out.println(employee);
return NONE;
}
}
模型驱动来完成数据封装
采用模型驱动完成数据封装(推荐)
页面:
<h3>数据封装的方式三:采用模型驱动的方式</h3>
<form action="${ pageContext.request.contextPath }/employee3Action.action" method="post">
姓名:<input type="text" name="name"/><br/>
年龄:<input type="text" name="age"/><br/>
性别:<input type="text" name="sex"/><br/>
工资:<input type="text" name="salary"/><br/>
<input type="submit" value="提交"/>
</form>
编写Action:
/**
* 数据封装的方式三:采用模型驱动的方式
* @author jt
*
*/
public class Employee3Action extends ActionSupport implements ModelDriven<Employee>{
// 模型驱动使用的对象:必须手动构建对象的实例!!!!
private Employee employee = new Employee();
@Override
public Employee getModel() {
return employee;
}
@Override
public String execute() throws Exception {
System.out.println(employee);
return NONE;
}
}
4、封装复杂数据
封转数据到List集合或Map集合:只需要声明对应的成员变量,并且提供get和set方法即可
封装到List集合
页面:
<form action="${ pageContext.request.contextPath }/product1Action.action" method="post">
商品名称:<input type="text" name="list[0].name"/><br/>
商品价格:<input type="text" name="list[0].price"/><br/>
商品名称:<input type="text" name="list[1].name"/><br/>
商品价格:<input type="text" name="list[1].price"/><br/>
商品名称:<input type="text" name="list[2].name"/><br/>
商品价格:<input type="text" name="list[2].price"/><br/>
<input type="submit" value="批量导入"/>
</form>
Action:
/**
* 封装复杂的数据到List集合中。,声明List并提供get和set方法即可
* @author jt
*
*/
public class Product1Action extends ActionSupport{
private List<Product> list;
public List<Product> getList() {
return list;
}
public void setList(List<Product> list) {
this.list = list;
}
@Override
public String execute() throws Exception {
for (Product product : list) {
System.out.println(product);
}
return NONE;
}
}
封装到Map集合
页面:
<h1>批量插入商品:封装到Map集合</h1>
<form action="${ pageContext.request.contextPath }/product2Action.action" method="post">
商品名称:<input type="text" name="map['one'].name"/><br/>
商品价格:<input type="text" name="map['one'].price"/><br/>
商品名称:<input type="text" name="map['two'].name"/><br/>
商品价格:<input type="text" name="map['two'].price"/><br/>
商品名称:<input type="text" name="map['three'].name"/><br/>
商品价格:<input type="text" name="map['three'].price"/><br/>
<input type="submit" value="批量导入"/>
</form>
Action:
/**
* 复杂类型数据封装:封装到Map集合,提供成员属性,并提供get和Set方法
* @author jt
*
*/
public class Product2Action extends ActionSupport {
private Map<String,Product> map;
public Map<String, Product> getMap() {
return map;
}
public void setMap(Map<String, Product> map) {
this.map = map;
}
@Override
public String execute() throws Exception {
for (String key : map.keySet()) {
Product product = map.get(key);
System.out.println(key+" "+product);
}
return NONE;
}
}