@liayun
2016-10-03T02:03:18.000000Z
字数 13516
阅读 1842
Struts2框架学习
这是Struts2框架进阶三。废话不多说,直接进入正文。
在Struts2中,我们可以实现对action的所有方法进行校验或者对action的指定方法进行校验。
对于输入校验,Struts2提供了两种实现方法:
通过重写validate()或validateXxx()方法实现,validate()方法会校验action中所有与execute方法签名相同的方法。validateXxx()只会校验action中方法名为Xxx的方法。其中Xxx的第一个字母要大写。当某个数据校验失败时,我们应该调用addFieldError()方法往系统的fieldErrors添加校验失败信息(为了使用addFieldError()方法,action可以继承ActionSupport ),如果系统的fieldErrors包含失败信息,Struts2会将请求转发到名为input的result,在input视图中可以通过<s:fielderror/>显示失败信息。
首先我们编写struts.xml配置文件的内容为:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN""http://struts.apache.org/dtds/struts-2.3.dtd"><struts><package name="person" namespace="/person" extends="struts-default"><action name="manage_*" class="cn.itcast.action.PersonAction" method="{1}"><result name="input">/index.jsp</result><result name="message">/WEB-INF/page/message.jsp</result></action></package></struts>
接着我们在WebRoot根目录下创建出一个jsp页面——index.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>输入校验</title></head><body><form action="${pageContext.request.contextPath }/person/manage_save.action" method="post">用户名:<input type="text" name="username">不能为空<br/>手机号:<input type="text" name="mobile">不能为空,并且要符合手机好的格式:1,3/5/8,后面是9个数字<br/><input type="submit" value="提交"></form></body></html>
我们还要在WEB-INF/page/目录下创建出一个全局消息显示页面——message.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>结果</title></head><body>${message }</body></html>
最后我们在cn.itcast.action包下创建一个Action——PersonAction.java。
public class PersonAction extends ActionSupport {private String username;private String mobile;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getMobile() {return mobile;}public void setMobile(String mobile) {this.mobile = mobile;}public String update() {ActionContext.getContext().put("message", "更新成功");return "message";}public String save() {ActionContext.getContext().put("message", "保存成功");return "message";}}
以上准备工作做好之后,开始对PersonAction.java中的所有方法进行输入校验。我们只须在PersonAction类中添加如下方法即可:
@Overridepublic void validate() { // 会对action中的所有方法进行校验if (this.username==null || "".equals(this.username.trim())) {this.addFieldError("username", "用户名不能为空"); // 输出校验错误信息}if (this.mobile==null || "".equals(this.mobile.trim())) {this.addFieldError("mobile", "手机号不能为空");} else {if (!Pattern.compile("^1[358]\\d{9}$").matcher(this.mobile).matches()) {this.addFieldError("mobile", "手机号格式不正确");}}}
如果验证失败后,请求将转发至input视图:
<result name="input">/index.jsp</result>
在index.jsp页面中还要使用Struts2标签<s:fielderror/>显示校验失败信息。注意,还要在页面头部添加:
<%@ taglib="/struts-tags" prefix="s" %>
这样,index.jsp页面的内容就为:
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s" %><!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>输入校验</title></head><body><s:fielderror /><form action="${pageContext.request.contextPath }/person/manage_save.action" method="post">用户名:<input type="text" name="username">不能为空<br/>手机号:<input type="text" name="mobile">不能为空,并且要符合手机好的格式:1,3/5/8,后面是9个数字<br/><input type="submit" value="提交"></form></body></html>
这样,我们就实现了对action中的所有方法进行输入校验。大家亦可自行测试。
若是要对PersonAction.java中的update()方法进行输入校验,只须在PersonAction类中添加如下方法即可:
public void validateUpdate() { // 会对action中的update()方法进行校验if (this.username==null || "".equals(this.username.trim())) {this.addFieldError("username", "用户名不能为空"); // 输出校验错误信息}if (this.mobile==null || "".equals(this.mobile.trim())) {this.addFieldError("mobile", "手机号不能为空");} else {if (!Pattern.compile("^1[358]\\d{9}$").matcher(this.mobile).matches()) {this.addFieldError("mobile", "手机号格式不正确");}}}
这样,我们就实现了对action中的指定方法进行输入校验。大家亦可自行测试。
第2步说明了进入input视图有两种情况:
如果validate()方法中没有一行代码,但是还会进入input视图,原因就应该是类型转换失败了。我们举例来说明这一点。
我们首先修改index.jsp的页面内容为:
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s" %><!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>输入校验</title></head><body><s:fielderror /><form action="${pageContext.request.contextPath }/person/manage_update.action" method="post">用户名:<input type="text" name="username">不能为空<br/>生日:<input type="text" name="birthday"><br/>手机号:<input type="text" name="mobile">不能为空,并且要符合手机好的格式:1,3/5/8,后面是9个数字<br/><input type="submit" value="提交"></form></body></html>
接着修改PersonAction类的代码为:
public class PersonAction extends ActionSupport {private String username;private String mobile;private Date birthday;public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getMobile() {return mobile;}public void setMobile(String mobile) {this.mobile = mobile;}public String update() {ActionContext.getContext().put("message", "更新成功");return "message";}public String save() {ActionContext.getContext().put("message", "保存成功");return "message";}public void validateUpdate() { // 会对action中的update()方法进行校验}}
测试如下:
记得要插入.GIF的图片
验证了这一点。
若要基于XML配置方式实现输入校验,则Action类需要继承ActionSupport,然后还得提供校验文件,如下:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC"-//Apache Struts//XWork Validator 1.0.3//EN""http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"><validators><field name="username"><field-validator type="requiredstring"><param name="trim">true</param><message>用户名不能为空!</message></field-validator></field></validators>
初学者可能不知道以上的校验文件怎么写,但没关系,Struts2框架给开发人员提供了一些案例,我们可以拷贝其中的校验文件到我们的项目中,然后修修改改。如我们可以在诸如...\struts-2.3.24\apps\struts2-blank\WEB-INF\classes\example目录下找到这样的校验文件——Login-validation.xml,打开:
<!DOCTYPE validators PUBLIC"-//Apache Struts//XWork Validator 1.0.2//EN""http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd"><validators><field name="username"><field-validator type="requiredstring"><message key="requiredstring"/></field-validator></field><field name="password"><field-validator type="requiredstring"><message key="requiredstring"/></field-validator></field></validators>
发现该校验文件使用的是XWork Validator 1.0.2版本,该版本对有些输入校验不友好,所以就不要选用这个版本了,最好是选用1.0.3版本。总之,不要使用XWork Validator 1.0.2这个版本。
好了,我们还是回到一开始的校验文件。在这个校验文件中,对action中字符串类型的username属性进行验证,首先要求调用trim()方法去掉空格,然后判断用户名是否为空。该文件需要和action类放在同一个包下,文件的取名应遵守ActionClassName-validation.xml规则,其中ActionClassName为action的简单类名,-validation为固定写法。如果Action类为cn.itcast.action.UserAction,那么该文件的取名应为:UserAction-validation.xml。
我们把注意力集中在这段代码上面:
<field name="username"><field-validator type="requiredstring"><param name="trim">true</param><message>用户名不能为空!</message></field-validator></field>
<field>指定action中要校验的属性。<field-validator>指定校验器。<message>为校验失败后的提示信息,如果需要国际化,可以为message指定key属性,key的值为属性文件中的key。上面指定的校验器requiredstring是由系统提供的,系统提供了能满足大部分验证需求的校验器,这些校验器的定义可以在xwork-core-2.x.x.jar中的com.opensymphony.xwork2.validator.validators下的default.xml中找到。
下面我们就来详细说明系统提供的校验器。
系统提供的校验器如下:
required(必填校验器,要求field的值不能为null),如:
<field-validator type="required"><message>性别不能为空!</message></field-validator>
requiredstring(必填字符串校验器,要求field的值不能为null,并且长度大于0,默认情况下会对字符串去前后空格),如:
<field-validator type="requiredstring"><param name="trim">true</param><message>用户名不能为空!</message></field-validator>
stringlength(字符串长度校验器,要求field的值必须在指定的范围内,否则校验失败,minLength参数指定最小长度,maxLength参数指定最大长度,trim参数指定校验field之前是否去除字符串前后的空格),如:
<field-validator type="stringlength"><param name="maxLength">10</param><param name="minLength">2</param><param name="trim">true</param><message><![CDATA[产品名称应在1-10个字符之间]]></message></field-validator>
regex(正则表达式校验器,检查被校验的field是否匹配一个正则表达式。expression参数指定正则表达式,caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认值为true),如:
<field-validator type="regex"><param name="expression"><![CDATA[^1[358]\d{9}$]]></param><message>手机号格式不正确!</message></field-validator>
int(整数校验器,要求field的整数值必须在指定范围内,min指定最小值,max指定最大值),如:
<field-validator type="int"><param name="min">1</param><param name="max">150</param><message>年龄必须在1-150之间</message></field-validator>
fieldexpression(字段OGNL表达式校验器,要求field满足一个OGNL表达式,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过),如:
<field name="imagefile"><field-validator type="fieldexpression"><param name="expression"><![CDATA[imagefile.length() > 0]]></param><message>文件不能为空</message></field-validator></field>
email(邮件地址校验器,要求如果field的值非空,则必须是合法的邮件地址),如:
<field-validator type="email"><message>电子邮件地址无效</message></field-validator>
弄清楚上面的知识点之后,我们就基于XML配置方式实现对action的所有方法进行校验。
首先我们将PersonAction类的代码修改为:
public class PersonAction extends ActionSupport {private String username;private String mobile;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getMobile() {return mobile;}public void setMobile(String mobile) {this.mobile = mobile;}public String update() {ActionContext.getContext().put("message", "更新成功");return "message";}public String save() {ActionContext.getContext().put("message", "保存成功");return "message";}}
接着我们还要修改index.jsp页面的内容为:
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s" %><!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>输入校验</title></head><body><s:fielderror /><form action="${pageContext.request.contextPath }/person/manage_save.action" method="post">用户名:<input type="text" name="username">不能为空<br/>手机号:<input type="text" name="mobile">不能为空,并且要符合手机好的格式:1,3/5/8,后面是9个数字<br/><input type="submit" value="提交"></form></body></html>
最后我们就要在cn.itcast.action包下提供校验文件了,文件名必须为PersonAction-validation.xml。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC"-//Apache Struts//XWork Validator 1.0.3//EN""http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"><validators><field name="username"><field-validator type="requiredstring"><param name="trim">true</param><message>用户名不能为空!</message></field-validator></field><field name="mobile"><field-validator type="requiredstring"><message>手机号不能为空!</message></field-validator><field-validator type="regex"><param name="expression"><![CDATA[^1[358]\d{9}$]]></param><message>手机号格式不正确!</message></field-validator></field></validators>
测试,发现正则表达式校验器不起作用,原因不知为何?
当校验文件的取名为ActionClassName-validation.xml时,会对action中的所有处理方法实施输入验证。如果你只需要对action中的某个处理方法实施验证,那么,校验文件的取名应为:ActionClassName-ActionName-validation.xml,其中ActionName为struts.xml中为action配置的名称。例如:在实际应用中,常有以下配置:
<action name="user_*" class="cn.itcast.action.UserAction" method="{1}"><result name="success">/WEB-INF/page/message.jsp</result><result name="input">/WEB-INF/page/addUser.jsp</result></action>
UserAction中有以下两个处理方法:
public String add() throws Exception{....}public String update() throws Exception{....}
如果我们要访问UserAction类中的add()方法,那极有可能在浏览器中输入这样的URL地址:.../person/user_add.action,这时我们有必要知道Struts2框架是如何解析这样的URL地址的。
Struts2框架在寻找action的时候,先解析出:namespace=/person,然后再解析出:ActionName=user_add,也即是说,ActionName是路径中的,而不是<action>标签中的name。所以,
现在我们基于XML配置方式只实现对PersonAction的update()方法进行输入校验。我们只须在cn.itcast.action包下提供校验文件即可,校验文件必须得为PersonAction-manage_update-validation.xml。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC"-//Apache Struts//XWork Validator 1.0.3//EN""http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"><validators><field name="username"><field-validator type="requiredstring"><param name="trim">true</param><message>用户名不能为空!</message></field-validator></field><field name="mobile"><field-validator type="requiredstring"><message>手机号不能为空!</message></field-validator><field-validator type="regex"><param name="expression"><![CDATA[^1[358]\d{9}$]]></param><message>手机号格式不正确!</message></field-validator></field></validators>
测试,发现正则表达式校验器不起作用,原因不知为何?
当为某个action提供了ActionClassName-validation.xml和ActionClassName-ActionName-validation.xml两种规则的校验文件时,系统按下面顺序寻找校验文件:
系统寻找到第一个校验文件时还会继续搜索后面的校验文件,当搜索到所有校验文件时,会把校验文件里的所有校验规则汇总,然后全部应用于处理方法的校验。如果两个校验文件中指定的校验规则冲突,则只使用后面文件中的校验规则。
当action继承了另一个action,父类action的校验文件会先被搜索到。假设UserAction继承BaseAction, UserAction在struts.xml中的配置如下:
<action name="user" class="cn.itcast.action.UserAction" method="{1}">.....</action>
访问上面名为user的action,系统先搜索到BaseAction-validation.xml, BaseAction-user-validation.xml,接着搜索到UserAction-validation.xml, UserAction-user-validation.xml。校验规则是这四个文件的总和。