一、什么是 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);
- }
- }
来源: http://www.bubuko.com/infodetail-1986274.html