1.请求参数接收的分为两大类:属性驱动和模型驱动。
属性驱动方式接收:
a.简单属性驱动方式接收
步骤:
1、编写登录页面login1.jsp(发送参数,参数要有名字)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>演示简单属性驱动方式接收参数</h1>
<form action="login1.action" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
2.在Action类中定义属性,提供属性对应的setter方法
public class Login1Action extends ActionSupport{
private String username;//属性名一定要和页面参数名一致
private String password;//属性名一定要和页面参数名一致
@Override
public String execute() throws Exception {
System.out.println(username);
System.out.println(password);
return NONE;
}
//一定要提供属性对应的set方法,并且方法名要满足规范 set+参数名
public void setUsername(String username) {
System.out.println("调用了setUsername");
this.username = username;
}
public void setPassword(String password) {
System.out.println("调用了setPassword");
this.password = password;
}
}
原理:
拦截器(params)拦截用户请求,调用Action类里属性的setter方法,把参数值设置到对应的属性里面去。
优势:当参数比较少的时候,采用这种方式接收简单。
弊端:当参数比较多的时候,Action类里定义很多个属性及setter方法,不便于向业务层传递参数,比较麻烦。
b. 对象属性驱动方式接收
步骤:
1、编写页面,注意:参数名:user.username(对象名.属性名)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>演示对象属性驱动方式接收参数</h1>
<form action="login2.action" method="post">
用户名:<input type="text" name="user.username"><br>
密码:<input type="password" name="user.password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
2、封装实体类User(属性名要和参数名对应,提供属性对应的set方法)
package com.icbc.struts.study2;
public class User {
private String username;//属性名要和参数名一致,并且要提供对应的set方法
private String password;//属性名要和参数名一致,并且要提供对应的set方法
private int age;//属性名要和参数名一致,并且要提供对应的set方法
public User(){
System.out.println("调用了User类默认的构造方法");
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
System.out.println("调用了setUsername方法");
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
System.out.println("调用了setPassword方法");
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
3、在Action类里提供对象属性user,提供user属性对应的setter方法和getter方法,注意方法的名字
public class Login2Action extends ActionSupport{
private User user;//对象属性接收参数,名字要和页面上对象名一致
@Override
public String execute() throws Exception {
System.out.println(user.getUsername());
System.out.println(user.getPassword());
return NONE;
}
public User getUser() {
System.out.println("调用了getUser");
return user;
}
public void setUser(User user) {
System.out.println("调用了setUser");
this.user = user;
}
}
原理:请求被拦截器拦截,对参数名(user.username)进行截取,寻找Action里对应的属性名,调用get***方法 获取到对象,如果对象为null,则调用实体类里的默认的构造方法实例化,再调用对象属性的set***方法把对象设置进去,再把参数值通过对象的set***方法把参数值设置到对象里。当第二次设置参数时,调用get***方法获取对象,但此时对象不为null,调用对象的 set方法把参数值设置到对象里。
优势:把参数封装到Action的对象属性里,Ation类没必要提供很多的简单属性及set方法,代码量少;向业务层传递参数可以直接传递对象,方便。
弊端:需要在页面中,参数名前面加上对象名,写起来有点麻烦。
重点b.模型驱动方式接收 :action类实现ModelDriven<实体类>接口
步骤:
1、编写页面login3.jsp,注意:参数名前不需要加对象名。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>演示模型驱动方式接收参数</h1>
<form action="login3.action" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
2、封装实体类,同对象属性驱动方式。
package com.icbc.struts.study2;
public class User {
private String username;//属性名要和参数名一致,并且要提供对应的set方法
private String password;//属性名要和参数名一致,并且要提供对应的set方法
private int age;//属性名要和参数名一致,并且要提供对应的set方法
public User(){
System.out.println("调用了User类默认的构造方法");
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
System.out.println("调用了setUsername方法");
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
System.out.println("调用了setPassword方法");
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
3、在Action类中提供对象属性并实例化,让Action类实现ModelDriven<实体类>接口,重写getModel方法,返回对象属性。
public class Login3Action extends ActionSupport implements ModelDriven<User>{
private User user = new User();//一定要手动实例化
@Override
public String execute() throws Exception {
System.out.println(user.getUsername());
System.out.println(user.getPassword());
return NONE;
}
/**
* struts2先判断Action类是否实现了ModelDriven
* 如果实现,调用getModel方法,返回一个对象,框架会把参数填充到返回的对象里
*/
@Override
public User getModel() {
return user;
}
}
原理:
拦截器拦截请求(modelDriven,params),判断该Action是否实现了ModelDriven接口,如果实现了ModelDriven接口,调用getModel方法,获取对象,把参数封装到对象的属性里去(调用对象的set***方法)。
三种方式总结:
如果参数比较少(一到两个),可以使用第一种;
如果参数比较多,建议采用第二种或第三种(看个人习惯)。
多种接收方式优先级的问题:
先采用模型驱动方式接收,再采用属性驱动方式接收.