JavaBean的前世今生

一、什么是JavaBean?

JavaBean是一个遵循特定写法的Java类,它通常具有如下的特点:

这个Java类必须具有一个无参数的构造方法。

属性私有化。

私有化的属性化必须通过public类型的方法暴露给其他程序,并且方法的命名也必须遵守一定的命名规范。

JavaBean在JavaEE开中中,通常用于封装数据,对于遵循以上写法的JavaBean组件,其他程序可以通过反射技术实例化JavaBean对象,并且通过反射哪些遵守命名规范的方法,从而获取JavaBean的属性,进而调用其属性保存数据。

二、JavaBean的属性

JavaBean的属性可以是任意类型,并且一个JavaBean可以有多个属性。每个属性通常都需要具有对应的setter方法和getter方法,setter方法称为属性修改器,getter方法称为属性访问器。

属性修改器必须以小写的set前缀开头,后跟属性名,并且属性名的第一个字母必须要大写。

属性访问器通常以小写的get前缀开始,后跟属性名,并且属性名的第一个字母必须大写。

一个JavaBean的某个属性也可以只有setter方法或者getter方法,这样的属性通常也称为只写、只读属性。

总结:是setter方法和getter方法,成就属性,并不是field都是属性。

package cn.vo;

public class User {
	private String username;
	private String password;

}

上面的类严格意义上是没有任何属性,但是如果要说有的话,那就只有class,为什么呢,因为每个类都继承自Object,而Object有一个getClass()方法。

package cn.vo;

public class User {
	private String username;
	private String password;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

}

而此时的User类,有三个属性啊。

三、JavaBean在Servlet的时代

我们知道Servlet在Javaweb体系中是首先出现的,所以下面我们来模拟场景。

User.java

package cn.vo;

public class User {
	private String username;
	private String password;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

}

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP ‘login.jsp‘ starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    <form action="${request.servletContext}/login" method="post">
    	<table>
    		<tr>
    			<td>用户名</td>
    			<td>
    				<input type="text" name="username"/>
    			</td>
    		</tr>
    		<tr>
    			<td>密码</td>
    			<td>
    				<input type="password" name="password"/>
    			</td>
    		</tr>
    		<tr>
    			<td colspan="2">
    				<input type="submit" value="登录"/>
    			</td>
    		</tr>
    	</table>
    </form>
  </body>
</html>

LoginServlet.java

package cn.Introspector;

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.vo.User;

@SuppressWarnings("serial")
public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//设置请求的编码
		request.setCharacterEncoding("utf-8");
		//设置响应的编码
		response.setContentType("text/html;charset=utf-8");
		//获取用户名
		String username = request.getParameter("username");
		//获取密码
		String password = request.getParameter("password");

		//实例化User
		User vo = new User();
		vo.setUsername(username);
		vo.setUsername(password);

		response.getWriter().print("姓名:"+username+",密码:"+password);
	}

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

		this.doGet(request, response);
	}

}

这时,可能有人会想就两个属性,为什么封装到对象中,这样不是很烦,不是的哦,如果这个类有50个属性,那么我们一个一个接收,很烦的啊,所以,我们将数据封装到JavaBean中,然后传递JavaBean,这样是非常方便的。

四、JavaBean在jsp的时代

随着时代的发展,我们知道Servlet有许多不足,所以,sun公司就推出了jsp技术。那么JavaBean在jsp时代又有怎么样的变化呢?

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP ‘login.jsp‘ starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    <form action="/day11/loginJsp.jsp" method="post">
    	<table>
    		<tr>
    			<td>用户名</td>
    			<td>
    				<input type="text" name="username"/>
    			</td>
    		</tr>
    		<tr>
    			<td>密码</td>
    			<td>
    				<input type="password" name="password"/>
    			</td>
    		</tr>
    		<tr>
    			<td colspan="2">
    				<input type="submit" value="登录"/>
    			</td>
    		</tr>
    	</table>
    </form>
  </body>
</html>

loginJsp.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP ‘loginJsp.jsp‘ starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
   	<!-- 
   		class属性:写封装数据类的全路径,用于获取反射的Class类,以便来实例化对象
   	 -->
	<jsp:useBean id="u" class="cn.vo.User"></jsp:useBean> 
	<!-- 
		property属性:要和表单中的对应的name相同,这样才能将表单对应对应的数据封装到对象之中
	 -->  
	<jsp:setProperty property="username" name="u"/>
	<jsp:setProperty property="password" name="u"/>
   <jsp:getProperty property="username" name="u"/>
   <jsp:getProperty property="password" name="u"/>
  </body>
</html>

其实,这个时候,我们就应该有点看出sun公司的意图了,那就是将表单的数据封装到对象之中,来传递。但是这种模式很快就要被淘汰了,因为MVC出现了,MVC的V让jsp来显示,C是让Servlet来充当了。但是,JavaBean从发展而来的种种表明,将数据封装到JavaBean是一条正确之路。

五、JavaBean在MVC2.0时代

通过Introspector类获取Bean对象的BeanInfo,然后通过BeanInfo类来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后通过反射机制来调用这些方法。

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP ‘login.jsp‘ starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    <form action="/day11/login" method="post">
    	<table>
    		<tr>
    			<td>用户名</td>
    			<td>
    				<input type="text" name="username"/>
    			</td>
    		</tr>
    		<tr>
    			<td>密码</td>
    			<td>
    				<input type="password" name="password"/>
    			</td>
    		</tr>
    		<tr>
    			<td colspan="2">
    				<input type="submit" value="登录"/>
    			</td>
    		</tr>
    	</table>
    </form>
  </body>
</html>

LoginServlet.java

package cn.Introspector;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

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

import cn.vo.User;

@SuppressWarnings("serial")
public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		Map<String, String[]> parameterMap = request.getParameterMap();
		User user = new User();
		try {
			BeanInfo info = Introspector.getBeanInfo(user.getClass());
			PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors();
			for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
				if(!propertyDescriptor.getName().equals("class")){
					if(parameterMap.containsKey(propertyDescriptor.getName())){
						Method writeMethod = propertyDescriptor.getWriteMethod();
						writeMethod.invoke(user, parameterMap.get(propertyDescriptor.getName())[0]);
					}
				}
			}
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		response.getWriter().println("姓名:"+user.getUsername()+",密码:"+user.getPassword());

	}

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

		this.doGet(request, response);
	}

}

User.java

package cn.vo;

public class User {
	private String username;
	private String password;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

}

六、BeanUtils工具包

虽然,上面已经实现了功能,但是在开发中我们还会遇到许多问题,比如多选框等等,我们都没有考虑。

Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,一次,在实际开发之中很多程序员使用这套API操作JavaBean,以简化程序代码的编写。

BeanUtils工具包常用类。

BeanUtils:

populate(Object bean,Map properties)

自定义转换器:

ConvertUtils.register(Converter convert,Class clazz)

传入日期类型的Date.class

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP ‘login.jsp‘ starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    <form action="/day11/login" method="post">
    	<table>
    		<tr>
    			<td>用户名</td>
    			<td>
    				<input type="text" name="username"/>
    			</td>
    		</tr>
    		<tr>
    			<td>密码</td>
    			<td>
    				<input type="password" name="password"/>
    			</td>
    		</tr>
    		<tr>
    			<td colspan="2">
    				<input type="submit" value="登录"/>
    			</td>
    		</tr>
    	</table>
    </form>
  </body>
</html>

User.java

package cn.vo;

public class User {
	private String username;
	private String password;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

}

LoginServlet.java

package cn.Introspector;

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.vo.User;

@SuppressWarnings("serial")
public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		Map<String, String[]> parameterMap = request.getParameterMap();
		User user = new User();
		try {
			BeanUtils.populate(user, parameterMap);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		response.getWriter().println("姓名:"+user.getUsername()+",密码:"+user.getPassword());

	}

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

		this.doGet(request, response);
	}

}

日期转换器

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP ‘login.jsp‘ starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    <form action="/day11/login" method="post">
    	<table>
    		<tr>
    			<td>用户名</td>
    			<td>
    				<input type="text" name="username"/>
    			</td>
    		</tr>
    		<tr>
    			<td>密码</td>
    			<td>
    				<input type="password" name="password"/>
    			</td>
    		</tr>
    		<tr>
    			<td>生日</td>
    			<td>
    				<input type="text" name="birthday"/>
    			</td>
    		</tr>
    		<tr>
    			<td colspan="2">
    				<input type="submit" value="登录"/>
    			</td>
    		</tr>
    	</table>
    </form>
  </body>
</html>

User.java

package cn.vo;

import java.util.Date;

public class User {
	private String username;
	private String password;
	private Date birthday;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

}

DateConverter.java

package cn.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import org.apache.commons.beanutils.Converter;

public class DateConverter implements Converter {

	@Override
	public Object convert(Class claza, Object obj) {
		if(obj instanceof String){
			String date = (String) obj;
			try {
				return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

}

LoginServlet.java

package cn.Introspector;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
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 org.apache.commons.beanutils.ConvertUtils;

import cn.util.DateConverter;
import cn.vo.User;

@SuppressWarnings("serial")
public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		Map<String, String[]> parameterMap = request.getParameterMap();
		User user = new User();
		ConvertUtils.register(new DateConverter(), Date.class);
		try {
			BeanUtils.populate(user, parameterMap);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		response.getWriter().println("姓名:"+user.getUsername()+",密码:"+user.getPassword()+",生日:"+user.getBirthday());

	}

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

		this.doGet(request, response);
	}

}
时间: 2024-10-09 16:13:18

JavaBean的前世今生的相关文章

与MVC框架解耦的OGNL:前世今生及其基本用法

摘要: 虽然我们一般都是通过学习MVC框架而结缘OGNL,但它并没有与MVC框架紧紧耦合在一起,而是一个以独立的库文件出现的一种功能强大的表达式语言,也是字符串与Java对象之间沟通的桥梁.特别地,正因为它的独立性,使得我们可以十分方便地利用它构建我们自己的框架.在充分理解和掌握 OGNL 三要素 后,我们就可以通过简单一致的语法去存取Java对象树中的任意属性.调用Java对象树的方法并自动实现必要的类型转化.本文首先概述了Ognl的前世今生,并结合具体实例和源码阐述了OGNL的实质和OGNL

JAVA中反射机制五(JavaBean的内省与BeanUtils库)

内省(Introspector) 是Java 语言对JavaBean类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则.如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为“值对象”(Value Object),或“VO”.方法比较少.这些信息储存在类的私有变量中,通过set().get()获得. 例如类UserInfo : package com.peidasoft.in

JSON与Javabean转换的几种形式

JSON格式的数据传递是最常用的方法之一,以下列出了常用的几种形态以及与Javabean之间的转换: String json1="{'name':'zhangsan','age':23,'interests':[{'interest':'篮球','colors':['绿色','黄色']},{'interest':'足球','colors':['红色','蓝色']}]}"; String json2="[{'name':'zhangsan'},{'name':'lisi'},{

java中的反射机制和javaBean

反射 反射:就是通过一个类加载进方法区时加载到栈内存中的Class字节码文件对这个类进行解剖 通过反射可以获取到一个类的构造方法,成员方法,成员变量 反射将一个类的各个部分映射成相应的类 反射获取构造方法 Class类中方法 Constructor<?>[] getConstructors() 返回当前字节码文件对象的所有public修饰的构造方法 Constructor<T> getConstructor(Class<?>...parameterTypes)返回指定了

JAVAWEB开发之Session的追踪创建和销毁、JSP详解(指令,标签,内置对象,动作即转发和包含)、JavaBean及内省技术以及EL表达式获取内容的使用

Session的追踪技术 已知Session是利用cookie机制的服务器端技术,当客户端第一次访问资源时 如果调用request.getSession() 就会在服务器端创建一个由浏览器独享的session空间,并分配一个唯一且名称为JSESSIONID的cookie发送到浏览器端,如果浏览器没有禁用cookie的话,当浏览器再次访问项目中的Servlet程序时会将JSESSIONID带着,这时JSESSIONID就像唯一的一把钥匙  开启服务器端对应的session空间,进而获取到sessi

了解vo pojo javabean dto

1什么是vo. (1.VO是用new关键字创建,由GC回收的 PO是向数据库中添加新数据时创建,删除数据库中的数据时削除的.并且只能存活在一个数据库连接中,断开连接即被销毁 (2.VO是值对象,业务对象,存活在业务层,是业务逻辑使用的,存活的目的就是为数据提供一个生存的地方.PO则是有状态的,每个属性代表其当前的状态.它是物理数据的对象表示.使用它,可以使我们的程序与物理数据解耦,并且可以简化对象数据与物理数据之间的转换. (3.VO的属性是根据当前业务的不同而不同的,也就是说,它的每一个属性都

JavaBean规范

(1)JavaBean 类必须是一个公共类,并将其访问属性设置为 public ,如: public class user{......} (2)JavaBean 类必须有一个空的构造函数:类中必须有一个不带参数的公用构造器 (3)一个javaBean类不应有公共实例变量,类变量都为private ,如: private int id; (4)属性应该通过一组存取方法(getXxx 和 setXxx)来访问,一般是IDE(Eclipse.JBuilder) 为属性生成getter/setter

Git前世今生-版本控制软件的发展

版本控制软件发展至今已有40多年的历史. 最早的版本控制软件是1972年由Marc J. Rochkind开发的SCCS (Source Code Control System),通过将不同版本下的文件单独保存的形式完成,将同一版本的所有文件打包保存.SCCS使用了长达10年的时间,直到1982年RCS的问世. 1982年,Walter F.Tichy 发布了RCS (Revision Control System),提供了较SCCS更多的功能,并作为GNU项目的一部分. 1986年创建的CVS

老白的JAVA课程16 卡片布局 javaBean

基于组件的开发 javaBean 组成部件 规范   1: 必须要有一个公共的构造方法,javaBean这个类也必须是公共的   2:javaBean中的属性都是私有的,每一个属性都必须提供符合命名规范的set和get方法   3:应该是可序列化的,但是并不是必须的 类型:  1:简单属性javabean  set和get足够简单  2:绑定属性JavaBean  属性复杂,需要绑定其他属性  3:约束属性JavaBean  set和get方法有约束 cardlayout.show(父容器,按钮