• 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工具的使用

    使用

    如果,这篇博客帮您解决了问题,不妨点击一下右下角的【推荐】。

    如果,您希望更容易地发现我的新博客,不妨点击一下【加关注】。

    因为,我的热情需要您的肯定和支持! 

    感谢您的阅读,如果文章中有错误或者您有什么好的建议,也欢迎您直接留言批评指教。Thanks,friends!




  • 相关阅读:
    Docker篇章1:Docker介绍
    flask-restful结合vue自定义错误类型
    9.Go语言-函数
    8.Go语言-流程控制
    7.Go语言-结构体
    6.Go语言-指针
    5.Go语言-map类型
    计算机组成原理笔记2-数制、字符、校验码、定点数、浮点数、算术逻辑单元
    计算机组成原理笔记1--基础概念丶性能指标
    计算机网络笔记2--物理层
  • 原文地址:https://www.cnblogs.com/yejiurui/p/2712693.html
Copyright © 2020-2023  润新知