一、什么是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);
}
}
转载于:https://blog.51cto.com/11841428/1907778