JAVAWEB开发之Struts2详解(二)——Action接受请求参数、类型转换器、使用Struts2的输入校验、以及遵守约定规则实现Struts2的零配置

本文详细介绍了Struts2中Action如何接收请求参数,包括属性驱动和模型驱动的方式。深入探讨了Struts2内置的类型转换器,如boolean、Date、数组和集合的转换,并讲解了自定义类型转换器的实现。同时,文章还涵盖了Struts2的输入校验机制,包括代码校验、配置校验以及各种内置校验器的使用。最后,讨论了基于XML校验的特点和Struts2的零配置约定。
摘要由CSDN通过智能技术生成

Action接受请求参数

作为MVC框架,必须要负责解析HTTP请求参数,并将其封装到Model对象中
Struts2提供了非常强大的类型转换机制用于请求数据 到 model对象的封装
Struts2和MVC定义关系
StrutsPrepareAndExecuteFilter:控制器
在Struts2中action是什么?(Struts2是一个MVC框架)
V:jsp
M:action
C:action StrutsPrepareAndExecuteFilter

Struts2提供了三种数据封装方式:
  • Action本身作为model对象,通过成员setter封装。(属于属性驱动)
  • 创建独立model对象,页面通过ognl表达式封装。(属于属性驱动)
  • 使用ModelDrivern接口,对请求数据进行封装。(属于模型驱动)
具体使用如下:

1.属性驱动

 属性驱动方式(一):直接将action作为一个model,就可以得到请求参数
action类成员变量setter接收参数如下图所示:

问题1:action封装请求参数,会不会存在线程安全问题?
   是不会的,因为每一次请求,都是一个新的action
优点:使用简单
缺点:需要单独定义JavaBean,将action中属性copy到JavaBean中(不能将Action作为model传给service层)
这种方式,底层是通过反射进行实现的。

属性驱动方式(二):创建一个单独的Model类,在action类中引用model作为成员变量。(页面使用ognl)
具体操作:
在action类中声明一个mdoel,private User user; 
提供对应的setter和getter方法。
在页面上使用ognl来进行描述
<input type="text" name="user.username"> 如下图所示:

这种方式的优点:简单易使用,解决了第一种封装的问题。
缺点:在页面上使用了ognl表达式,页面不通用了。
问题:这种方式,数据是怎样封装的?
是通过Struts2中name为params的interceptor拦截器进行的数据封装(Struts的核心core包下struts-default.xml中定义)<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

2.模型驱动(在开发中应用比较多)

模型驱动的步骤:
1.让action 类实现ModelDrivern接口。
2.重写getModel方法
3.在action中实例化一个model对象,让getModel方法返回这个对象。
  public class Login3Action extends ActionSupport implements ModelDriven<User> {
private User user = new User();
public User getModel() {
return user;
}
  }
如下图所示:

优点:解决了属性驱动存在的问题
缺点:一次只能封装一个model对象
Struts2有很多围绕模型驱动的属性(在struts-default.xml中的拦截器中定义)
<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
扩展:
(1)将数据封装到List集合。类型转换与Collection配合使用。
 Struts2还允许填充Collection里的对象,这常见于需要快速录入批量数据的场合。

页面:
 username1:<input type="text" name="users[0].username"><br>
 password1:<input type="password" name="users[0].password"><br>
 username2:<input type="text" name="users[1].username"><br>
 password2:<input type="password" name="users[1].password"><br>

action类:
 private List<User> users;
 get/set方法
(2)将数据封装到Map集合(类型转换与Map配合使用)

页面:
username1:<input type="text" name="map['aaa'].username"><br>
password1:<input type="password" name="map['aaa'].password"><br>
username2:<input type="text" name="map['bbb'].username"><br>
password2:<input type="password" name="map['bbb'].password"><br>

action类:
private Map<String, User> map;
提供get/set
示例:
1.将action作为model(属性驱动方式一)
Login1Action
package cn.itcast.action;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

// 获取请求参数  属性驱动 第一种,直接将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();
		// 2.判断用户名与密码是否正确
		if ("tom".equals(username) && "123".equals(password)) {

			request.getSession().setAttribute("username", username);
			return SUCCESS;

		} else {
			request.setAttribute("login.message", "用户名或密码错误");
			return "failer";
		}

	}
}
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>
	${requestScope["login.message"]}
	<br>
	<form action="${pageContext.request.contextPath}/login1" method="POST">
		username:<input type="text" name="username"><br>
		password:<input type="password" name="password"><br>
		<input type="submit" value="登录">
	</form>
</body>
</html>
2.将model对象作为Action类成员(属性驱动模式二)
封装Model类
User
package cn.itcast.domain;

public class User {
	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 toString() {
		return "User [username=" + username + ", password=" + password + "]";
	}

}

Login2Action
package cn.itcast.action;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import cn.itcast.domain.User;

import com.opensymphony.xwork2.ActionSupport;

// 获取请求参数  属性驱动 第二种,直接在action上声明一个model
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();
		// 2.判断用户名与密码是否正确
		if ("tom".equals(user.getUsername())
				&& "123".equals(user.getPassword())) {

			request.getSession().setAttribute("username", user.getUsername());
			return SUCCESS;

		} else {
			request.setAttribute("login.message", "用户名或密码错误");
			return "failer";
		}

	}
}
login2.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>
	${requestScope["login.message"]}
	<br>
	<form action="${pageContext.request.contextPath}/login2" method="POST">
		username:<input type="text" name="user.username"><br>
		password:<input type="password" name="user.password"><br>
		<input type="submit" value="登录">
	</form>
</body>
</html>
3.模型驱动(action类实现ModelDrivern接口)
Login3Action
package cn.itcast.action;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import cn.itcast.domain.User;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

// 获取请求参数 模型驱动
public class Login3Action extends ActionSupport implements ModelDriven<User> {
	private User user=new User();
	
	@Override
	public User getModel() {
		return user;
	}
	
	@Override
	public String execute() throws Exception {
		HttpServletRequest request = ServletActionContext.getRequest();
		// 2.判断用户名与密码是否正确
		if ("tom".equals(user.getUsername())
				&& "123".equals(user.getPassword())) {

			request.getSession().setAttribute("username", user.getUsername());
			return SUCCESS;

		} else {
			request.setAttribute("login.message", "用户名或密码错误");
			return "failer";
		}

	}

}
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>
	${requestScope["login.message"]}
	<br>
	<form action="${pageContext.request.contextPath}/login3" method="POST">
		username:<input type="text" name="username"><br>
		password:<input type="password" name="password"><br>
		<input type="submit" value="登录">
	</form>
</body>
</html>

success.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>
	${username }
</body>
</html>

4.将数据封装到List集合
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值