javabean以及內省技術詳解


一、關於javabean

javabean是固定寫法的java類

書寫格式為:

1)必須有無參構造函數

2)屬性必須私有, 我們稱為字段

3)提供標准的getter和setter

例: name 字段 的getter: String getName() settter: void setName(String name)

javabean例子:

//快捷鍵是shift+alt+s
public class User
{
    private String name;
    private int age;
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public int getAge()
    {
        return age;
    }
    public void setAge(int age)
    {
        this.age = age;
    }
    @Override
    //為了方便打印,添加一個toString方法
    public String toString()
    {
        return "User [age=" + age + ", name=" + name + "]";
    }
}

二、關於 內省

內省是什么?: 通過反射的方式訪問javabean的技術

Jdk中的api : PropertyDescriptor類操作Bean的屬性

內省的作用:我們可以去實現一種通用性

1.傳統的方式去訪問javabean

public class Demo1
{
    public static void main(String[] args)
    {
        User user=new User();
        
        user.setName("zhangsan");
        user.setAge(19);
        System.out.println(user);
    }
    
}

2.使用內省的方式來訪問javabean

public class Demo1
{
    public static void main(String[] args) throws Exception
    {
        User user=new User();
        //創建屬性描述器
        PropertyDescriptor descriptor=new PropertyDescriptor("name",User.class);
        //獲得寫方法
        Method writeMethod=descriptor.getWriteMethod();
        
        //調用寫方法
        writeMethod.invoke(user, "lisi");
        System.out.println(user);

    }
    
}

 

3.簡化書寫,實現通用性。這里寫一個通用的方法,讓屬性名稱為一個變量,假如屬性名很多的話,得到屬性名后,就可以遍歷,然后給他們一一的賦值,這就是內省的魅力。

如果不用反射,那么傳統的方式是不可能實現通用的。

下面代碼實現能夠為任何的javabean賦任何的值,只有用內省的方法才可以做的到:

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import cn.itcast.day08.domain.User;

public class Demo2 {

    /**
     * @param args
     * @throws IntrospectionException 
     * @throws InvocationTargetException 
     * @throws IllegalAccessException 
     * @throws IllegalArgumentException 
     */
    public static void main(String[] args) throws Exception {
        // 內省
        
        User user = new User();
        
        setProperty(user, "name", "wangwu");
        setProperty(user, "age", 11);
        
        System.out.println(user);

    }
    
    // 實現一個通用的方法   為任意的一個javabean的任意屬性賦任意值
    public static void setProperty(Object bean, String fieldName, Object value) throws Exception {
        // 創建屬性描述器
        PropertyDescriptor descriptor = new PropertyDescriptor(fieldName, bean.getClass());
        
        // 獲得 寫方法
        Method writeMethod = descriptor.getWriteMethod();
        
        // 調用 寫方法
        writeMethod.invoke(bean, value);
    }

}

 

由於內省用起來特別麻煩,Apache組織開發了一套用於操作JavaBean的API,如下詳講:

 

三、BeanUtils工具包

Apache組織開發了一套用於操作JavaBean的API(內省)

核心類 BeanUtils

setProperty(bean, name, value)

copyProperties(target, source);

可以支持String到8中基本數據類型轉換

其他引用數據類型都需要注冊轉換器 ConvertUtils.register(Converter, Class)

 

注意:1、要想使用beanutils需要導入外部的jar包:commons-beanutils-1.8.0.jar這個jar包到lib目錄里面

2、BeanUtils要想使用,還需要導入一個log的jar包:commons-logging.jar

下面我們來看看BeanUtils的魅力:

使用BeanUtils來格式化日期

1.javabean

package cn.itcast.day08.domain;

import java.util.Date;

// 一個javabean 是否有name屬性取決於是否getter或setter方法
public class User {

    private String name;    // 字段

    private int age;
    
    private Date birthday;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + "]";
    }

    
}

2.beanutils

package cn.itcast.day08.introspector;

import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;

import cn.itcast.day08.domain.User;

public class Demo3 {
    
    public static void main(String[] args) throws Exception {
        
        User user = new User();
        
        String name = "zhangsan";
        String age = "19";
        String birthday = "19801122";
        // 11/22/1980   1980 11 22
        
        // 注冊一個轉換器
        /* 使用匿名內部類來注冊轉換器
        ConvertUtils.register(new Converter() {
            
            public Object convert(Class beanClass, Object value) {
                // String -- Date
                String birthday = (String) value;
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                try {
                    return sdf.parse(birthday);
                } catch (ParseException e) {
                    return null;
                }
            }
        }, Date.class);
        */
        DateConverter converter = new DateConverter();
        converter.setPatterns(new String[]{"yyyy-MM-dd","yyyyMMdd","MM/dd/yyyy"});
        ConvertUtils.register(converter, Date.class);
        
        String fieldName = "name";
        BeanUtils.setProperty(user, fieldName, name);
        BeanUtils.setProperty(user, "age", age);
        BeanUtils.setProperty(user, "birthday", birthday);
        
        
        
        System.out.println(user);
        System.out.println(user.getBirthday().toLocaleString());
        
    }

}

 

四. WebUtils 工具類

實現任何request提交的表單封裝到對應的javabean

 

1.用戶注冊jsp頁面:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
   
    <title>用戶注冊表單</title>
    
  </head>
  
  <body style="text-align: center;">
       <form action="/myday08/servlet2" method="post" >
           <table border="1" width="600px">
               <tr>
                   <td>用戶名</td>
                   <td>
                       <input type="text" name="name" />
                   </td>
               </tr>
           
               <tr>
                   <td>年齡</td>
                   <td>
                       <input type="text" name="age" />
                   </td>
               </tr>
               <tr>
                   <td>出生日期</td>
                   <td>
                       <input type="text" name="birthday" />
                   </td>
               </tr>
               
               <tr>
                   <td>
                       <input type="reset" value="重置" />
                   </td>
                   <td>
                       <input type="submit" value="用戶注冊" />
                   </td>
               </tr>
           </table>
       </form>
  </body>
</html>

2.寫一個工具類,把request里面所有的參數全部封裝到javabean中去:

package cn.itcast.day08.util;

import java.lang.reflect.InvocationTargetException;
import java.sql.Date;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;

public class WebUtils
{
    private WebUtils(){}
    
    //定義一個通用工具方法,將請求參數封裝到javabean
    public static Object request2bean(HttpServletRequest request,Class beanClass){

    try{
        Object bean=beanClass.newInstance();
        //        獲得所有請求參數名
        Enumeration names = request.getParameterNames();
        //注冊日期轉換器
        DateConverter converter=new DateConverter();
        converter.setPattern("yyyy-MM-dd");
        ConvertUtils.register(converter, Date.class);
        
        //遍歷
        while(names.hasMoreElements()){
//            獲得一個參數名
            String name = (String)names.nextElement();
//            獲得參數名對應的參數值
            String value = request.getParameter(name);
            //將參數名作為屬性名 將參數值作為屬性值,通過beanutils工具實現屬性的封裝
        
                BeanUtils.setProperty(bean, name, value);
            }
                return bean;
            }catch (Exception e)
            {
                throw new RuntimeException(e);
            }//異常要抓下來,不能拋給servlet,把編譯時異常包裝稱運行時異常
            
        }
    }

3.寫一個servlet頁面,注意查看導入的包名稱!分清關系

package cn.itcast.day08.web.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.itcast.day08.domain.User;
import cn.itcast.day08.util.WebUtils;

public class Servlet2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 表單提交的參數封裝到javabean
        User bean = WebUtils.request2Bean(request, User.class);
        
        System.out.println(bean);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

 

 

jsp這塊的重點為:

1. jsp運行原理(會被翻譯成servlet)

2. jsp腳本表達式和腳本片段

3. jsp九大隱式對象

4. web開發的四個域對象

5. 內省

beanUtils工具的使用

使用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM