JavaBean的定义:
JavaBean是一个遵循特定写法的Java类;
JavaBean的特点:
- 这个Java类必须具有一个无参的构造函数
- 属性私有化。
- 私有化的属性必须通过public类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范。
JavaBean的作用:
通常用于封装数据,对于遵循以上写法的JavaBean组件,其它程序可以通过反射技术实例化JavaBean对象,并且通过反射那些遵守命名规范的方法,从而获知JavaBean的属性,进而调用其属性保存数据。
JavaBean的属性:
- JavaBean的属性可以是任意类型,并且一个JavaBean可以有多个属性。每个属性通常都需要具有相应的setter、 getter方法,setter方法称为属性修改器,getter方法称为属性访问器。
- 属性修改器必须以小写的set前缀开始,后跟属性名,且属性名的第一个字母要改为大写,例如,name属性的修改器名称为setName,password属性的修改器名称为setPassword。
- 一个JavaBean的某个属性也可以只有set方法或get方法,这样的属性通常也称之为只写、只读属性。
JSP的三种封装数据的方式:
下面是一个User类,同时它也是一个JavaBean组件,接下来是实例代码:
package cn.study.bean;
import java.util.Date;
/**
* User的JavaBean
* @author 哎呦不错呦
*
*/
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页面,在其中写了三个表单,分别用于jsp三种封装数据时的测试;
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>表单提交到JSP的页面</h3>
<form action="/JSPStudy/bean/success.jsp" method="post">
账号:<input type="text" name="username"/><br>
密码:<input type="password" name="password"/><br>
<input type="submit" value="登录"/>
</form>
<h3>表单提交到Servlet程序</h3>
<form action="/JSPStudy/user" method="post">
账号:<input type="text" name="username"/><br>
密码:<input type="password" name="password"/><br>
<input type="submit" value="登录"/>
</form>
<h3>表单提交到Servlet(BeanUtils)程序</h3>
<form action="/JSPStudy/userBeanUtils" method="post">
账号:<input type="text" name="username"/><br>
密码:<input type="password" name="password"/><br>
余额:<input type="text" name="money"/><br>
生日:<input type="text" name="birthday"/><br>
<input type="submit" value="登录"/>
</form>
</body>
</html>
1.使用JavaBean组件的动作元素,即JSP标签,完成数据封装,它们分别为:
<jsp:useBean>标签:用于在JSP页面中查找或实例化一个JavaBean组件。
<jsp:setProperty>标签:用于在JSP页面中设置一个JavaBean组件的属性。
<jsp:getProperty>标签:用于在JSP页面中获取一个JavaBean组件的属性。
当我们使用JSP标签封装数据时,从ligin.jsp提交表单数据,跳转到success.jsp页面可以这样写:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="cn.study.bean.User"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>传统方式封装数据</h3>
<%
//获取请求参数,创建User对象,设置值
//获取表单的内容
String username = request.getParameter("username");
String password = request.getParameter("password");
//创建User对象,set设置值
User user = new User();
user.setUsername(username);
user.setPassword(password);
%>
<!-- <%=user.getUsername()+":"+user.getPassword() %> -->
<!-- 下面是使用JSP动作标签完成数据封装-->
<jsp:useBean id="u" class="cn.study.bean.User"></jsp:useBean>
<!-- 上述的id 是javabean组件的标识,可以任意取名 class属性中是javabean组件的完全路径名: 即上述User类的 包名+ 类名 -->
<!-- 如果属性多可以使用下面一行代码色设置属性值 -->
<!-- <jsp:setProperty property="*" name="u"/> -->
<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>
2.通过内省(Introspector) — JavaBean 完成数据封装
访问JavaBean属性的两种方式:
- 直接调用bean的setXXX或getXXX方法。
- 通过内省技术访问(java.beans包提供了内省的API)
什么是内省呢?
内省是基于反射的 ,通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。
下面写了一个UserServlet类继承了HttpServlet,获取login.jsp中表单提交的数据,通过内省的方式进行封装;下面是实例代码;
package cn.study.servlet;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
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.study.bean.User;
/**
* 获取请求参数,封装数据
*/
public class UserServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//获取请求参数,创建User对象,设置值
/**
* //获取表单的内容
String username = request.getParameter("username");
String password = request.getParameter("password");
//创建User对象,set设置值
User user = new User();
user.setUsername(username);
user.setPassword(password);
*/
//获取输入的数据
Map<String, String[]> map = request.getParameterMap();
//创建User对象
User user = new User();
//自己编写封装数据的方法
try {
populate(user,map);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//完成数据封装
System.out.println(user.getUsername());
System.out.println(user.getPassword());
}
/**
* 完成数据的封装
* @param map
* @param user
* @throws Exception
*/
private void populate(User user,Map<String, String[]> map) throws Exception {
// TODO Auto-generated method stub
//获取JavaBean类的信息
BeanInfo info = Introspector.getBeanInfo(user.getClass());
//获取属性描述
PropertyDescriptor[] pds = info.getPropertyDescriptors();
//循环遍历
for (PropertyDescriptor pd : pds) {
//获取属性的名称
String name = pd.getName();
//map的key
if(map.containsKey(name)) {
//获取属性的写的方法
Method m = pd.getWriteMethod();
//执行
m.invoke(user, map.get(name)[0]);
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
3.使用beanutils工具包完成数据封装(第二种方式封装数据我写的只能封装字符串数据,如要封装Double数据类型的画需要自己重新编写,或者直接使用第三种方式,使用beanutils工具包进行数据的封装)
在使用Beanutils工具包之前,需要在WEBINF/lib的目录中导入两个jar的包,才能进行数据的封装;如下图所示:
Beanutils工具包的常用类:
BeanUtils populate(Object bean, Map properties) 自定义转换器
ConvertUtils.regsiter(Converter convert, Class clazz) 传入日期类型的Date.class
如果属性是日期型数据,不能直接使用Beanutils工具包进行数据封装,注意:需要先把默认的字符串转换成日期型数据;过程分为以下两步:
1.编写一个类,实现Converter接口,重写该方法。把字符串转换成日期。
package cn.study.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.management.RuntimeErrorException;
import org.apache.commons.beanutils.Converter;
public class MyDateConverter implements Converter{
/**
* 字符串转换成日期
*/
@Override
public Object convert(Class type, Object value) {
// TODO Auto-generated method stub
//value表示输入的值
//把输入的字符串,转换成日期,返回
String dDate = (String) value;
//把字符串转换成日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = sdf.parse(dDate);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
//throw new RuntimeException("转换日期错误");
}
return date;
}
}
2.在封装数据之前进行注册。使用ConvertUtils类的 ConvertUtils.register(Converter converter, Class clazz)方法进行注册。 clazz的值是Date.class
package cn.study.servlet;
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.study.bean.User;
import cn.study.utils.MyDateConverter;
/**
* Servlet implementation class userBeanUtils
* 使用BeanUtils完成数据封装
*/
public class userBeanUtils extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//获取数据
Map<String, String[]> map = request.getParameterMap();
//创建User对象
User user = new User();
//完成注册
ConvertUtils.register(new MyDateConverter(), Date.class);
//使用BeanUtils完成封装
try {
BeanUtils.populate(user, map);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//打印
System.out.println(user.getUsername());
System.out.println(user.getPassword());
System.out.println(user.getMoney());
System.out.println(user.getBirthday());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
参考: 传智播客 www.itcast.cn