Struts2为了简化我们的开发,也提供了数据校验的功能…前面已经说过了,如果想要使用数据校验的功能,在编写Action的时候就必须继承着ActionSupport类或者实现相对应的接口
现在,我们的Action类已经继承了ActionSupport类了,现在那怎么使用数据校验的功能呢??我们想一下….
如果我们不写FormBean对象,直接在Action进行校验的话,我们可能会这样写:
private Map<String, String> map; public void validation() { //如果有错误了,那么就将错误信息添加到map集合 map.put(); } public String login() { //判断map是否有错误信息,如果有,就直接跳转到相对应的页面了,不执行login剩下的代码了。 }上面的思路是可行的,但是不优雅…..在login()方法验证map集合,就与数据校验耦合了….于是乎,我们想要的是在调用login()方法之前就验证map集合是否存在…如果存在了错误的信息,就不调用login()方法了。
明显地,我们就需要使用拦截器…….Struts2内部的数据校验也是使用拦截器来实现的。
<interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>Struts2为我们提供了4种方式来实现拦截
使用代码拦截所有的方法使用代码拦截部分的方法使用XML配置拦截所有的方法使用XML配置拦截部分的方法Struts2提供了我们做校验的方法….实现validate()
@Override public void validate() { super.validate(); }validate()方法在内部已经维护了一个Map集合了
public synchronized void addFieldError(String fieldName, String errorMessage) { Map errors = this.internalGetFieldErrors(); Object thisFieldErrors = (List)errors.get(fieldName); if(thisFieldErrors == null) { thisFieldErrors = new ArrayList(); errors.put(fieldName, thisFieldErrors); } ((List)thisFieldErrors).add(errorMessage); }我们如果捕获到了错误信息,那么直接使用底层为我们写好的Map集合就好了!
@Override public void validate() { //判断用户名是否为空 if (user.getUsername() == null || "".equals(user.getUsername())) { super.addFieldError("username","用户名是空的"); } //判断密码是否为空 if (user.getPassword() == null || "".equals(user.getPassword())) { super.addFieldError("username","密码是空的"); } }配置struts.xml文件
<package name="xxx" extends="struts-default"> <action name="user_*" class="zhongfucheng.action.UserAction" method="{1}"> <!--如果校验成功,那么回到首页--> <result name="success">/index.jsp</result> <!--如果失败,重新回到login页面,并显示错误信息--> <result name="input">/login.jsp</result> </action> </package>在JSP页面中,可以使用Struts自带的标签来显示错误信息
<s:fielderror></s:fielderror> 测试:上面已经实现了数据校验的功能了,但是呢。现在我有一个list()方法。使用list()方法讲道理是不用进行数据校验的…
//查看user信息 public String list() { return SUCCESS; }但是呢,当我执行list()方法的时候,还是经过了数据校验….
因此,我们要做的是:拦截特定的方法..非常简单,只要重命名validate()方法就行了!
格式:validate + 要验证的方法名将validate()方法名改成是validateLogin(),那么Struts2就仅仅过滤指定的方法了。
前面我们已经使用过了代码验证的方法,,,,感觉还是要写很多代码….很多代码也是啰嗦的,要判断非空啊,数值的验证啊..等等的处理…这样判断、验证往往都是通用的…于是Struts又帮我们封装了很多的校验器
路径: xwork-core-2.3.4.1.jar/com.opensymphony.xwork2.validator.validators/default.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator Definition 1.0//EN" "http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd"> <!-- START SNIPPET: validators-default --> <validators> <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/> <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/> <validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/> <validator name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/> <validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/> <validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/> <validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/> <validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/> <validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/> <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/> <validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/> <validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/> <validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/> <validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/> <validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/> <validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/> </validators> <!-- END SNIPPET: validators-default -->以上的校验器我们可以通过XML文件来配置,编写XML文件的语法:
名称语法: ActionClassName-validation.xmlxml需要与当期要验证的action在同一个目录例子:UserAction-validation.xml那么XML该怎么写呢????Struts2也为我们提供了DTD文件
<?xml version="1.0" encoding="UTF-8"?> <!-- XWork Validators DTD. Used the following DOCTYPE. <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> --> <!ELEMENT validators (field|validator)+> <!ELEMENT field (field-validator+)> <!ATTLIST field name CDATA #REQUIRED > <!ELEMENT field-validator (param*, message)> <!ATTLIST field-validator type CDATA #REQUIRED short-circuit (true|false) "false" > <!ELEMENT validator (param*, message)> <!ATTLIST validator type CDATA #REQUIRED short-circuit (true|false) "false" > <!ELEMENT param (#PCDATA)> <!ATTLIST param name CDATA #REQUIRED > <!ELEMENT message (#PCDATA|param)*> <!ATTLIST message key CDATA #IMPLIED > 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> <!--指定Bean对象的username属性--> <field name="user.username"> <!--指定类型不能是空的--> <field-validator type="requiredstring"> <message>用户名不能是空的</message> </field-validator> </field> <!--指定Bean对象的属性--> <field name="user.password"> <!--指定类型不能是空的--> <field-validator type="requiredstring"> <message>密码不能是空的</message> </field-validator> <!--设置密码的长度6到8位--> <field-validator type="stringlength"> <param name="minLength">6</param> <param name="maxLength">8</param> <message>密码只能是6-8位</message> </field-validator> </field> </validators>用户名和密码都不能为空
密码只能是6-8位
和代码的方式一样,我们写上了XML文件,它也是默认拦截所有的方法。那么我们想要它只拦截特定的方法,怎么办呢???
修改XML文件的名称:
语法:ActionClassName-ActionName-validation.xml例子:UserAction-user_login-validation.xml我们发现,返回错误信息的样式是这样的:
这明显不符合我们的审美的……于是乎我们是可以修改它的样式的…我们查看源文件的时候,可以发现Struts为它自动加了ul li
我们可以在css文件中把它们去除就行了
<style type="text/css"> ul{ display: inline; } ul li { display: inline; color: red;; } </style>Struts2标签的样式是由文件来指定的…具体路径如下:
我们发现ul li是它指定加上去的,我们把它修改,然后覆盖掉它,那么Struts2在读取的时候就使用我们的文件
在src下创建template.simple包..文件是fielderror.ftl…项目在执行的时候就会把Struts2自带的给覆盖了!
使用<s:fielderror></s:fielderror>是默认返回全部错误的,我们通常来说,都是把错误放在输入框的后面的…Struts提供了指定返回错误..只要指定fileName就行了
<form action="${pageContext.request.contextPath}/user_login" method="post"> 用户名:<input type="text" name="user.username"><s:fielderror fieldName="user.username"/><br> 密码:<input type="password" name="user.password"><s:fielderror fieldName="user.password"/><br> <input type="submit" value="登陆"><br> </form>Struts2也支持客户端的校验,在使用Struts2的form标签的使用,在validate属性上设置为true,那么Struts2会自动加载JavaScript的类库来实现客户端的数据校验了!
Struts2也提供了客户端的数据校验功能….
我们现在已经学会了使用手写代码的方式和XML配置的方式去校验数据了。。
那么哪种方式更好呢???我们来总结一下
手写代码方式:
更加灵活,要校验的逻辑全都是自己把握但是比较繁琐,有很多的重复逻辑代码XML配置方式
不用自己手写逻辑代码,调用Struts提供给我们的拦截器即可但是如果拦截的方法比较多的话,会出现多个XML配置文件最后补充:Struts2也支持通过注解的方式实现数据校验,但是这会造成Action类看起来十分冗余,一般很少使用