javabean以及内省技术的详解

时间:2022-04-24 19:05:46

一、关于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

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 + "]";
}


}<div class="cnblogs_code" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a target=_blank title="复制代码"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif" /></a></span></div><pre><span style="color: #0000ff;">package</span><span style="color: #000000;"> cn.itcast.day08.introspector;

</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.lang.reflect.InvocationTargetException;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.text.ParseException;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.text.SimpleDateFormat;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.util.Date;

</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> org.apache.commons.beanutils.BeanUtils;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> org.apache.commons.beanutils.ConvertUtils;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> org.apache.commons.beanutils.Converter;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> org.apache.commons.beanutils.converters.DateConverter;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> org.apache.commons.beanutils.locale.converters.DateLocaleConverter;

</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> cn.itcast.day08.domain.User;

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Demo3 {

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> main(String[] args) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> Exception {

User user </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> User();

String name </span>= "zhangsan"<span style="color: #000000;">;
String age </span>= "19"<span style="color: #000000;">;
String birthday </span>= "19801122"<span style="color: #000000;">;
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 11/22/1980 1980 11 22

</span><span style="color: #008000;">//</span><span style="color: #008000;"> 注册一个转换器</span>
<span style="color: #008000;">/*</span><span style="color: #008000;"> 使用匿名内部类来注册转换器
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);
</span><span style="color: #008000;">*/</span><span style="color: #000000;">
DateConverter converter </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> DateConverter();
converter.setPatterns(</span><span style="color: #0000ff;">new</span> String[]{"yyyy-MM-dd","yyyyMMdd","MM/dd/yyyy"<span style="color: #000000;">});
ConvertUtils.register(converter, Date.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);

String fieldName </span>= "name"<span style="color: #000000;">;
BeanUtils.setProperty(user, fieldName, name);
BeanUtils.setProperty(user, </span>"age"<span style="color: #000000;">, age);
BeanUtils.setProperty(user, </span>"birthday"<span style="color: #000000;">, birthday);



System.out.println(user);
System.out.println(user.getBirthday().toLocaleString());

}

}</span>

javabean以及内省技术的详解

 

四. WebUtils工具类

实现任何request提交的表单封装到对应的javabean

 

1.用户注册jsp页面:

javabean以及内省技术的详解
<%@ 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>
javabean以及内省技术的详解

2.写一个工具类,把request里面所有的参数全部封装到javabean中去:

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,把编译时异常包装称运行时异常

}
}
javabean以及内省技术的详解

3.写一个servlet页面,注意查看导入的包名称!分清关系

javabean以及内省技术的详解
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);
}

}
javabean以及内省技术的详解

 

 

jsp这块的重点为:

1. jsp运行原理(会被翻译成servlet)

2. jsp脚本表达式和脚本片段

3. jsp九大隐式对象

4. web开发的四个域对象

5. 内省

beanUtils工具


不改


转自:cnblogs.com/yejiurui/archive/2012/10/06/2712693.html