天天看點

04JavaServlet-19. BeanUtils詳解

BeanUtils

BeanUtils是Apache commens元件裡面的成員,由Apache提供的一套開源api,用于簡化對javaBean的操作,能夠對基本類型自動轉換。

JavaBean

BeanUtils元件是用于簡化javaBean的操作,那麼什麼是javaBean呢?簡單來說,javaBean實質就是java類,隻不過是遵循了某種規範的java類。

javaBean的特點:

  • 必須具有一個無參的構造方法
  • 屬性必須私有化
  • 私有化的屬性必須通過public類型的方法來暴露,也就是說要出現setXXX()、getXXX()或者isXXX()的方法

下載下傳BeanUtils

​​​ http://commons.apache.org/proper/commons-beanutils/download_beanutils.cgi,下載下傳好元件,再到項目裡面引入jar檔案。​​

導入核心包

  • commons-beanutils-1.9.3.jar
  • commons-logging-1.2.jar

注意:當缺少日志jar包,會出現如下的報錯情況。

java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory

logging元件的下載下傳位址:http://commons.apache.org/proper/commons-logging/download_logging.cgi

javaBean執行個體

public class Student {
    private String name;
    private String id;
    private int age;
    private String sex;
    private Date d;
    public Student() {
        super();
    }
    public Date getD() {
        return d;
    }
    public void setD(Date d) {
        this.d = d;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", id=" + id + ", age=" + age
                + ", sex=" + sex + ", d=" + d + "]";
    }
}      

BeanUtils用法

  • 對象的拷貝,BeanUtils.copyProperties(Object dest,Object orig)
  • 對象屬性的拷貝,BeanUtils.copyProperties(Object bean,String name,Object value)或者BeanUtils.setProperty(Object bean,String name,Object value)
  • map資料封裝到Javabean,populate(Object bean, Map<String,? extends Object> properties)

執行個體

對象的拷貝

@Test
  public void test() throws Exception {
      //建立對象
      Student s=new Student();
      /**
       * 元件對JavaBean的操作
       * bean:javaBean對象
       * name:對象的屬性名稱
       * value:對象的屬性值
       */
      //1.實作對象的屬性拷貝, 對于基本資料類型,會自動進行類型轉換
      BeanUtils.copyProperty(s, "id","2018100712");
       
      //2.實作對象之間的拷貝:Object dest<---Object orig
      Student s2=new Student();
      BeanUtils.copyProperties(s2, s);
      System.out.println(s2);
}      

對象屬性的拷貝

@Test
    public void test() throws Exception {
        //建立對象
        Student s=new Student();
        /*一般的操作
        s.setId("1221212");
        s.setName("老王");
        System.out.println(s);
        */
        //1.實作對象的屬性拷貝, 對于基本資料類型,會自動進行類型轉換
        BeanUtils.copyProperty(s, "id","2018100712");
    System.out.println(s)
}      

map資料封裝到javaBean

注意:要map中的資料封裝到JavaBean中去,需要map中的key與JavaBean裡面的私有化的屬性要相比對

@Test
    public void test() throws Exception {
        //建立對象
        Student s2=new Student();
        //1.map的資料拷貝到對象中去
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("id","12233");
        map.put("name","老王");
        map.put("sex","男");
        BeanUtils.populate(s2, map);
        System.out.println(s2);
    }      

類型轉換器

當javaBean中出現非基本類型資料的私有化屬性,并且需要對該資料進行封裝時,就要去注冊該資料類型的類型轉換器了,不如就會出現錯誤,比如該Student對象中的日期類型。

日期類型轉換出錯:org.apache.commons.beanutils.converters.DateConverter toDate 警告: DateConverter does not support default String to ‘Date’ conversion,可以看出工具類converters在轉換的時候出現了錯誤,為此我們可以去檢視該類,以便我們接下來去實作類型轉換。

converter

在解壓出來的BeanUtils檔案下的apidoc目錄中的index.html裡面可以找到該類的說明,會發現它是一個接口,有很多的實作類,我們可以使用裡面的實作類來做日期類型的轉換或者說我們可以自己去注冊個類型轉換器。

04JavaServlet-19. BeanUtils詳解

自定義類型轉換器

去複寫ConvertUtils裡面的register(Converter converter, Class<?> clazz)方法

@Test
    public void test2() throws Exception {
        //假設網頁表單送出過來的資料
        String name="老王";
        String id="121212";
        String date="2018-10-11";
        Student s=new Student();
        //1.自定義:注冊日期類型轉換器去複寫ConvertUtils裡面的register(Converter converter, Class<?> clazz)方法
        ConvertUtils.register(new Converter() {
            //修改第三方jar引入方法的參數時候,可以關聯源碼,ctrl選擇該類,點進去,選擇Attach source--->external file
            @Override
            public Object convert(Class type, Object value) {
                //判斷
                if (value ==null ||"".equals(value.toString().trim())){
                    return null;    
                }
                if (type !=Date.class){
                    return null;
                }
                try {
                    //字元串轉換為日期
                    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
                    return sdf.parse(value.toString());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        },Date.class);
        //把表單的資料封裝到對象中去
        BeanUtils.copyProperty(s, "name",name);
        BeanUtils.copyProperty(s, "id",id);
        BeanUtils.copyProperty(s, "d",date);
        System.out.println(s);
    }      

使用工具類提供的類型轉換器

@Test
    public void test3() throws Exception {
        //利用元件提供的日期類型轉換器,提供一個實作類
        //假設表單的資料
        String name="老王";
        String id="121212";
        //當日期字元串出現空字元串或者出現空格的情況,會報錯org.apache.commons.beanutils.ConversionException
        String date="2018-09-12";
        Student s=new Student();
        ConvertUtils.register(new DateLocaleConverter(), Date.class);
        //把表單的資料封裝到對象中去
        BeanUtils.copyProperty(s, "name",name);
        BeanUtils.copyProperty(s, "id",id);
        BeanUtils.copyProperty(s, "d",date);
        System.out.println(s);
    }      

注意:當日期字元串是空字元串或者存在空格的時候,會報錯!

BeanUtils在servlet的使用

擷取表單送出的資料并封裝到javabean中去,request.getParameterMap()擷取所有的參數并存儲到Map中去,并利用BeanUtils裡面的populate(Object bean, Map<String,? extends Object> properties),封裝到對象中去,簡化了很多的操作!

1.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
  <title>注冊</title>
 </head>
 <body>
    <form action="registe.do" method="post">
        使用者名稱:<input type="text" name="name"><br>
        密&nbsp;&nbsp;碼:<input type="password" name="password"><br>
        聯系方式:<input type="text" name="phone"><br>
        <input type="submit" value="送出">
    </form>
 </body>
</html>      
package cn.tan.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import cn.tan.entry.Student;
  
public class GetDataServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //擷取所有參數
        Map<String, String[]> map = request.getParameterMap();
        Student s=new Student();
        try {
            BeanUtils.populate(s, map);
            //測試,輸出封裝的結果
            System.out.println(s);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
  
}