文档版本 | 开发工具 | 测试平台 | 工程名字 | 日期 | 作者 | 备注 |
---|---|---|---|---|---|---|
V1.0 | 2016.06.14 | lutianfei | none |
1.直接将action做一个model(类似bean结构),就可以得到请求参数.
配合第一天作业案例,修改Login1Action.java
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";
}
}
}
2.在action中声明一个model。
Login2Action.java
//获取请求参数 属性驱动 第二种,直接在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";
}
}
}
<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>
public class Login3Action extends ActionSupport implements ModelDriven<User> { //第一步:implements ModelDriven
private User user = new User(); //第三步
public User getModel() { //第二步
return user;
}
}
//jsp
${requestScope["login.message"] }
缺点:一次只能封装一个model对象.
struts2 有很多围绕模型驱动的特性
为模型驱动提供了更多特性页面:
username1:type="text" name="users[0].username">
password1:type="password" name="users[0].password">
username2:type="text" name="users[1].username">
password2:type="password" name="users[1].password">
action类:
public class ListAction extends ActionSupport {
private List users;
public List getUsers() {
return users;
}
public void setUsers(List users) {
this.users = users;
}
@Override
public String execute() throws Exception {
System.out.println(users);
return null;
}
}
//struts.xml配置
"list" class="cn.itcast.action.ListAction">
action>
页面:
username1:type="text" name="map['aaa'].username">
password1:type="password" name="map['aaa'].password">
username2:type="text" name="map['bbb'].username">
password2:type="password" name="map['bbb'].password">
public class MapAction extends ActionSupport {
private Map map;
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
@Override
public String execute() throws Exception {
System.out.println(map);
return null;
}
}
struts2中action得到请求参数,也可以直接封装到javaBean.
struts2 内部提供大量类型转换器,用来完成数据类型转换问题
但并不是所有的类型都支持
关于struts2中的类型转换器根接口是:com.opensymphony.xwork2.conversion.TypeConverter
。
1.实现TypeConverter需要重写如下方法:
public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType);
如果实现接口,这个方法参数太多(6个),不推荐。2.继承 DefaultTypeConverter类
public Object convertValue(Map context, Object value, Class toType) {return convertValue(value, toType);}
3.推荐使用 继承DefaultTypeConverter类
的一个子类StrutsTypeConverter
.
public abstract Object convertFromString(Map context, String[] values, Class toClass);
public abstract String convertToString(Map context, Object o);
1.局部–针对于action(action中包含了一个Bean结构)
Action类名-conversion.properties
属性名称=类型转换器的全类名
eg:
birthday= test.utils.MyTypeConverter
public class MyTypeConverter extends StrutsTypeConverter{
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
// System.out.println(context); //ognl.OgnlContext@faae2497
// System.out.println(values[0]); //1990/11/10
// System.out.println(toClass); //class java.util.Date
String value = values[0];
SimpleDateFormat sdf =new SimpleDateFormat("yyyy/MM/dd");
Date date = null;
try {
date = sdf.parse(value);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return date;
}
public class RegistAction extends ActionSupport implements ModelDriven<User>{
private User user = new User();
@Override
public User getModel() {
//
return user;
}
@Override
public String execute() {
System.out.println(user);
return null;
}
}
<struts>
<package name="default" namespace="/" extends ="struts-default">
<action name="regist" class = "test.action.RegistAction">
<result name="input">/success.jspresult>
action>
package>
struts>
<body>
<form action="${pageContext.request.contextPath}/regist" method="post">
username:<input type="text" name="username"><br>
password:<input type="password" name="password"><br>
hobby:<input type="checkbox" name="hobby" value="eat">吃<input
type="checkbox" name="hobby" value="drink">喝<input
type="checkbox" name="hobby" value="play">玩<br> age:<input
type="text" name="age"><br> birthday:<input type="text"
name="birthday"><br> <input type="submit" value="注册">
form>
body>
2.局部–针对于model(action中实例化了一个Bean)
model类名-conversion.properties
属性名称=类型转换器的全类名
eg:在上例的基础上做如下修改
RegistAction.jsp
public class RegistAction extends ActionSupport {
private String username;
private String password;
private int age;
private Date birthday;
private String[] hobby;
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String execute() throws Exception {
System.out.println(this.toString());
return null;
}
@Override
public String toString() {
return "RegistAction [username=" + username + ", password=" + password
+ ", age=" + age + ", birthday=" + birthday + ", hobby="
+ Arrays.toString(hobby) + "]";
}
}
3.全局
xwork-conversion.properties
要转换的类型全名=类型转换器的全类名
eg:
src
目录下就好。java.util.Date=test.utils.MyTypeConverter
注意:
对于struts2中类型转换器(非自定义),如果表单数据提交时,将数据向model封装,出现了问题,会报错:
No result defined for action cn.itcast.action.RegistAction and result input
意思是,在RegistAction的配置中没有配置input结果视图;当加入result name=input
标签时,会跳转到对应的页面(例如success.jsp)
name="regist" class="cn.itcast.action.RegistAction">
<result name="input">/success.jspresult>
用于记录类型转换问题。
用于得到问题,向input视图跳转。
显示错误信息如果想通过国际化改为中文显示需要在Action所在包中,创建 ActionName.properties
,在局部资源文件中配置提示信息 : invalid.fieldvalue.属性名= 错误信息
eg:
//注意加 taglib
<%@ taglib prefix="s" uri="/struts-tags" %>
<body>
<s:fielderror/>
body>
//RegisAction.properties
invalid.fieldvalue.birthday=\u65E5\u671F\u683C\u5F0F\u8981\u6C42 yyyy/MM/dd
public class MyTypeConverter extends StrutsTypeConverter {
// 接收页面传递的数据封装到javaBean.
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
// System.out.println(context); //ognl.OgnlContext@faae2497
// System.out.println(values[0]); //[Ljava.lang.String;@100c4d
// System.out.println(toClass); //class java.util.Date
String value = values[0];
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
Date date = null;
try {
date = sdf.parse(value);
} catch (ParseException e) {
// e.printStackTrace();
throw new RuntimeException();
}
return date;
}
在开发中,请求参数是需要校验的。
struts2中提供的校验—–服务器端校验。
validate
struts2提供的校验,也是通过拦截器实现的。
问题:在validate方法中怎样存储校验错误信息?
@Override
public void validate() {
if (user.getUsername() == null
|| user.getUsername().trim().length() == 0) {
// 说明用户名为空
this.addFieldError("username.message", "用户名不能为空");
}
if (user.getPassword() == null
|| user.getPassword().trim().length() == 0) {
this.addFieldError("password.message", "密码不能为空");
}
if (!(user.getAge() >= 10 && user.getAge() <= 40)) {
this.addFieldError("age.message", "年龄必须在10-40之间");
}
// System.out.println("validate......");
}
展示所有错误信息
展示特定名称的错误信息. <s:fielderror/>
<form action="${pageContext.request.contextPath}/regist" method="post">
username:<input type="text" name="username"><s:fielderror fieldName="username.message"/><br>
password:<input type="password" name="password"><s:fielderror fieldName="password.message"/><br>
validate+请求处理方法名
regist()
校验的 方法名 validateRegist()
validate
方法时,会先运行validateRegist()
方法,后运行validate()
方法。已经完成了校验操作(做了很多校验方法)。而我们在使用时,只需要将它们调用就可以(通过配置文件)
要求:action类必须继承自ActionSupport类。
action类名-validation.xml
xwork-core-2.3.7.jar
中 xwork-validator-1.0.3.dtd
下
子元素
xwork-core-2.3.7.jar
中 /com/opensymphony/xwork2/validator/validators/default.xml下name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
子元素
错误信息
5.
子元素
值
: 用于指定校验器中的参数。eg :
<validators>
<field name="username">
<field-validator type="requiredstring">
<message>用户名不能为空--------message>
field-validator>
validators>
required
(必填校验器,要求被校验的属性值不能为null)
requiredstring
(必填字符串校验器,要求被校验的属性值不能为null,并且长度大于0,默认情况下会对字符串去前后空格),如果不想去空格,只需如下设置。
stringlength
(字符串长度校验器,要求被校验的属性值必须在指定的范围内,否则校验失败
regex
正则表达式校验器,检查被校验的属性值是否匹配一个正则表达式,expression参数指定正则表达式,caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认值为true)
int(整数校验器,要求field的整数值必须在指定范围内
double
(双精度浮点数校验器,要求field的双精度浮点数必须在指定范围内,min指定最小值,max指定最大值)
fieldexpression
(字段OGNL表达式校验器,要求field满足一个ognl表达式,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过)
email
(邮件地址校验器,要求如果被校验的属性值非空,则必须是合法的邮件地址)
url(网址校验器,要求如果被校验的属性值非空,则必须是合法的url地址)
date
:日期校验器,要求field的日期值必须在指定范围内
问题:通过配置校验,怎样处理在同一个action中存在多个请求处理方法校验问题?
action类名-valication.xml
现在要对action类中某一个方法校验。action类名-action名称-validation.xml