- 浏览: 328866 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
xuechenyoyo:
用Java播放mp3音乐 -
javacainiaosc:
在Ubuntu 编译的jdk在windows下可以使用吗
OpenJDK和JDK区别 -
wkk2620632:
同问
DB2中SQLSTATE=57016 SQLCODE=-668,原因码 "7"的解决 -
gary_bu:
student_list表中的'index'字段只是为了存储l ...
hibernate中List一对多映射关系详解 -
adam52:
草鸟学习啦
转载的
Struts2的 输入校验
信息基本校验
对于每个web框架输入输入校验都是一个重要的部分,对用户输入的数据进行有效的过滤,是保持系统安全的一方面措施.Struts2也不例外,同样也提供了更简易的输入校验机制,Struts2提供的输入校验有两种方式,一种是硬编码的方式,一种是采用Struts2的输入校验框架进行校验,即采用XML配置的方式进行校验。
下面我们看一上采集硬编码的方式如果校验:
举例说明:需要对一个用户注册的数据进行校验
首先要在myeclipse中创建一Web工程,在src目录中创建struts.xml文件,到struts2的资源包中例子中拷
1.1在WebRoot下面创建一个register.jsp页面,代码
<%@pagelanguage="java"pageEncoding="UTF-8"%>
<%@tagliburi="/struts-tags"prefix="s"%>
<!DOCTYPEHTMLPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>register page</title>
<metahttp-equiv="pragma"content="no-cache">
<metahttp-equiv="cache-control"content="no-cache">
<metahttp-equiv="expires"content="0">
<metahttp-equiv="keywords"content="keyword1,keyword2,keyword3">
<metahttp-equiv="description"content="This is my page">
</head>
<body>
<formaction="register.action"method="post">
<fontcolor="red"size="2"><s:fielderror/></font>
<tableborder="1"cellpadding="0"cellspacing="0"width="500">
<tr>
<tdcolspan="2">用户注册</td>
</tr>
<tr>
<tdwidth="100">username</td>
<td><inputtype="text"name="username"value="${requestScope.username }"/>6-10 cahr</td>
</tr>
<tr>
<td>password</td>
<td><inputtype="password"name="password"value="${requestScope.password }"/></td>
</tr>
<tr>
<td>re-password</td>
<td><inputtype="password"name="repassword"value="${requestScope.repassword }"/></td>
</tr>
<tr>
<td>age</td>
<td><inputtype="text"name="age"value="${requestScope.age }"/>0-150</td>
</tr>
<tr>
<td>birthday</td>
<td><inputtype="text"name="birthday"value="${requestScope.birthday }"/>must be date</td>
</tr>
<tr>
<td>graduation</td>
<td><inputtype="text"name="graduation"value="${requestScope.graduation }"/>must after birthday</td>
</tr>
<tr>
<td></td>
<td><inputtype="submit"value="register"/></td>
</tr>
</table>
</form>
</body>
</html>
上面一个表单使用HTML描述表单内容。显示如:
校验需要,username:不能为空必须是6-10个字符
password repassword不能为空必须是6-10个字符,而且两次输入密码要一致
age必须是0-150数字
birthday graduation都必须是日期,且出生日期要大于毕业日期
1.2下面创建一个RegisterAction来处理用户注册数据代码如下:
package com.snt.struts2.action;
import java.util.Calendar;
import java.util.Date;
import com.opensymphony.xwork2.ActionSupport;
public class RegisterAction extends ActionSupport {
private String username;
private String password;
private String repassword;
private int age;
private Date birthday;
private Date graduation;
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;
}
public Date getGraduation() {
return graduation;
}
public void setGraduation(Date graduation) {
this.graduation = graduation;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRepassword() {
return repassword;
}
public void setRepassword(String repassword) {
this.repassword = repassword;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
public String abc()throws Exception{
System.out.println("abc method invoke!");
return SUCCESS;
}
public String xyz()throws Exception{
System.out.println("abc method invoke!");
return SUCCESS;
}
public void validateAbc(){
System.out.println("valide abc()");
}
public void validateXyz(){
System.out.println("valide xyz()");
}
/***
*当遇到类型转化时,struts2自动生成一条错误信息,放到
* fielderrors中
*/
@Override
public void validate() {
//当用户直接访问action时,action的属性都是null
//防止NullPointException
System.out.println("validate()...........");
if(null==username || username.length()<6 || username.length()>10){
this.addFieldError("username", "username is invalid");
}
if(null==password ||password.length()<6 || password.length()>10){this.addFieldError("password", "password is invalid!");
}else if(null==repassword ||repassword.length()<6 || repassword.length()>10){
this.addFieldError("password", "password is invalid!");
}else if(!password.equals(repassword)){
this.addFieldError("password", "tow password is not be same!");
}
if(age<0 || age>150){
this.addFieldError("age", "age is invalid!");
}
if(null==birthday){
this.addFieldError("birthday", "birthday invalid!");
}
if(null==graduation){
this.addFieldError("graduation", "graduationinvalid!");
}
if(null!=birthday && null!=graduation){
Calendar c1=Calendar.getInstance();
c1.setTime(birthday);
Calendar c2=Calendar.getInstance();
c2.setTime(graduation);
if(!c1.before(c2)){
this.addFieldError("birthday","birthday shoud before graduation!");
}
}
}
}
红色的是检验的代码,我创建的Action继承了ActionSupport类,ActionSupport双继承了Validateable和ValidationAware接口,validate()是Validateable接口中的方法,我们继承Validateable接口,实现validate()就可以在调用Action的execute()方法之前,执行validate()方法进行数据检验。根据的我们的检验逻辑如果某个属性出错了,会产生一个相应的错误信息,以属性名为Key值,以错误信息为值,形成一个键值对通过addFieldError()方法放在一个保存错误信息的Map中,下面介绍一个addFieldError()方法的原理:
下面是ActionSupport中的一些方法:
private final ValidationAwareSupport validationAware=new ValidationAwareSupport();
//struts2是采用上面的ValidationAwareSupport这个类完成的类完成的。
//设置字段错误信息
publicvoidsetFieldErrors(Map<String, List<String>> errorMap) {
validationAware.setFieldErrors(errorMap);
}
//获取所有字段错误信息
publicMap<String, List<String>> getFieldErrors() {
returnvalidationAware.getFieldErrors();
}
//我们从上面的方法大致可以看出来,struts2是如下保存错误信息:
每个字段的错误是这样保存的每个字段上可能产生多条错误信息,所有保存时是:字段名为Key,
将所有这个字段的错误形成一个List作为value值,放在Map的一条记录中。
//添加一条字段错误信息
publicvoidaddFieldError(String fieldName, String errorMessage) {
validationAware.addFieldError(fieldName, errorMessage);
}
下面是ValidationAwareSupport部分源代码:
publicclassValidationAwareSupportimplementsValidationAware, Serializable {
privateCollection<String>actionErrors;//保存Action级别的错误信息Collection
privateMap<String, List<String>>fieldErrors;//保存Field级别的错误信息Map
//添加一条字段错误的详细代码
publicsynchronizedvoidaddFieldError(String fieldName, String errorMessage) {
//获取所有字段错误的Map
finalMap<String, List<String>> errors =internalGetFieldErrors();
//取出对应字段的错误信息列表
List<String> thisFieldErrors = errors.get(fieldName);
//如果之前没有错误,新创建一个List保存错误信息
if(thisFieldErrors ==null) {
thisFieldErrors =newArrayList<String>();
errors.put(fieldName, thisFieldErrors);
}
//将错误信息添加到列表中
thisFieldErrors.add(errorMessage);
}
//初始化存储错误的信息的Map
privateMap<String, List<String>>internalGetFieldErrors() {
if(fieldErrors==null) {
fieldErrors=newLinkedHashMap<String, List<String>>();
}
returnfieldErrors;
}
}
1.3在struts.xml文件本配置RegisterAction如下:
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEstrutsPUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constantname="struts.custom.i18n.resources"value="message"/>
<packagename="struts2"extends="struts-default">
<actionname="register"
class="com.snt.struts2.action.RegisterAction">
<resultname="success">/success.jsp</result>
<resultname="input">/register2.jsp</result>
</action>
</package>
</struts>
运行应用测试:
OK,验证信息成功,但是我们发现错误信息中出现一些我们没有见过的信息,
比如:Invalid field value for field "birthday".这样的信息,这是由Struts2自身的校验给出来的信息,默认的情况下,如果遇到类型转化失败的问题,struts2会自动添加一条错误信息,使用addFieldError()添加一条错误信息。但是这样的信息并不是我们想要的,因为这些信并不友好,我们又不好控制,所有我们要想办法取消这些信息,但是这些是信息是struts2自身的一些拦截器实现的功能,又不容易取掉(应该可以去掉,可以找到这个拦截器,重写它去掉这部分功能,自己再组织拦截器栈),所以考虑将其替换掉;因此Struts2提供一此替换这些信息的方法:1可以通过替换国际化资源配置文件,来达到目的,具体做法:
[1]在strrts.xml配置中指定国际化资源文件常量
在<package >标签下加一条
<constantname="struts.custom.i18n.resources"value="message"/>
Name代表常量名,固定的;value代表指定的资源配置文件
这样配置会覆盖default.properties中struts2的配置常量
[2]在classes目录下,创建工程时可以在src目录下创建一个message.properties文件,文件名要和上面的vlaue值对应,这个文件是全局的配置,输入内容如下:
xwork.default.invalid.fieldvalue={0}error
等号左边的是固定不变的,右边是{0}一个占位符,将来会被错误的字段名替换;
也是当一个字段发生错误了,比如:age转化时错了,就会显示age error的信息
运行测试,这样显示就友好一点了!如下显示:
但是还存在一些问题,信息出错时,错误信息显示太死板了,我们想给一些字段加上个性化的信息。Struts2也提供对应的方法:
[1]在需要输入校验的Action同目标下,创建一个与Action同名的资源文件,比如:RegisterAction.properties这个文件将成功局部的资源配置文件,它里面的配置可以替换全局的配置;输入以下内容
invalid.fieldvalue.age=/u5e74/u9f84/u8f93/u5165/u4fe1/u606f/u4e0d/u6b63/u786e
invalid.fieldvalue.birthday=/u65e5/u671f/u8f93/u5165/u9519/u8bef
invalid.fieldvalue.graduation=/u6bd5/u4e1a/u65f6/u95f4/u65e5/u671f/u8f93/u5165/u4e0d/u6b63/u786e
这样的信息,注意等号左边的invalid.fieldvalue是固定的,之后跟的是字段名;右边是要显示的错误信息;采用的是Unicode码表示的!因为是中文,所有需要使用JDK中的native2ascii命令将汉字翻译成unicode码,即可使用。Native2ascii命令在JDK安装目录/bin下面。
这样运行即可以显示友好的中文信息:
回显表单数据,排除信息重复显示
OK,上面的基本的输入校验已经完成,当然还存在一些问题,比如:错误信息提示还是有重复的,当数据错误时不能回显,这都是一些不友好的做法!我们下面一步步完善!
为了添加回显的功能,我用采用Struts2标签库来很容易地实现!当然使用HTML,通过JSP的EL表达式也可以实现回显,上面写过了,介这种做法并不好,显示过程中可能会出现问题,特别是日期显示那块!
下面我们采用struts2的标签库来重构页面:
创建一个register2.jsp页面,导入struts2的标签库,代码如下:
<%@pagelanguage="java"pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPEHTMLPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>register page</title>
<metahttp-equiv="pragma"content="no-cache">
<metahttp-equiv="cache-control"content="no-cache">
<metahttp-equiv="expires"content="0">
<metahttp-equiv="keywords"content="keyword1,keyword2,keyword3">
<metahttp-equiv="description"content="This is my page">
</head>
<!--回显-->
<body>
<s:actionerror cssStyle="color:red;"/>
<hr>
<s:fielderror cssStyle="color:red;"/>
<s:formaction="register2"theme="simple">
<tableborder="1"cellpadding="0"cellspacing="0">
<tr>
<td>username</td>
<td><s:textfieldname="username"label="usernmae"/></td>
</tr>
<tr>
<td>password</td>
<td><s:passwordname="password"label="password"/></td>
</tr>
<tr>
<td>repassword</td>
<td><s:passwordname="repassword"label="repassword"/></td>
</tr>
<tr>
<td>age</td>
<td><s:textfieldname="age"label="age"/></td>
</tr>
<tr>
<td>birthday</td>
<td><s:textfieldname="birthday"label="birthday"/></td>
</tr>
<tr>
<td>graduation</td>
<td><s:textfieldname="graduation"label="graduation"/></td>
</tr>
<tr>
<td> </td>
<td><s:submit/></td>
</tr>
</table>
</s:form>
</body>
</html>
上面我们采用了表格布局,当然如果不采用表格的话,struts2在翻译struts2标签是,会为每个标签添加一个单元格将控件括起来。这是struts表单默认的显示样式。
显示如下:
运行测试仪可以正常回显数据:
错误级别
上面我们提到过,错误信息的级别,其实Struts2中的错误有两种级别:
1.Action级别的错误
2.Field级别的错误
而Struts2只有判断到两种错误级别的信息都没有的情况,才认为是输入校验通过。
查看VlidationAwareSupport类的原代码:高亮显示的一句代码,可以确定struts2是这样做的。
publicsynchronizedbooleanhasActionErrors() {
return(actionErrors!=null) && !actionErrors.isEmpty();
}
publicsynchronizedbooleanhasActionMessages() {
return(actionMessages!=null) && !actionMessages.isEmpty();
}
publicsynchronizedbooleanhasErrors() {
return(hasActionErrors() || hasFieldErrors());
}
publicsynchronizedbooleanhasFieldErrors() {
return(fieldErrors!=null) && !fieldErrors.isEmpty();
}
下面我们重写一下validate()方法,将所有添加addFieldError()的信息,转化成addActionError();
如下:
publicvoidvalidateExecute() {
//当用户直接访问action时,action的属性都是null
//防止NullPointException
System.out.println("validate()...........");
if(null==username||username.length()<6 ||username.length()>10){
this.addActionError("username invalid!");
}
if(null==password||password.length()<6 ||password.length()>10){
this.addActionError("password is invalid!");
}elseif(null==repassword||repassword.length()<6 ||repassword.length()>10){
this.addActionError("password is invalid!");
}elseif(!password.equals(repassword)){
this.addActionError("tow password is not be same!");
}
if(age<=0 ||age>150){
System.out.println("ERROR");
this.addActionError("age is invalid!");
}
if(null!=birthday&&null!=graduation){
Calendar c1=Calendar.getInstance();
c1.setTime(birthday);
Calendar c2=Calendar.getInstance();
c2.setTime(graduation);
if(!c1.before(c2)){
this.addActionError("birthday shoud before graduation!");
}
}
再将运行界面时,我们发现数据校验明明是错误的却不会显示错误信息;这是因为Struts2标签默认只会显示Field级别的错误信息。要想显示Action级别的信息,需要在表单一加上一句;
<s:actionerror cssStyle="color:red;"/>
OK,这样信息显示出来,但还是有问题的,我们发现Struts2默认的表单布局,错误信息部会显示在控件的上方,而且种级别的信息显示有重复的,这需要我们做两件事情,来避免!
1.需要重新考虑validate()校验方法的代码,比如:前类型转化失败的情况下,一些校验就不用做了;即便这样有时还会是有重复的,另一种办法就是改变表单的主题,Struts2为每个表单显示都定义了一个主题,默认是HTML主题,其它的还有Ajax和Simple ,我们可以把它改成Simple即可以自己定义布局的主题,是这样,一旦改成了theme=”simple”它的错误信息就不会显示了。这也是我们使用这个主题的原因。
这些操作已经在上面jsp页面中做了!
在真正的开发中,需要根据情况采用修改主题,或重构验证方法,来正确显示错误信息。
多方法情况下输入校验
OK,上面讲的都是针对Action中execute()方法之前的验证,我们知道struts2中也提供了一个Action中多个方法,处理多种请求的机制。可能通过,struts.xml配置action中,加一个method属性来实现!如:
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEstrutsPUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constantname="struts.custom.i18n.resources"value="message"/>
<packagename="struts2"extends="struts-default">
<actionname="register1"class="com.snt.struts2.action.RegisterAction"method="register1">
<resultname="success">/success.jsp</result>
<resultname="input">/register.jsp</result>
</action>
<actionname="register2"
class="com.snt.struts2.action.RegisterAction">
<resultname="success">/success.jsp</result>
<resultname="input">/register2.jsp</result>
</action>
</package>
</struts>
这样配置是可以的,使用register1的请求会调用Action中的register()方法;
使用regiser2的请求会调用Acrtion中的execute()方法。
但这时输入校验如何处理呢?Struts2是这样处理的:
对于execute()方法,它会执行validate()方法进行输入校验,对于register()它会调用validateRegiser()方法进行输入校验,但是对于register()的情况比较特别,它调用validateRegister()方法后,它还会调用validate()方法。也是就说validate()方法总会被调用的!对于这种情况呢,当然是对我们输入校验会产生干扰的!~
如何处理这样的问题呢?提供以下解决方案:
1.空实现valiate()方法,但是这样有问题,如何校验execute()方法呢?可以选择不用execute()方法
2.不提供validate()方法,也就是空实现,但要提供一个validateExecute()方法来校验execute()方法!
转载来自:
http://blog.csdn.net/lilp_ndsc/article/details/4054251
相关推荐
### Struts2输入校验深度解析 #### 一、手动输入完成校验 在Struts2框架中,输入校验是确保数据完整性和安全性的重要环节。对于手动输入完成校验,Struts2提供了灵活的机制。 1. **普通处理方式**:在Action类中...
Struts 2 输入校验
本篇文章将深入探讨Struts2中的输入校验机制。 一、Struts2 输入校验概述 Struts2提供了多种进行输入校验的方式,包括Action级别校验、Validator框架校验、拦截器校验以及使用JSR303/JSR349 Bean Validation标准。...
本文将深入探讨Struts2中的输入校验机制,以及如何对指定方法进行输入校验。 在Struts2中,输入校验通常分为两种方式:客户端校验和服务器端校验。客户端校验主要通过JavaScript在用户端进行,可以提供即时反馈,但...
本文将深入探讨Struts2中的输入校验机制,帮助开发者更好地理解和应用。 一、Struts2输入校验概述 在Struts2中,输入校验主要用于验证用户通过表单提交的数据,防止无效或恶意数据进入系统。Struts2提供了多种方式...
在Struts2中,输入校验是确保数据安全、准确和有效的重要环节。本篇文章将深入探讨Struts2的输入校验机制及其相关知识点。 **输入校验的重要性** 输入校验是Web应用开发中的关键步骤,它可以防止恶意用户提交无效或...
在Struts2中,输入校验是确保数据安全性和应用稳定性的重要环节。它帮助开发者防止非法或无效的数据进入系统,从而减少潜在的错误和安全漏洞。 **Struts2输入校验机制** 1. **内置验证框架**: Struts2提供了内置的...
要求使用Struts2的内建校验器校验“书名”、“作者”、“出版日期”、“价格”和“库存数量”字段;要求手动编写代码校验“书号”的有效性;要求手动编写代码校验“出版社”字段中是否包含了“出版社”三个字。
Struts2是一个流行的Java web开发框架,它提供了一套强大的输入校验机制,确保用户提交的数据符合业务逻辑的要求。在本文中,我们将深入探讨Struts2的输入校验功能,包括手动输入校验和基于验证框架的输入校验。 ##...
在Struts2中,输入校验是确保数据完整性和安全性的重要环节。输入校验可以防止恶意用户提交无效或有害的数据,并确保应用程序的稳定运行。以下是关于Struts2输入校验的详细知识: 1. **客户端校验**: 客户端校验...
struts2的输入校验有两种方式: 一.重写validate()方式 二.采用配置文件的方式 先我们就以一个简单的登录的例子来讲解这个吧. 重点讲解下,第二个采用配置文件的方式: 1.添加一个xml的校验文件,保存在...
Struts2作为一款流行的Java Web框架,其在处理用户输入数据和实现多语言支持方面具有强大的功能。在“Struts2数据校验与国际化”这一主题中,我们将深入探讨Struts2如何通过不同的验证机制确保数据的有效性,以及...
在Struts2中,校验器(Validator)是处理用户输入验证的核心组件,确保提交到服务器的数据符合预设的业务规则。这篇博客文章可能是关于如何使用Struts2的内置校验机制以及自定义校验规则的探讨。 Struts2的校验框架...
在Struts2框架中,输入校验是一个关键环节,它确保了用户提交的数据符合应用的要求,从而避免了无效数据导致的错误或安全问题。本讲将深入探讨Struts2的输入校验机制。 1. **Struts2输入校验概述** - 输入校验是...
在Struts2中,输入校验是一个至关重要的部分,它确保了用户从客户端提交的数据符合预设的业务规则,从而避免了无效或不合法数据进入系统。本篇文章将详细介绍如何在Struts2中进行输入校验,包括两种主要实现方式:...