首先要知道什么是JavaBean:
JavaBean是一种遵循特点写法的Java类,通常遵循如下特点:
这个Java类必须要具有一个无参的构造方法
属性私有化
私有化的属性必须通过set、get的public方法暴露给其他程序,命名也要按照已有的规范
JavaBean在J2EE开发中,通常用于封装数据,对于遵循以上写法的JavaBean组件,其它程序可以通过反射技术实例化JavaBean对象,并且通过反射那些遵守命名规范的方法,从而获知JavaBean的属性,进而调用其属性保存数据。
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;
}
}
像平常的方法,创建对象,一个一个获得属性的值,一个一个调用set方法设置。但是如果碰到有大量的数据需要获取,需要导入设置,这个方法就非常的麻烦。
<%@page import="com.xml.ov.User"%>
<%@ 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>接受数据</h3>
<%
//获取表单内容
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()%>
</body>
</html>
1.通过JSP的动态标签完成数据封装
主要使用的3种动态标签:
<jsp:useBean> : <jsp:useBean id="u" class="cn.itcast.vo.User"></jsp:useBean>
* id映射class,class是JavaBean的合格路径(包名+类名)
<jsp:setProperty> : <jsp:setProperty property="username" name="u"/>* property指的是要写入值的名称,name对应id
<jsp:getProperty> : <jsp:setProperty property="password" name="u"/>
这是怎么做到的呢?
从前端表单提交到后台以后,在set标签填入JavaBean中的属性名称,当表单中的name和属性名称相同时,自动填入数据。这就要求表单和JavaBean的属性名相同了。
<%@page import="com.xml.ov.User"%>
<%@ 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>接受数据</h3>
<!-- 使用JSP标签封装数据 -->
<jsp:useBean id="u" class="com.xml.ov.User"></jsp:useBean>
<jsp:setProperty property="username" name="u"/>
<jsp:setProperty property="password" name="u"/>
<jsp:getProperty property="username" name="u"/>
<jsp:getProperty property="password" name="u"/>
当要填入的数据太多时,
赋值还有下面这种全选的方法,就是使用‘*’,只要是属性名称对应的都可以传值给后面
<!-- <jsp:setProperty property="*" name="u"/> -->
</body>
</html>
2.通过内省完成数据封装
内省是基于反射技术的。内省技术在Java.Bean的包中也有专门的API —— Introspector类。
通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取输入数据
Map<String, String[]> map = request.getParameterMap();
//创建User对象
User user = new User();
//自己编写一个方法封装数据
try {
populate(map,user);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("UserServlet"+user.getUsername());
System.out.println("UserServlet"+user.getPassword());
}
public void populate(Map<String, String[]> map,User user) throws IntrospectionException, Exception, IllegalArgumentException, InvocationTargetException {
BeanInfo info = Introspector.getBeanInfo(user.getClass());
//获得属性描述
java.beans.PropertyDescriptor[] pds = info.getPropertyDescriptors();
//循环遍历
for(java.beans.PropertyDescriptor pd:pds) {
//获得属性名
String name = pd.getName();
//map的key
if (map.containsKey(name)) {
//获得属性的方法
Method m = pd.getWriteMethod();
//执行写入
m.invoke(user, map.get(name)[0]);
}
}
}
3.相比之下最方便简洁的引入jar包(BeanUtils包)
仔细看一眼就会发现,引入的jar包中的BeanUtils调用的方法就是我们上一个例子中自己写的populate方法。没错,就是这个已经写好了的方法!
但是!万一你要填入的是double呢?没关系。这些基本数据类型和string的转换都在BeanUtils中自动完成了。
但但是!万一你填入的是不一般的数据呢?比如日期,岂不是凉凉?所以要自己写一个类(实现Converter,注册转换器,Converter也是BeanUtils包里面的类)转换啊!
1.写一个类,实现Converter接口。
2.重写接口方法,实现日期和字符串得到转换。
3.注册。一定要在数据封装之前。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//编译的时候,populate方法就已经将Javabean中的非string类型进行了适当的转换
Map<String, String[]> map = request.getParameterMap();
User user = new User();
//完成日期转换要在数据封装之前,必须完成Converter的注册。想要转换成什么类型,就在第二个参数设置。如果是日期转换,就是Date.class.具体视情况而定
ConvertUtils.register(new MyDateConverter(), Date.class);
try {
BeanUtils.populate(user, map);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("UserBeanUtils"+user.getUsername());
System.out.println("UserBeanUtils"+user.getPassword());
System.out.println("UserBeanUtils"+user.getMoney());
System.out.println("UserBeanUtils"+user.getBirthday());
}
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
public class MyDateConverter implements Converter{
//把输入的字符串,转换成日期类型,返回
@Override
public Object convert(Class clazz, Object obj) {
String sdate = (String) obj;
//转换
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date;
try {
date = sdf.parse(sdate);
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("日期转换出错");
}
return date;
}
}