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。 
相關文章
相關標籤/搜索