当前位置:编程学习 > JAVA >>

深度剖析:Java POJO Bean对象与Web Form表单的自动装配

 时下很多 Web 框架 都实现了 Form 表单域与 Java 对象属性的自动装配功能,该功能确实非常有用,试想如果没这功能则势必到处冲积着 request.getParameter() 系列方法与类型转换方法的调用。重复代码量大,容易出错,同时又不美观,影响市容。

  现在的问题是,这些框架通过什么方法实现自动装配的?如果不用这些框架我们自己如何去实现呢?尤其对于那些纯 JSP/Servlet 应用,要是拥有自动装配功能该多好啊!本座深知各位之期盼,决定把自动装配的原理和实现方法娓娓道来。

  实现原理其实比较简单,主要由以下3个步骤构成:


通过 request.getParameterMap() 获取被提交的 Form 的所有表单域的名称-值映射,其中名称和值均为字符串类型。
利用 java.beans.PropertyDescriptor 对象获取 Java Bean 的所有属性的名称及其类型。
把表单域的名称与 Bean 的属性的名称逐个进行匹配,当找到相匹配的属性时就调用 Bean 的 setter 方法把表单域的值设置给该 Bean 属性。当然,因为表单域的值总是字符串类型,很可能与 Bean 属性的类型不一致,所以在设置 Bean 属性前要进行必要的类型转换。
  上面所表述的3点原理不知大家是否完全理解,没关系,下面我们通过一个具体的表单提交的例子来看一看实际的效果,首先看看待提交的表单页面及其代码:

 \


 

<form action="checkbean.action" method="post">
    First Name: <input type="text" name="firstName" value="丑">
    <br>
    Last Name: <input type="text" name="lastName" value="怪兽">
    <br>
    Birthday: <input type="text" name="birthday" value="1978-11-03">
    <br>
    Gender: 男 <input type="radio"" name="gender" value="false">
         女 <input type="radio"" name="gender" value="true" checked="checked">
    <br>
    Working age: <select name="working-Age">
        <option value="-1">-请选择-</option>
        <option value="3">三年</option>
        <option value="5" selected="selected">五年</option>
        <option value="10">十年</option>
        <option value="20">二十年</option>
    </select>
    <br>
    Interest: 游泳 <input type="checkbox" name="its" value="1" checked="checked">
         打球 <input type="checkbox" name="its" value="2" checked="checked">
         下棋 <input type="checkbox" name="its" value="3">
         打麻将 <input type="checkbox" name="its" value="4">
         看书 <input type="checkbox" name="its" value="5" checked="checked">
    <br>
<br>
<input type="submit" value="确 定">  <input type="reset" value="重 置">
</form>
 
  从上图可以看出,总共有6个表单域,其名称-值分别是:{"firstName" - "丑","lastName" - "怪兽","birthday" - "1978-11-03","gender" - "女","working-Age" - "5","its" - "1,2,5"},该表单需要提交给 checkbean.action 进行处理(请注意:不要一看到 .aciton 就以为是 struts2,骑白马的不一定都是唐僧!),下面来看看 CheckBean Action 的处理代码和 Bean 的定义:
 
import java.util.HashMap;
import java.util.Map;

import vo.Persion;

import com.bruce.mvc.ActionSupport;

public class CheckBean extends ActionSupport
{
    @Override
    public String execute()
    {
        // 如果表单元素的名称和 Form Bean 属性名不一致则使用 keyMap 进行映射
        // key: 表单元素名称, value: Form Bean 属性名
        Map<String, String> keyMap = new HashMap<String, String>();
        keyMap.put("working-Age", "workingAge");
        keyMap.put("its", "interest");
       
        /* 自动装配方法一 */
        // 使用表单元素创建 Form Bean
        // 如果表单元素的名称和 Form Bean 属性名完全一致则不需使用 keyMap 进行映射
        Persion p = createFormBean(Persion.class, keyMap);
       
        /* 自动装配方法二 */
        // 先创建 Form Bean 对象, 然后再填充它的属性
        Persion p2 = new Persion();
        fillFormBeanProperties(p2, keyMap);
       
        // 可以获取 Form Bean 的所有属性值
        //Map<String, Object> result = BeanHelper.getProperties(p);
       
        // 把 p 设置为 request 属性,并最终在结果页面展示
        setRequestAttribute("persion", p);
       
        return SUCCESS;
    }
}
import java.util.Date;
import java.util.List;

public class Persion
{
    private String firstName;
    private String lastName;
    private Date birthday;
    private boolean gender;
    private int workingAge;
    private int[] interest;
    private List<String> photos;

    // getter 和 setter 方法
    // (略)。。。。。。
}

   从 CheckBean 的代码可以看出,它是通过 createFormBean() 或 fillFormBeanProperties() 方法来自动装配 Persion 的,它们之间的区别是:前者会直接创建新的 Persion 对象,而后者填充原有 Persion 对象的属性。请注意,如果表单域的名称与 Persion 对应的属性名不一致则用 keyMap 进行映射,如表单域 "working-Age" 是对应 Persion 的 workingAge 属性的,但它们的名称不一致,所以要进行映射。另外,Persion 有一个 photos 属性,而我们的表单域却没有,自动装配时会忽略该属性。最后看一下输出的结果页面及其代码:

 \



<body>
  <br>
  <div align="right">
      <a href="index.action"><u:msg key="jsp-

补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,