Struts2之处理请求参数
时间:2017-1-11 11:05
——Struts2中获取请求参数(重点)
1、Struts2是一个MVC框架,那么分别表示什么?
View:JSP
Model:Action
Controller:Action、StrutsPrepareAndExecuteFilter
2、为什么Action既是Model又是Controller?
因为Action本身可以作为一个JavaBean。
3、在Struts2中获取请求参数有两大种(三小种)方式可以获取:
1)属性驱动(在Action中添加属性,对Action的属性进行操作)
* 直接将Action作为一个Model,就可以得到请求参数,也就是将Action作为一个JavaBean,提供get/set方法。
这种方式底层是通过反射来实现的。
> 问题1:使用Action封装请求参数,会不会存在线程安全问题?
不会,每一次请求都会生成一个Action对象。
> 问题2:使用该方式封装数据,将数据封装到Action属性中,不可能将Action对象传递给业务层。
需要单独定义JavaBean,将Action属性封装到JavaBean
示例代码:
------------------------------------------------------------------------------------------------------------------
* 创建独立的Model对象,页面通过ognl表达式封装
> 在Action中声明一个JavaBean对象
> private User user;
> 提供get/set方法:public User getUser()....
> 在页面中使用ognl表达式:<input type="text" name="user.username" />
优点:简单,解决了第一种封装的问题。
缺点:在页面中使用了ognl表达式,与Struts2框架耦合度高。
示例代码:
/*
这种方式底层通过Struts2中的一个interceptor进行了封装:
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor" />
@Override
------------------------------------------------------------------------------------------------------------------
2)模型驱动(在开发中应用比较多)
使用ModelDriven接口,对请求数据进行封装。
步骤:
* 声明一个JavaBean对象并且必须实例化对象。
> private User user = new User();
* Action类实现ModelDriven接口
> public class Login3Action extends ActionSupport implements ModelDriven
1、Struts2是一个MVC框架,那么分别表示什么?
View:JSP
Model:Action
Controller:Action、StrutsPrepareAndExecuteFilter
2、为什么Action既是Model又是Controller?
因为Action本身可以作为一个JavaBean。
3、在Struts2中获取请求参数有两大种(三小种)方式可以获取:
1)属性驱动(在Action中添加属性,对Action的属性进行操作)
* 直接将Action作为一个Model,就可以得到请求参数,也就是将Action作为一个JavaBean,提供get/set方法。
这种方式底层是通过反射来实现的。
> 问题1:使用Action封装请求参数,会不会存在线程安全问题?
不会,每一次请求都会生成一个Action对象。
> 问题2:使用该方式封装数据,将数据封装到Action属性中,不可能将Action对象传递给业务层。
需要单独定义JavaBean,将Action属性封装到JavaBean
示例代码:
//属性驱动的第一种方式获取请求参数,直接将Action做为Model
public class Login1Action extends ActionSupport {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
if ("tom".equals(username) && "123".equals(password)) {
request.getSession().setAttribute("username", username);
return SUCCESS;
} else {
request.setAttribute("login.message", "用户名或密码错误");
return "failer";
}
}
}
实现原理:
1、首先为Action类提供JavaBean属性,并提供get / set方法
2、在过滤器中添加如下代码,将请求参数封装到JavaBean中:
实现原理:
1、首先为Action类提供JavaBean属性,并提供get / set方法
2、在过滤器中添加如下代码,将请求参数封装到JavaBean中:
/*
* 在调用invoke()方法前,处理请求参数的封装
*/
Object actionObject = c.newInstance();
// 将请求参数封装到Action中(底层也是反射实现的)
BeanUtils.populate(actionObject, request.getParameterMap());
3、在Action中使用属性
3、在Action中使用属性
------------------------------------------------------------------------------------------------------------------
* 创建独立的Model对象,页面通过ognl表达式封装
> 在Action中声明一个JavaBean对象
> private User user;
> 提供get/set方法:public User getUser()....
> 在页面中使用ognl表达式:<input type="text" name="user.username" />
优点:简单,解决了第一种封装的问题。
缺点:在页面中使用了ognl表达式,与Struts2框架耦合度高。
示例代码:
/*
* 属性驱动的第二种方式获取请求参数,在Action中声明一个JavaBean
* 在表单中的name值需要修改为:
* * name="user.username" name="user.password"
* * <input type="text" name="user.username" />
* user表示Action内部封装JavaBean对象的名称
* 这是Struts2中提供的一个默认表达式语言:ognl
*/
public class Login2Action extends ActionSupport {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
if ("tom".equals(user.getUsername()) && "123".equals(user.getPassword())) {
request.getSession().setAttribute("username", user.getUsername());
return SUCCESS;
} else {
request.setAttribute("login.message", "用户名或密码错误");
return "failer";
}
}
}
------------------------------------------------------------------------------------------------------------------这种方式底层通过Struts2中的一个interceptor进行了封装:
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor" />
@Override
public String doIntercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
if (!(action instanceof NoParameters)) {
ActionContext ac = invocation.getInvocationContext();
// 相当于request.getParameters();
// 相当于request.getParameters();
final Map<String, Object> parameters = retrieveParameters(ac);
if (LOG.isDebugEnabled()) {
LOG.debug("Setting params " + getParameterLogMap(parameters));
}
if (parameters != null) {
Map<String, Object> contextMap = ac.getContextMap();
try {
ReflectionContextState.setCreatingNullObjects(contextMap, true);
ReflectionContextState.setDenyMethodExecution(contextMap, true);
ReflectionContextState.setReportingConversionErrors(contextMap, true);
ValueStack stack = ac.getValueStack();
// 将参数赋值给Action中的JavaBean
// 将参数赋值给Action中的JavaBean
setParameters(action, stack, parameters);
} finally {
ReflectionContextState.setCreatingNullObjects(contextMap, false);
ReflectionContextState.setDenyMethodExecution(contextMap, false);
ReflectionContextState.setReportingConversionErrors(contextMap, false);
}
}
}
return invocation.invoke();
}
------------------------------------------------------------------------------------------------------------------
2)模型驱动(在开发中应用比较多)
使用ModelDriven接口,对请求数据进行封装。
步骤:
* 声明一个JavaBean对象并且必须实例化对象。
> private User user = new User();
* Action类实现ModelDriven接口
> public class Login3Action extends ActionSupport implements ModelDriven
* 重写getModel()方法
> public Object getModel() { return this.user; }
优点:解决了属性驱动存在的问题
* 不需要将Action封装成JavaBean
* 解决了在页面中使用ognl表达式的问题
缺点:一次只能封装一个JavaBean对象,getModel()方法只能返回一个Bean。
很多关于模型驱动的拦截器都是ModelDriven拦截器操作的:
com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor
示例代码:
/*
——将请求参数封装到集合(了解)
原理:使用ognl表达式实现。
1、将数据封装到List集合
页面:
用户名1:<input type="text" name="users[0].username" /><br/>
Action类:
private List<User> users;
get / set方法
2、将数据封装到Map集合
页面:
用户名1:<input type="text" name="users['aaa'].username" /><br/>
Action类:
private Map<String, User> users;
get / set方法
> public Object getModel() { return this.user; }
优点:解决了属性驱动存在的问题
* 不需要将Action封装成JavaBean
* 解决了在页面中使用ognl表达式的问题
缺点:一次只能封装一个JavaBean对象,getModel()方法只能返回一个Bean。
很多关于模型驱动的拦截器都是ModelDriven拦截器操作的:
com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor
示例代码:
/*
* 使用模型驱动获取请求参数
*/
public class Login3Action extends ActionSupport implements ModelDriven {
private User user = new User();
public Object getModel() {
return this.user;
}
public String login() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
System.out.println(user.getUsername() + ": " + user.getPassword());
if ("tom".equals(user.getUsername()) && "123".equals(user.getPassword())) {
request.getSession().setAttribute("username", user.getUsername());
return "success.jsp";
} else {
request.setAttribute("msg", "用户名或密码错误");
return "login.jsp";
}
}
}
实现原理:
1、在Action中声明一个初始化的JavaBean对象。
2、实现ModelDriven接口
3、重写getModel()方法
4、在拦截器中实现如下代码:
实现原理:
1、在Action中声明一个初始化的JavaBean对象。
2、实现ModelDriven接口
3、重写getModel()方法
4、在拦截器中实现如下代码:
/*
* 模型驱动
*/
// 得到HelloAction类中声明的User对象
Object actionObject = c.newInstance();
// 判断HelloAction是否实现了MyModelDriven接口
if(actionObject instanceof MyModelDriven){
// 将子类强转成父类
MyModelDriven model = (MyModelDriven)actionObject;
// 获取HelloAction内部的User对象,然后把请求参数封装到User对象中
BeanUtils.populate(model.getModel(), request.getParameterMap());
} else {
// 1、属性驱动
actionObject = c.newInstance();
// 将请求参数封装到Action中(底层也是反射实现的)
BeanUtils.populate(actionObject, request.getParameterMap());
}
——将请求参数封装到集合(了解)
原理:使用ognl表达式实现。
1、将数据封装到List集合
页面:
用户名1:<input type="text" name="users[0].username" /><br/>
密 码1:<input type="password" name="users[0].password" /><br/>
用户名2:<input type="text" name="users[1].username" /><br/>
密 码2:<input type="password" name="users[1].password" /><br/>
Action类:
private List<User> users;
get / set方法
2、将数据封装到Map集合
页面:
用户名1:<input type="text" name="users['aaa'].username" /><br/>
密 码1:<input type="password" name="users['aaa'].password" /><br/>
用户名2:<input type="text" name="users['bbb'].username" /><br/>
密 码2:<input type="password" name="users['bbb'].password" /><br/>
Action类:
private Map<String, User> users;
get / set方法
——总结
1、Action接收请求参数
* 关于Struts2中的MVC
* 属性驱动
> 直接将Action作为JavaBean。
> Action中封装JavaBean,在页面上需要使用ognl表达式来给组件起名。
* 模型驱动
> 让Action实现ModelDriven接口,重写getModel()方法实例化一个JavaBean对象,该方法返回的就是实例化的JavaBean对象。
* 关于请求参数封装到集合
> List
> Map