一、输入校验与类型转化的关系
遇到类型转换错误的时候(也就是说不能进行类型转换),struts2框架自动生成一条错误信息,并且将该错误信息放到addFieldError里面
类型转换与输入校验的流程
1. 首先Struts2对客户端传来的数据进行类型转换
2. 类型转换完毕后再进行输入校验
3. 如果类型转换和输入校验都没有错误发生,那么进入execute方法(调用商业逻辑)
注意:如果类型转换不成功,也同样要进行输入校验,这样一来某些字段会出来两个错误提示信息。(所以对某些字段可以不做输入校验,光做类型转换,如上例中
可注销掉
// if(null == birthday)
// {
// this.addFieldError("birthday","birthday invalid");
// }
// if(null == graduation)
// {
// this.addFieldError("graduation","graduation invalid");
// }
对于有些struts框架提供的错误信息,还是去不掉,可以使用struts的简单主题,即可以把某个字段设置为simple"的模式、也可以把表单也改成simple模式,见下文把表单也改成simple模式。
二、转换错误提示信息个性化
struts默认的转化信息报错往往不友好
我们可以通过以下方式处理
方式一,“转化信息报错”全局的属性文件
1、在strut.xml加上以下内容
<constant name="struts.custom.i18n.resources" value="message"></constant>
2、在src文件夹下加入以下文件message.properties
内容为xwork.default.invalid.fieldvalue={0} error
{0}表方哪个字段出错了,显示时自动地会用出错的字段填充。
方式二,“转化信息报错”局部的属性文件
位置:和相应的action在同一个包中
命名:action的名字.properties
例如:RegisterAction.properties文件
该文件内容为
invalid.fieldvalue.age=age convert error
若要把这个显示为中文,可以使用jdk的工具native2ascII.exe(该工具可以转换一行汉字或一个汉字文件成ascii吗)
三、对于输入输出页面改用struts标签库
1、register2.jsp 若采用的是默认模式的话,struts会自动生成表格
<body>
<s:form action="register" >
<s:textfield name="username" label="username" ></s:textfield>
<s:password name="password" label="password" ></s:password>
<s:repassword name="repassword" label="repassword" ></s:password>
<s:textfield name="age" label="age"></s:textfield>
<s:textfield name="birthday" label="birthday"></s:textfield>
<s:textfield name="graduation" label="graduation"></s:textfield>
<s:submit value=" submit "></s:submit>
</s:form>
</body>
下面采用的是theme="simple"的模式:
<%@ taglib prefix="s" uri="/struts-tags"%>
...
<body>
<table align="center" width="40%">
<tr>
<td>
<s:fielderror cssStyle="color:red" />
</td>
</tr>
</table>
<s:form action="register" theme="simple">
<table align="center" width="40%" border="1">
<tr>
<td>
username
</td>
<td>
<s:textfield name="username" label="username" id="usernameId"></s:textfield>
</td>
</tr>
<tr>
<td>
password
</td>
<td>
<s:password name="password" label="password" id="passwordId"></s:password>
</td>
</tr>
<tr>
<td>
re-password
</td>
<td>
<s:password name="repassword" label="repassword" id="repasswordId"></s:password>
</td>
</tr>
<tr>
<td>
age
</td>
<td>
<s:textfield name="age" label="age"></s:textfield>
</td>
</tr>
<tr>
<td>
birthday
</td>
<td>
<s:textfield name="birthday" label="birthday"></s:textfield>
</td>
</tr>
<tr>
<td>
graduation
</td>
<td>
<s:textfield name="graduation" label="graduation"></s:textfield>
</td>
</tr>
<tr>
<td>
<s:submit value=" submit "></s:submit>
</td>
<td>
<s:reset value=" reset "></s:reset>
</td>
</tr>
</table>
</s:form>
</body>
四、Error级别
filed级别的fieldError和action级别ActionError
可将将原来的addfieldError修改为addActionError ,我们就开始使用ActionError级别了,例如:
if (null == username || username.length() < 6 || username.length() > 10)
{
this.addActionError("username invalid");
}
五、以上修改后,struts不会提示任何错误信息了
因为register2.jsp默认只会显示addfieldError级别的信息
六、如何显示ActionError级别的信息呢
很简单,在register2.jsp页面上加上以下信息即可了
<s:actionerror/>
注意:在第五步,即使不显示也通不过验证的,因为在整个验证中只要addfieldError和addActionError只要有一个不为空,就会验证通不过!
七、在sturts.xml配置文件中增加method属性,在RegisterAction增加相应method属性值的方法
<action name="register1" class="com.test.action.RegisterAction" method="test">
<result name="success">/success.jsp</result>
<result name="input">/register2.jsp</result>
</action>
<action name="regir2" class="com.test.action.RegisterAction" method="abc">
<result name="success">/success.jsp</result>
<result name="input">/register2.jsp</result>
</action>
@Override
public String execute() throws Exception
{
return SUCCESS;
}
public String test() throws Exception
{
return SUCCESS;
}
public String abc() throws Exception
{
System.out.println("abc method invoked");
return SUCCESS;
}
public void validateAbc()
{
System.out.println("validateAbc() invoked");
}
@Override
@SuppressWarnings("unchecked")
public void validate()
{
System.out.println("validate~~~~~~~~~~~~~~~~~~~");
if (null == username || username.length() < 6 || username.length() > 10)
{
List list = new ArrayList();
list.add(username);
this.addActionError(this.getText("username.invalid",new String[]{username}));
}
这样一来,以前在执行这个RegisterAction的时候,业务逻辑是只能放在excute()方法中的,现在也可以放在test方法中、abc()方法中了。提交register1表单时
可以用test方法。提交regi2表单时可以用类中的abc方法
那么这样一来,执行这些方法前,大家都用统一的一个很大的validate()方法来验证吗?显然这样是比较粗粒度的,不精细的
struts提出了方法相对应的validate()。如上面两个方法对应的validate()分别为:validateTest()和validateAbc()
如调用registerAction的test方法:执行过程将会如下的顺序validateTest()--》validate()--》test()
这样一来,谁都还是要去执行validate()验证,所以可以这样处理,再写一个validateExcute()对应Excute方法,然后在validate()中什么也不写,空方法。