1. 程式人生 > >javaweb:JavaBean及內省

javaweb:JavaBean及內省

什麼是JavaBean

lJavaBean是一個遵循特定寫法的Java類,它通常具有如下特點:

這個Java類必須具有一個無參的建構函式

屬性私有化。

私有化的屬性必須通過public型別的getset方法暴露給其它程式,並且方法的命名也必須遵守一定的命名規範。

JavaBeanJ2EE開發中,通常用於封裝資料,對於遵循以上寫法的JavaBean元件,其它程式可以通過反射技術例項化JavaBean物件,並且通過反射那些遵守命名規範的方法,從而獲知JavaBean的屬性,進而呼叫其屬性儲存資料

JavaBean的屬性

lJavaBean的屬性可以是任意型別,並且一個

JavaBean可以有多個屬性。每個屬性通常都需要具有相應的settergetter方法,setter方法稱為屬性修改器,getter方法稱為屬性訪問器。

l屬性修改器必須以小寫的set字首開始,後跟屬性名,且屬性名的第一個字母要改為大寫,例如,name屬性的修改器名稱為setNamepassword屬性的修改器名稱為setPassword

l屬性訪問器通常以小寫的get字首開始,後跟屬性名,且屬性名的第一個字母也要改為大寫,例如,name屬性的訪問器名稱為getNamepassword屬性的訪問器名稱為getPassword

一個JavaBean的某個屬性也可以只有

set方法或get方法,這樣的屬性通常也稱之為只寫、只讀屬性。

例如封裝user:

user.java

package cn.itcast.domain;

import java.util.Date;

public class User {
	
	private String username;
	private String password;
	private double money;
	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 double getMoney() {
		return money;
	}
	public void setMoney(double money) {
		this.money = money;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

}

bean1.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<h3>在JSP中封裝資料</h3>
<form action="/day12/action/bean/bean2.jsp" method="post">
	姓名:<input type="text" name="username" /><br/>
	密碼:<input type="password" name="password" /><br/>
	<input type="submit" value="提交" />
</form>

<h3>在JSP中使用動作標籤來封裝資料</h3>
<form action="/day12/action/bean/bean3.jsp" method="post">
	姓名:<input type="text" name="username" /><br/>
	密碼:<input type="password" name="password" /><br/>
	<input type="submit" value="提交" />
</form>


<h3>在JSP中把資料提交到Servlet程式中</h3>
<form action="/day12/user" method="post">
	姓名:<input type="text" name="username" /><br/>
	密碼:<input type="password" name="password" /><br/>
	<input type="submit" value="提交" />
</form>

<h3>在JSP中把資料提交到Servlet程式中(BeanUtil封裝資料)</h3>
<form action="/day12/user2" 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>





 bean2.jsp

<%@page import="cn.itcast.domain.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<h3>把資料封裝User物件中</h3>
<%
	String username = request.getParameter("username");
	String password = request.getParameter("password");
	// 完成封裝
	User user = new User();
	user.setUsername(username);
	user.setPassword(password);
	// 在後臺的程式中傳輸user物件
%>

<%= user.getUsername() %>
<%= user.getPassword() %>

</body>
</html>







方式二:使用JSP的動作標籤封裝資料

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<h3>使用JSP的動作標籤封裝資料</h3>
<jsp:useBean id="u" class="cn.itcast.domain.User" scope="page"></jsp:useBean>
<jsp:setProperty property="*" name="u"/>

<h4>檢視資料</h4>
<jsp:getProperty property="username" name="u"/>
<jsp:getProperty property="password" name="u"/>


</body>
</html>

JSP中使用JavaBean :

lJSP技術提供了三個關於JavaBean元件的動作元素,即JSP標籤,它們分別為:

l<jsp:useBean>標籤:用於在JSP頁面中查詢或例項化一個JavaBean元件。

l<jsp:setProperty>標籤:用於在JSP頁面中設定一個JavaBean元件的屬性。

l<jsp:getProperty>標籤:用於在JSP頁面中獲取一個JavaBean元件的屬性。

<jsp:useBean>標籤

l<jsp:useBean>標籤用於在指定的域範圍查詢指定名稱的JavaBean物件:

如果存在則直接返回該JavaBean物件的引用。

如果不存在則例項化一個新的JavaBean物件並將它以指定的名稱儲存到指定的域範圍中。

l常用語法:

  <jsp:useBean id="beanName" class="cn.itcast.Test"

  scope="page|request|session|application"/>

 

üid屬性用於指定JavaBean例項物件的引用名稱和其儲存在域範圍中的名稱。

üclass屬性用於指定JavaBean的完整類名(即必須帶有包名)。

üscope屬性用於指定JavaBean例項物件所儲存的域範圍,其取值只能是pagerequestsessionapplication等四個值中的一個,其預設值是page

<jsp:useBean>執行原理:

l<jsp:useBean id="currentDate" class="java.util.Date"/>

l翻譯成的Servlet原始碼:

java.util.Date currentDate = null;

synchronized (_jspx_page_context) {

  currentDate = (java.util.Date)             _jspx_page_context.getAttribute(

  "currentDate", PageContext.PAGE_SCOPE);

  if (currentDate == null){

  currentDate = new java.util.Date();

  _jspx_page_context.setAttribute("currentDate",

  currentDate, PageContext.PAGE_SCOPE);

  }

 }   

帶標籤體的<jsp:useBean>標籤

l語法:

  <jsp:useBean ...> 

  Body 

  </jsp:useBean>

l功能:

  Body部分的內容只在<jsp:useBean>標籤建立JavaBean的例項物件時才執行。

<jsp:getProperty>標籤:

l<jsp:getProperty>標籤用於讀取JavaBean物件的屬性,也就是呼叫JavaBean物件的getter方法,然後將讀取的屬性值轉換成字串後插入進輸出的響應正文中。

l語法:

  <jsp:getProperty name="beanInstanceName" property="PropertyName" />

üname屬性用於指定JavaBean例項物件的名稱,其值應與<jsp:useBean>標籤的id屬性值相同。

üproperty屬性用於指定JavaBean例項物件的屬性名。

l如果一個JavaBean例項物件的某個屬性的值為null,那麼,使用<jsp:getProperty>標籤輸出該屬性的結果將是一個內容為“null”的字串。

內省(Introspector) JavaBean:

l什麼是JavaBean和屬性的讀寫方法?

l訪問JavaBean屬性的兩種方式:

直接呼叫beansetXXXgetXXX方法。

通過內省技術訪問(java.beans包提供了內省的API)

內省技術是基於反射技術的

通過Introspector類獲得Bean物件的 BeanInfo,然後通過 BeanInfo 來獲取屬性的描述器( PropertyDescriptor ),通過這個屬性描述器就可以獲取某個屬性對應的 getter/setter 方法,然後通過反射機制來呼叫這些方法。

內省beanutils工具包

連結: https://pan.baidu.com/s/1m16SgTL4n0xlQqO2X8S7TA 提取碼: sgrk 

 

lApache組織開發了一套用於操作JavaBeanAPI,這套API考慮到了很多實際開發中的應用場景,因此在實際開發中很多程式設計師使用這套API操作JavaBean,以簡化程式程式碼的編寫。

lBeanutils工具包的常用類:

BeanUtils

populate(Object bean, Map properties)

自定義轉換器

ConvertUtils.regsiter(Converter convert, Class clazz)

傳入日期型別的Date.class

UserServlet.java:

package cn.itcast.servlet;

import java.io.IOException;
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.itcast.domain.MyConverter;
import cn.itcast.domain.User;

/**
 * 使用BeanUtils來封裝資料
 * @author Administrator
 *
 */
public class User2Servlet extends HttpServlet {
	
	private static final long serialVersionUID = 4587417600858959675L;

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 獲取資料
		Map<String, String []> map = request.getParameterMap();
		// 建立User物件
		User user = new User();
		
		// 完成註冊(告訴封裝資料的時候,遇到Date型別的時候,按著我給你傳入物件的方式來解決)
		ConvertUtils.register(new MyConverter(), Date.class);
		
		// 可以使用工具類進行封裝(匯入包)
		try {
			BeanUtils.populate(user, map);
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 看結果
		System.out.println("使用者名稱:"+user.getUsername());
		System.out.println("密碼:"+user.getPassword());
		System.out.println("餘額:"+user.getMoney());
		System.out.println("生日:"+user.getBirthday());
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}

}



當遇到日期型別的時候,需要編寫如下程式碼進行轉換,要不後臺會出現null 錯誤:

Myconvertor.java:

package cn.itcast.domain;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.beanutils.Converter;

/**
 * 完成日期轉換
 * @author Administrator
 *
 */
public class MyConverter implements Converter{
	
	/**
	 * obj:使用者輸入的資料
	 */
	public Object convert(Class clazz, Object obj) {
		// 把obj轉換日期型別
		String str = (String) obj;
		// 把字串轉換日期
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date date;
		try {
			// 轉換
			date = format.parse(str);
		} catch (ParseException e) {
			e.printStackTrace();
			throw new RuntimeException("轉換日期錯誤");
		}
		return date;
	}

}