根据实验四的图书管理系统,扩展图书新增功能,要求对新增页面表单中的每个文件输入框进行输入校验
书名 String 必须输入;长度在4-80之间
作者 String 必须输入;长度在4-40之间
书号(13位ISBN) String 必须输入;长度必须是13位;根据参考资料中的ISBN校验码的计算方法对书号的有效性进行校验。
出版社 String 文本中必须包含“出版社”一词
出版日期 Date 日期范围为1900年1月1日到当前日期
价格 Double 最小值为0.0
库存数量 Integer 最小值为0
验证方法
- 客户端验证
数据提交前在客户端验证
可使用JavaScript或者JQuery实现
特点:减少客户等待时间,减小服务器压力 - 服务端验证
在数据提交后服务器端验证
特点:防止“绕过”
客户端验证提交非法数据
可以在服务器端处理数据前确保数据的合法性 - 验证方式
- 使用ActionSupport编码实现验证
- 使用验证框架实现验证
ActionSupport编码实现验证(重)
- 在
Action类的方法中直接验证
- 重写
Validate()
- 使用
validateXxx()
添加错误信息
- addFieldError(String fieldName,String errorMessage)
添加字段的错误信息
- addActionError(String anErrorMessage)
添加与Action所处理业务相关的错误信息
addFieldError的使用方法
action.java
xml
表单前端
注意 有时会报错 No result defined for action…and result input都和这个有关系
<result name="input">BookListAdd.jsp</result>
其中 Struts2应用在运行过程中若发现addFieldError()中有信息或者类型转换失败或着输入校验失败等情况。详细查看 https://blog.csdn.net/lv_hang515888/article/details/73456789
那么它会自动跳转到name为input的,然后转到INPUT所对应的页面
Action中的属性值为空的时候,Struts2的默认拦截器会报错,但是又找不到input的Result,不能够把错误返回,所以报这种错误。
这里是因为使用了addFieldError()。
报错原因:
1、validate方法没有通过(表单验证看看有没有重名,导致js文件加载过慢);
2、页面元素中有重命名时,但后台action类的对应的接收此同名参数的是变量而没有写成数组
3、配置文件中result 返回.jsp出现错误(多了空格、或者没有界面)
4、对应Action中没有返回值,或者返回值数据类型转换出错
5、工程里有一个BaseAction的类,并且BaseAction使用了验证框架,有一个BaseAction-validation.xml的文件。
而PoiterAction正好是BaseAction的一个子类,也继承了父类的验证框架,因此按照验证框架的运行流程来看这个问题就很明显了。由于验证框架在调用子类的时候首先加载父类的验证规则,然后等待输入,系统会找到input元素制定的JSP文件的输入信息,但是PoiterAction并没有input项,所以系统抛出No result defined for action…and result input。
6、表单中有文件上传功能,提交form表单时,需要加enctype = “multipart/form-data”
比如<form action="xxxx.action" method="post" name="xxx" id="xxx"enctype = "multipart/form-data">
果不加enctype = "multipart/form-data"这个,在不同浏览器版本中,比如谷歌 52版本,不加也不会报错,但在58版本就报错了。所以避免浏览器兼容问题,最好加上!
业务方法中较验
前端页面
<body>
<!-- 判断字段是否有错误信息-->
<s:if test="hasFieldErrors()">
<h1 align="center">输出错误字段信息</h1>
<div align="center" style="color:blue;">
使用s:fielderror输出一个指定的错误信息
<s:fielderror name="user.username" />
使用s:fielderror输出全部的错误信息
<s:fielderror />
</div>
</s:if>
<!-- 判断action是否有错误 -->
<s:if test="hasActionErrors()">
<h1 align="center">输出错误Action信息</h1>
<div align="center" style="color:gray;">
使用s:actionerror输出action相关的错误信息
<s:actionerror/>
</div>
</s:if>
<h1>使用execute业务方法直接较验</h1>
<s:form action="register.action" method="post" >
<s:textfield label="用户名" name="user.username"/>
<s:password label="密码" name="user.password"/>
<s:textfield label="年龄" name="user.age" />
<s:textfield label="邮箱" name="user.email"/>
<s:submit value="提交" /><s:reset value="重置" /><br/>
</s:form>
<s:debug/>
</body>
action.java
public class UserAction extends ActionSupport {
private User user;
@Override
public String execute() throws Exception {
if(null==user.getUsername() || "".equals(user.getUsername())){
this.addFieldError("user.username", "用户名不能为空!");
}
if(null==user.getPassword() || "".equals(user.getPassword())){
this.addFieldError("user.password", "密码不能为空!");
}
String ageStr="^\\d{1,3}$";
Pattern ageReg=Pattern.compile(ageStr);
Matcher ageMatcher=ageReg.matcher(user.getAge()+"");
if(!ageMatcher.matches()){
this.addFieldError("user.age", "年龄只能是数字,并只能为1-200之间!");
}
if(null==user.getAge()){
this.addFieldError("user.age", "年龄不能为空!");
}
String emaString="^\\w+@\\w+(.\\w{2,3}){1,2}$";
Pattern emailReg=Pattern.compile(emaString);
Matcher emailMatcher=emailReg.matcher(user.getEmail());
if(!emailMatcher.matches()){
this.addFieldError("user.email", "邮箱格式不正确");
}
if(this.hasErrors()){
this.addActionError("输入的注册信息有误");
return INPUT;
}
return SUCCESS;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
这里主要介绍了三种方式显示Validation的错误信息显示方式,Validation的原理是由内置的验证拦截器在配置校验规则后,一旦不符合规则,拦截之后返回一个错误集合,如果直接使用<struts:fielderror/>
则遍历错误集合,打印所有信息,如果指定了变量名,<struts:fielderror><struts:param></struts:param></struts:fielderror>
则只打印指定字段的校验错误信息。同时,如果使用了Struts标签构造表单,那么错误信息会默认出现在输入框上方。参考: http://blog.csdn.net/drohe/article/details/72972320
在validate中验证
不管请求的action是哪个方法,validate方法都会被调用
在validateXXX()中验证
通过validateXxx()方法实现, validateXxx()只会校验action中方法名为Xxx的方法。其中Xxx的第一个字母要大写。当某个数据校验失败时,我们应该调用addFieldError()方法往系统的fieldErrors添加校验失败信息(为了使用addFieldError()方法,action可以继承ActionSupport ),如果系统的fieldErrors包含失败信息,struts2会将请求转发到名为input的result。在input视图中可以通过<s:fielderror/>
显示失败信息。
public String add() throws Exception{ return "success";}
public void validateAdd(){
if(username==null && "".equals(username.trim())) this.addFieldError("username", "用户名不能为空");
}
public static void invokePrefixMethod(com.opensymphony.xwork2.ActionInvocation actionInvocation,
java.lang.String[] prefixes)
throws java.lang.reflect.InvocationTargetException, java.lang.
IllegalAccessException { /* compiled code */ }
输入校验的流程
1、类型转换器对请求参数执行类型转换,并把转换后的值赋给action中的属性。
2、如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext,conversionError拦截器将异常信息添加到fieldErrors里。不管类型转换是否出现异常,都会进入第3步。
3、系统通过反射技术先调用action中的validateXxx()方法,Xxx为方法名。
4、再调用action中的validate()方法。
5、经过上面4步,如果系统中的fieldErrors存在错误信息(即存放错误信息的集合的size大于0),系统自动将请求转发至名称为input的视图。如果系统中的fieldErrors没有任何错误信息,系统将执行action中的处理方法。