struts表单校验失败后的整数重显问题

   通过王涛完成的项目练习,发现了struts中的表单校验失败后重显的一个问题:假设ActionForm Bean中有一个整数类型的属性,如果将其类型定义为int,这个属性的默认值是0;在表单页面中用一个文本框来输入这个属性的值, 当文本框中没有填写任何内容时,发送到WEB服务器的参数值为一空字符串""; 当ActionForm Bean中的其它属性校验失败时,回到表单页面重新显示,这时,与整数字段对应的文本框中显示的内容为0,而不是最初的那样(没有任何内容)。
  为此,我们想到了在Spring MVC中所采用的办法:将整数类型的属性定义为Integer类型,这样,该属性的默认值为null,借助<html:property>可将null显示为空字符串,但是,实际运行发现,ActionForm Bean中的其它属性校验失败回到表单页面重新显示时,与Integer类型的属性对应的文本框中显示的内容仍然为0。这说明struts在将请求参数组装进ActionForm Bean对象中时、它也会将内容为空字符串""的请求参数(文本框中不填写任何内容时即会出现这种情况)装配到ActionForm Bean中,并且将空字符串""转变成0值的Integer数据。对于这种情况,我们想到了将原本属于整数的属性设计成String类型的妥协解决办法,但觉得不是很理想,想知道各位有经验的朋友对这种情况是如何处理的?特向各位朋友请教。
下面是问题的完整描述:
假设有一个注册课程的表单,其中包含有“课程名”、“学分”等字段信息,显然“课程名”是String类型,“学分”是整数类型,与这个表单对应的ActionForm可以设计成如下形式:
public class RegisterCourseForm extends ActionForm
{
    private String name;
    public String getName()
    {        return name;
    }
    public void setName(String name) {
       this.name = name;
    }
   
    private Integer score;
    public Integer getScore()
    {
       return score;
    }
    public void setScore(Integer score)
    {
       this.score = score;
    }
    public ActionErrors validate(ActionMapping mapping,HttpServletRequest request)
    {
        if("".equals(name))
        {
            ActionErrors errors = new ActionErrors();
            errors.add("name",new ActionMessage("required.name"));
            return errors;
        }
        return null;
    }
   
}
注册课程的表单页面的主要内容如下:
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
 
<html:form action="/registerCourse">
     name : <html:text property="name"/><html:errors property="name"/><br/>
     score : <html:text property="score"/><html:errors property="score"/><br/>
     <html:submit/>
</html:form>
为了让这个用例能够运行,同时又简化整个程序的代码,我们直接使用Struts提供的ForwardAction,大家也可以使用MyEclipse自动为我们创建的没有任何业务逻辑的Action。在struts-config.xml文件中的配置片段如下:
   <form-bean name="registerCourseForm" type="cn.itcast.form.RegisterCourseForm" />
......
    <action parameter="/WEB-INF/jsp/registerCourse.jsp"
            path="/index" type="org.apache.struts.actions.ForwardAction"/>
 
    <action
      input="/WEB-INF/jsp/registerCourse.jsp"
      name="registerCourseForm"
      path="/registerCourse"
      scope="request"
      type="org.apache.struts.actions.ForwardAction"
       parameter="/WEB-INF/jsp/registerCourse.jsp"   
    />
(1)首先在浏览器地址栏中输入[url]http://localhost:8080/CourseManager/index.do[/url],请求交给第一个Action处理,浏览器中显示出registerCourse.jsp页面;
(2)在注册课程的表单页面不填写任何内容,直接提交表单,这时候表单校验失败(即RegisterCourseForm.validate方法返回ActionErrors对象),浏览器重新显示registerCourse.jsp页面。registerCourse.jsp页面除了显示出错误描述信息之外,还在表单中显示出上次输入的内容,现在遇到的问题是:我们上次提交表单时,并没有在学分(score)文本框中输入任何内容,但这次重显表单时,在学分(score)文本框中添入了一个0。
  我猜想这是因为struts在将请求参数组装进RegisterCourseForm对象中时、将空字符串""的请求参数(文本框中不填写任何内容时即会出现这种情况)转变成了0值的Integer数据。查看struts的源代码,了解到请求参数组装到FormBean中的方法调用过程如下:
ActionServlet.doGet/doPost-->ActionServlet.process-->RequestProcessor.process-->
RequestProcessor.processActionForm,RequestProcessor.processPopulate-->RequestUtils.populate-->
BeanUtils.populate-->BeanUtilsBean.setProperty(Object bean, String name, Object value)
可见,将请求参数组装成FormBean的属性时,最终调用的是BeanUtilsBean.setProperty方法,可能的原因就是BeanUtilsBean.setProperty方法在为JavaBean的整数类型的属性进行赋值时,会将空字符串""转换成0。BeanUtilsBean类位于apache的commons-beanutils包中,大家从struts安装包的lib目录中能够找到commons-beanutils.jar包及相关的依赖包。我安排王涛写了一个程序,来验证这种效果:
package com.tony;
public class TestInteger {
 public static void main(String[] args) {
  
  Student student = new Student();
  try {
   BeanUtilsBean.getInstance().setProperty(student,"name","Tony");
   BeanUtilsBean.getInstance().setProperty(student,"age","");
   System.out.print(student);
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}
package com.tony;
public class Student {
 private String name;
 private Integer age;
 public Integer getAge() {
  return age;
 }
 public void setAge(Integer age) {
  this.age = age;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String toString()
 {
  return this.name + ":" + this.age;
 }
}
程序最后打印出来的结果为Tony:0,这说明BeanUtilsBean.setProperty方法确实将空字符串""转换成了整数类型的0。 

你可能感兴趣的:(struts,表单,校验,整数,休闲)