7.9 errors和messages标签
<html:errors>标签与<html:messages>标签都是用来输出request或session范围内的消息的。它们之间有着相同的地方,也有不同的地方,本节将向大家详细介绍这两个标签的使用方法。
7.9.1 <html:errors>标签
该标签的使用方法很简单,直接在要输出错误信息的位置输入以下代码。
<html:errors/>
它表示输出request或session范围内的以“org.apache.struts.Globals.ERROR_KEY”为关键字存储的ActionMessages对象中的所有消息。
可通过以下属性的设置来输出指定的消息。
name属性:指定request或session范围内的关键字,该关键字指定了一个ActionMessages对象。若忽略该属性,则默认的关键字为“org.apache.struts.Globals. ERROR_KEY”。
property属性:用于指定由name属性指定的关键字指定的ActionMessages对象中的某个消息属性,该消息属性指定了某个ActionMessage对象。若忽略该属性,则<html:errors/>标签会输出指定ActionMessages中的所有消息。
bundle属性:指定消息资源文件。若忽略该属性则从默认的消息资源文件ApplicationResources.properties中获取输出的消息内容。
<html:errors/>标签通过property属性可以输出与表单元素相关的消息。该属性要与ActionMessages对象的add(String PropertyName,ActionMessage message)方法中的PropertyName参数匹配。当PropertyName参数值为“ActionMessages.GLOBAL_MESSAGE”时,表示该值指定的是一个全局消息。
每调用一次add()方法,当PropertyName参数值相同时,会将消息累加在一起并依次将它们输出。
下面通过一个简单的用户注册实例,向大家讲解如何通过<html:errors>标签显示全局和与表单元素关联的消息。实例运行效果如图7.17与图7.18所示。

图7.17 输出与表单元素关联的消息 图7.18 输出全局消息
实例位置:mr\07\sl\10
实例程序创建过程如下。
(1)先来设置一个临时的中文消息资源文件:message_temp.properties。内容如下。
errors.prefix=<font color="red">
errors.suffix=</font>
reg.name.error=<li>输入的用户名必须是英文!</li>
reg.pwd.error=<li>密码长度必须为8位!</li>
reg.qq.error=<li>输入的QQ号码必须为数字!</li>
reg.success=<li>注册成功!</li>
然后在“命令提示符”工具下通过native2ascii命令将该文件进行编码转换,并另存为ApplicationResources.properties文件。
native2ascii –encoding gb2312 message_temp.properties ApplicationResources.properties
转码后的ApplicationResources.properties文件内容如下。
errors.prefix=<font color="red">
errors.suffix=</font>
reg.name.error=<li>\u8f93\u5165\u7684\u7528\u6237\u540d\u5fc5\u987b\u662f\u82f1\u6587!</li>
reg.pwd.error=<li>\u5bc6\u7801\u957f\u5ea6\u5fc5\u987b\u4e3a8\u4f4d!</li>
reg.qq.error=<li>\u8f93\u5165\u7684QQ\u53f7\u7801\u5fc5\u987b\u4e3a\u6570\u5b57!</li>
reg.success=<li>\u6ce8\u518c\u6210\u529f!</li>
上述代码中errors.prefix关键字表示在输出每条消息(每通过一个add()方法增加的消息)之前输出的内容,errors.suffix关键字表示在输出每条消息之后输出的内容。如当前要输出“reg.name.error”关键字对应的内容时,程序会先输出<font color="red">,然后再输出“reg.name. error”对应的内容,最后输出</font>。类似的关键字还有errors.header表示一个<html:errors>标签在输出所有消息(通过add()方法增加的,但PropertyName参数值相同的所有消息)之前要输出的内容;errors.footer表示一个<html:errors>标签在输出所有消息之后要输出的内容。
另一种方法可通过<html:errors>标签的footer、header、prefix和suffix属性指定消息资源文件中的关键字,分别在相应的位置输出该关键字对应的内容。
说明:在Struts 1.1版本中<html:errors>标签不具备footer、header、prefix和suffix属性。
(2)配置struts-config.xml文件,关键代码如下。
例程7-10:光盘\mr\07\sl\10\WEB-INF\struts-config.xml
<form-beans>
<form-bean name="regform" type="com.message.actionform.RegForm"/>
</form-beans>
<action-mappings>
<action
path="/doreg"
type="com.message.action.RegAction"
name="regform">
<forward name="success" path="/index.jsp"/>
<forward name="false" path="/index.jsp"/>
</action>
</action-mappings>
<controller processorClass="com.message.tools.FormToChinese"/>
<message-resources parameter="com.message.ApplicationResources" />
<controller processorClass="com.message.tools.FormToChinese"/>元素指定了解决Struts中汉字乱码问题的FormToChinese类。读者可参看本书中的20.6.6章节的相关介绍。
(3)创建用户注册首页面index.jsp,在该页中要求用户输入用户名、密码及QQ号码。其关键代码如下。
例程7-10:光盘\mr\07\sl\10\index.jsp
<html:form action="doreg">
<table>
<tr bgcolor="lightgrey"><td align="center" colspan="2">填写注册信息</td></tr>
<tr><td align="center" colspan="2">
<html:errors property="<%=org.apache.struts.action.ActionMessages.GLOBAL_MESSAGE%>"/>
</td></tr>
<tr><td align="right">用户名:</td>
<td><html:text property="username"/></td></tr>
<tr><td colspan="2"><html:errors property="nameerror"/></td></tr> //显示用户名的相关信息
<tr><td align="right">密 码:</td>
<td><html:password property="userpwd" redisplay="false"/></td></tr>
<tr><td colspan="2"><html:errors property="pwderror"/></td></tr> //显示用户密码的相关信息
<tr><td align="right">QQ号码:</td>
<td><html:text property="userqq"/></td></tr>
<tr><td colspan="2"><html:errors property="qqerror"/></td></tr> //显示QQ号码的相关信息
<tr><td colspan="2"><html:submit value="注册"/> <html:reset value="重置"/></td></tr>
</table>
</html:form>
(4)通过在struts-config.xml文件中的配置,index.jsp页中的表单与RegForm Bean关联。RegForm的关键代码如下。
例程7-10:光盘\mr\07\sl\10\src\com\message\actionform\RegForm.java
package com.message.actionform;
import org.apache.struts.action.ActionForm;
public class RegForm extends ActionForm {
private String username; //用户名
private String userpwd; //用户密码
private String userqq; //用户QQ号码
public void setUsername(String username){ this.username=username; }
public String getUsername(){ return this.username; }
……//省略了其他属性的setXXX()与getXXX()方法
}
(5)创建RegAction类,该类处理用户单击【注册】按钮提交的请求。类中只对用户输入的表单数据进行验证并保存验证信息。具体代码如下。
例程7-10:光盘\mr\07\sl\10\src\com\message\action\RegAction.java
package com.message.action;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import com.message.actionform.RegForm;
public class RegAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response){
ActionMessages errors=new ActionMessages();
RegForm regform=(RegForm)form;
String username=regform.getUsername(); //获取表单中的用户名
String userpwd=regform.getUserpwd(); //获取表单中的用户密码
String userqq=regform.getUserqq(); //获取表单中的QQ号码
boolean mark=true;
int ascii=0;
int i=0;
while(i<username.length()){
ascii=username.substring(i,i+1).hashCode();
if(!((ascii>=97&&ascii<=122)||(ascii>=65&&ascii<=90))){
mark=false;
errors.add("nameerror",new ActionMessage("reg.name.error"));
i=username.length();
}
i++;
}
if(userpwd.length()>8||userpwd.length()<8){
mark=false;
errors.add("pwderror",new ActionMessage("reg.pwd.error"));
}
try{
Integer.parseInt(userqq);
}
catch(Exception e){
mark=false;
errors.add("qqerror",new ActionMessage("reg.qq.error"));
}
if(!mark){
saveErrors(request,errors); //将ActionMessages对象保存到request范围内
return mapping.findForward("false");
}
errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage("reg.success"));
saveErrors(request,errors);
return mapping.findForward("success");
}
}
上述代码中saveErrors(request,errors)方法将ActionMessages对象保存到了request范围内,并以“org.apache.struts.Globals.ERROR_KEY”关键字存储。Action基类中saveErrors()方法的关键代码如下。
protected void saveErrors(HttpServletRequest request, ActionMessages errors){
request.setAttribute(org.apache.struts.Globals.ERROR_KEY,errors);
}
另外,还可以通过saveMessages(request,errors)方法将ActionMessages对象保存到request范围内,但此时在request范围中以“org.apache.struts.Globals.MESSAGE_KEY”关键字存储。Action基类中saveMessages()方法的关键代码如下。
protected void saveMessages(HttpServletRequest request, ActionMessages errors) {
request.setAttribute(org.apache.struts.Globals.MESSAGE_KEY,errors);
}
所以如果使用了saveMessages()方法存储消息,在使用<html:errors>标签输出消息时,要通过name属性来指定在request或session范围内以“org.apache.struts. Globals.MESSAGE_KEY”关键字来查找ActionMessages对象。否则此时忽略name属性,Struts会使用默认的关键字“org.apache.struts.Globals. ERROR_KEY”进行查找,将找不到存储的消息。
7.9.2 <html:messages>标签
该标签与<html:errors>标签相似,同样用来输出消息。它们之间有着相同的地方,也有不同的地方。
1.与<html:errors>标签的相同点
消息来源:<html:messages>标签要输出的消息来源与<html:errors>标签相同,同样可以通过saveErrors()或saveMessages()方法将ActionMessages对象存入request或session范围内。例如:
ActionMessage messages=new ActionMessages();
errors.add("username",new ActionMessage("com.logon.name.error"));
saveErrors(request,messages);
属性:<html:messages>标签的name属性、property属性、bundle属性以及footer属性、header属性分别与<html:errors/>标签中对应的属性用法相同。
2.与<html:errors>标签的不同点
属性
message属性,<html:errors>标签中不存在的属性。当忽略该属性或将其设为“false”时,则根据由name属性指定的关键字在request或session范围中查找该关键字存储的ActionMessages对象,若此时没有设置name属性,则查找以默认关键字“org.apache.struts.Globals.ERROR_KEY”存储的ActionMessages对象;若将message属性设为“true”,表示以“org.apache.struts.Globals.MESSAGE_KEY”关键字进行查找,并且此时设置的name属性无效。
id属性,该属性是<html:messages>标签必须存在的属性,而<html:errors>标签中不存在该属性。它用来指定一个JSP页面变量,该变量代表了每次从ActionMessages对象中遍历出的一个ActionMessage对象。
使用方法:单独使用<html:messages>标签是不能输出消息的。因为该标签完成的操作只是对ActionMessages对象进行遍历,并将每次遍历出的ActionMessage对象存储在id属性所指定的JSP页面变量中。所以通常情况下嵌套<bean:write>标签一起使用,<bean:write>标签中的name属性要与<html:messages>标签的id属性相匹配。
说明:<bean:write>标签用来输出由name属性指定的对象值。详细的介绍请参看本书中的第8章。
使用<html:messages>标签输出消息的代码如下。
<html:messages id="messageid" message="true">
<bean:write name="messageid"/>
</html:messages>






