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);
	}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章