Struts2 第二天学习笔记
1、Struts2的API的访问
在使用Struts2框架的过程中,发现Struts2和Servlet的API的解耦合的。在实际开发中,经常使用Servlet的API,比如进行登录,将用户信息保存到Session中,有的时候需要向页面中输出一些内容,用到response对象,涉及到Servlet的API的访问
1.1Struts2的Servlet的API的访问
1.1.1 完全解耦合的方式
- 编写jsp
<form action="${pageContext.request.contextPath }/RequestDemo1.action" method="post">
姓名:<input name="name" type="text"/><br/>
密码:<input type="password" name="pwd"/><br/>
<input type="submit" value="提交"/>
</form>
- 编写action
@Override
public String execute() throws Exception {
//接受参数
//利用Struts2 的对象ActionContext对象
ActionContext context = ActionContext.getContext();
//调用ActionContext中的方法
//类似于request.getParamaterMap
Map<String, Object> map = context.getParameters();
for (String key : map.keySet()) {
String [] values = (String[]) map.get(key);
System.out.println(key+"--->"+Arrays.toString(values));
}
//向域对象中存入数据
context.put("reqName", "reqValue");//相当于request.setAttribute();
context.getSession().put("sessName", "sessValue");//相当于session.setAttribute()
context.getApplication().put("appName", "appValue");//相当于Application.setAttribute()
return "success";
}
*** 注意:这种方式只能获得代表request,session,application的数据的map集合,不能操作这些对选哪个本身的方法。
1.1.2 使用Servlet的API的原生方式
@Override
public String execute() throws Exception {
//接受参数
//直接获得request对象,通过ServletActionContext
HttpServletRequest request = ServletActionContext.getRequest();
Map<String, String[]> map = request.getParameterMap();
for (String key : map.keySet()) {
String [] values = map.get(key);
System.out.println(key+" "+Arrays.toString(values));
}
//向域对象中保存数据
request.setAttribute("reqName", "reqValue");
request.getSession().setAttribute("sessName", "sessValue");
ServletActionContext.getServletContext().setAttribute("appName", "appValue");
return SUCCESS;
}
1.1.3接口注入的方式
- 编写jsp
<h3>方式三:接口注入的方式</h3>
<form action="${pageContext.request.contextPath }/RequestDemo3.action" method="post">
姓名:<input name="name" type="text"/><br/>
密码:<input type="password" name="pwd"/><br/>
<input type="submit" value="提交"/>
</form>
- 配置struts.xml配置文件
<action name="RequestDemo3" class="com.struts2.day02.RequestDemo3">
<result name="success">/demo1/demo2.jsp</result>
</action>
- 编写action
- 实现ServletRequestAware接口和ServletContextAware接口,并实现里面的方法
public class RequestDemo3 extends ActionSupport implements ServletRequestAware,ServletContextAware{
private HttpServletRequest request;
private ServletContext context;
@Override
public String execute() throws Exception {
//接受参数
//直接获得request对象,通过ServletActionContext
Map<String, String []> map = request.getParameterMap();
for (String key : map.keySet()) {
String [] values = map.get(key);
System.out.println(key+" "+Arrays.toString(values));
}
//向域对象中存入数据
//向request中存数据
request.setAttribute("reqName", "reqValue");
//向session中存数据
request.getSession().setAttribute("sessName", "sessValue");
//向Application中存数据
context.setAttribute("appName", "appValue");
return SUCCESS;
}
@Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
@Override
public void setServletContext(ServletContext context) {
this.context = context;
}
}
Servlet是单例的,多个线程访问一个Servlet只会创建一个Servlet的实例。Action是多例的,一次请求,创建一个Action的实例(不会出现线程安全的问题)。
2、Struts2的结果页面的配置
2.1 结果页面的配置
2.1.1 全局结果页面
- 全局结果页面:指的是,在包中配置一次,其他的在这个包中的所有action只要返回了这个值,都可以跳转到这个页面。
- 针对这个包下的所有的action的配置都有效。
<struts>
<constant name="struts.action.extension" value="action"></constant>
<package name="demo1" extends="struts-default" namespace="/">
<!--全局结果页面 -->
<global-results>
<result name="success">/demo1/demo2.jsp</result>
</global-results>
<action name="RequestDemo1" class="com.struts2.day02.RequestDemo1"></action>
<action name="RequestDemo2" class="com.struts2.day02.RequestDemo2"></action>
<action name="RequestDemo3" class="com.struts2.day02.RequestDemo3"></action>
</package>
</struts>
2.1.2 局部结果页面
- 局部结果页面:指的是,在当前的action中的配置有效。
- 针对当前的action有效。
<action name="RequestDemo1" class="com.struts2.day02.RequestDemo1">
<result name="success">/demo1/demo2.jsp</result>
</action>
2.2 result标签的配置
- result标签用于配置页面的跳转。在result标签中有两个属性:
- name:逻辑视图的名称,默认值是success,返回默认值时可不写。
- type:页面跳转的类型。
- dispatcher:默认值,请求转发(Action转发jsp)
- redirect: 重定向(Action重定向到jsp)
- chain: 转发(Action转发到Action)
- redirectAction:重定向(Action重定向到Action)
3、Struts2的数据封装
Struts2是一个web层框架。Struts2提供了数据封装的功能。
3.1 属性驱动
3.1.1 提供属性的set()方法的方式(不常用,麻烦)
- 编写User类,生成set(),get()方法
public class User {
private String username;
private String password;
private Integer age;
private Date birthday;
private Double salary;
- 编写jsp页面
<form action="${pageContext.request.contextPath }/UserAction1.action" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
年龄:<input type="text" name="age"><br/>
生日:<input type="date" name="birthday"><br/>
工资:<input type="text" name="salary"><br/>
<input type="submit" value="提交">
</form>
- 编写UserAction类
- 提供对应的属性
- 提供属性所对应的的set()方法
public class UserAction1 extends ActionSupport{
//提供对应的属性
private String username;
private String password;
private Integer age;
private Date birthday;
private Double salary;
//提供属性所对应的的set()方法
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setAge(Integer age) {
this.age = age;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String execute() throws Exception {
//接受数据
System.out.println(username);
System.out.println(password);
System.out.println(age);
System.out.println(birthday);
System.out.println(salary);
//封装数据
return NONE;
}
}
3.1.2 页面中提供表达式的方式
- 编写jsp
- 注意name的写法
<h3>方式三属性驱动:在页面中提供表达式的方式</h3>
<form action="${pageContext.request.contextPath }/UserAction2.action" method="post">
用户名:<input type="text" name="user.username"><br/>
密码:<input type="password" name="user.password"><br/>
年龄:<input type="text" name="user.age"><br/>
生日:<input type="date" name="user.birthday"><br/>
工资:<input type="text" name="user.salary"><br/>
<input type="submit" value="提交">
</form>
- 编写action
- 提供一个User对象
- 提供user的get和set方法,一定要提供get()方法
//提供一个User对象
private User user;
//提供user的set和get方法,一定要提供get方法
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {
System.out.println(user);
return NONE;
}
3.2 模型驱动
- 编写jsp
<form action="${pageContext.request.contextPath }/UserAction3.action" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
年龄:<input type="text" name="age"><br/>
生日:<input type="date" name="birthday"><br/>
工资:<input type="text" name="salary"><br/>
<input type="submit" value="提交">
</form>
- 编写action类、
- 实现ModelDriven接口
- getModel():模型驱动需要使用的方法
- 模型驱动使用的对象:前提必须提供对象的实例
public class UserAction3 extends ActionSupport implements ModelDriven<User>{
//模型驱动使用的对象:前提必须提供对象的实例
private User user = new User(); //手动实例化User
//模型驱动需要使用的方法
@Override
public User getModel() {
return user;
}
@Override
public String execute() throws Exception {
System.out.println(user);
return NONE;
}
}
4、Struts2的复杂类型的数据封装
在实际开发中,有可能遇到批量向数据库中插入记录,需要在页面中将数据封账到集合中。
4.1 Struts2的复杂类型的数据封装
4.1.1 封装数据到List集合中
- 编写jsp页面
<form action="${pageContext.request.contextPath }/ProductAction1.action" method="post">
商品名称:<input type="text" name="products[0].name"><br>
商品价格:<input type="text" name="products[0].price"><br>
商品名称:<input type="text" name="products[1].name"><br>
商品价格:<input type="text" name="products[1].price"><br>
商品名称:<input type="text" name="products[2].name"><br>
商品价格:<input type="text" name="products[2].price"><br>
商品名称:<input type="text" name="products[3].name"><br>
商品价格:<input type="text" name="products[3].price"><br>
商品名称:<input type="text" name="products[4].name"><br>
商品价格:<input type="text" name="products[4].price"><br>
<input type="submit" value="提交">
</form>
- 编写Product类
- 生成set(),get()方法
public class Product {
private String name;
private Double price;
- 编写action类
- 提供Product类的集合对象
- 提供set()和get()方法
public class ProductAction1 extends ActionSupport{
public List<Product> products;
//提供集合的set()方法
public void setProduct(List<Product> products) {
this.products = products;
}
public List<Product> getProducts() {
return products;
}
@Override
public String execute() throws Exception {
for (Product product : products) {
System.out.println(product);
}
return NONE;
}
}
4.1.2封装数据到Map集合中
- 编写jsp
<h3>封装到Map集合中:批量插入商品</h3>
<form action="${pageContext.request.contextPath }/ProductAction2.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
- 提供product类的Map集合对象
- 提供set(),get()方法
public class ProductAction2 extends ActionSupport{
private Map<String,Product> map;
//提供集合的set()方法
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;
}
}
Map<String,Product> map;
//提供集合的set()方法
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;
}
}