1.1 案例需求概述
1.1.1 需求描述
客户管理的功能:
l 查询所有客户(上次课完成)
l 保存客户的功能(数据接收和封装)
1.2 相关知识点
1.2.1 Struts2的Servlet的API的访问
1.2.1.1 方式一:通过ActionContext实现
页面:
<h1>Servlet的API的访问方式一:解耦合的方式</h1>
<form action="${ pageContext.request.contextPath }/requestDemo1.action" method="post">
姓名:<input type="text" name="name"/><br/>
年龄:<input type="text" name="age"><br/>
<input type="submit" value="提交">
</form>
编写Action
/**
* 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石榴");
return SUCCESS;
}
}
1.2.1.2 方式二:实现特定接口的方式实现
在Struts2中提供了一些接口:ServletRequestAware,ServletResponseAware,ServletContextAware
页面:
<h1>Servlet的API的访问方式二:实现特定接口的方式</h1>
<form action="${ pageContext.request.contextPath }/requestDemo2.action" method="post">
姓名:<input type="text" name="name"/><br/>
年龄:<input type="text" name="age"><br/>
<input type="submit" value="提交">
</form>
编写Action:
/**
* 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;
}
}
1.2.1.3 方式三:通过ServletActionContext对象的静态方法实现
页面:
<h1>Servlet的API的访问方式三:通过ServletActionContext对象静态方法获取</h1>
<form action="${ pageContext.request.contextPath }/requestDemo3.action" method="post">
姓名:<input type="text" name="name"/><br/>
年龄:<input type="text" name="age"><br/>
<input type="submit" value="提交">
</form>
编写Action:
/**
* 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();
}
}
1.2.2 Struts2中的结果页面的配置
1.2.2.1 结果页面的分类
l 全局结果页面
n 针对一个包下所有的action都生效的一个页面
<!-- 全局结果页面 -->
<global-results>
<result>/demo1/success.jsp</result>
</global-results>
l 局部结果页面
n 针对某一个action生效的一个页面
<action name="requestDemo1" class="com.itheima.struts2.demo1.RequestDemo1Action">
<result>/demo1/success.jsp</result>
</action>
1.2.2.2 配置结果页面:
l <result>标签配置:
n name :逻辑视图的名称。默认值是success。
n type :
u dispatcher:默认值,转发。(转发到JSP的页面)
u redirect:重定向。(重定向到JSP的页面)
u chain:转发到另一个Action。
u redirectAction:重定向到另一个Action。
u stream:文件的下载。
1.2.2.3 Struts2的多例性
原来的Servlet是单例存在,多次请求,请求都是同一个Servlet的实例。Struts2中Action是多实例的。有一次请求就会有一个Action的实例。现在可以在Action中定义成员属性了。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////可以做保存了,但是使用struts2自己的封装方式
1.2.3 Struts2的数据封装:
1.2.3.1 Struts2中的数据封装-属性驱动:
l 提供对应属性的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类易读性变差。
l 页面中提供表达式的方式:
页面:
<h3>数据封装的方式二:页面提供OGNL表达式的写法</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;
}
}
1.2.3.2 Struts2中的数据封装-模型驱动:
l 采用模型驱动完成数据封装(推荐)
页面:
<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;
}
}
***** 模型驱动只能向一个实体中封装数据,如果需要向多个实体封装数据优先采用第二种方式。
1.2.4 Struts2的复杂数据的封装:
1.2.4.1 封装到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集合中。
* @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;
}
}
1.2.4.2 封装到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集合
* @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;
}
}