天天看点

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);
        }
    }
  
}