BeanUtils開發包的使用

  • 2020 年 2 月 14 日
  • 筆記

對內省技術有了一定的了解之後,我們就可以來學習一下BeanUtils開發包的使用了。

我們先假設一個情景,有一個JSP文件,如果要將該JSP文件中表單數據封裝到Servlet文件應該怎麼辦?此時<jsp:setProperty property="*"/>方法顯然就不奏效了,因為它是JSP文件特有的動作指令。當然,在ServletRqeuest接口中存在方法getParameterMap(),所以可以通過該方法得到表單數據的Map集合,然後利用內省技術將Map集合中的數據保存到bean對象對應的屬性中去。

顯然這是很麻煩的一件事情,但是也不用擔心,Apache組織開發了一套用於操作JavaBean的API,此時,就引出了我們今天的主題,BeanUtils開發包,它考慮到了很多實際開發中的應用場景,當然也就包括我上面提到的情景,那麼BeanUtils該如何使用呢?

首先要下載BeanUtils的jar包,Apache公司的很多項目都是有相互的依賴的,所以這時候需要下載兩個jar包,1、commons-beanutils 2、commons-logging beanutils依賴於logging的jar包。 大家可以下載我上傳的壓縮包,點擊下載,不過新版本的CSDN好像改不了下載積分了,本來是想免費分享的,系統默認設置為了5積分下載,沒有積分的小夥伴也可以自己去官網下載或者百度下載。 下載好了壓縮包後,解壓就會得到兩個壓縮包,分別解壓開。

將紅色方框內的兩個jar包複製到項目中去,接下來通過一個案例來入門使用一下BeanUtils開發包。 創建一個Person類

public class Person {  	private String name;  	private String city;  	private String hobby;    	public String getName() {  		return name;  	}    	public void setName(String name) {  		this.name = name;  	}    	public String getCity() {  		return city;  	}    	public void setCity(String city) {  		this.city = city;  	}    	public String getHobby() {  		return hobby;  	}    	public void setHobby(String hobby) {  		this.hobby = hobby;  	}  }

接下來新建demo.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>  	<!-- 使用BeanUtils 將 form參數封裝到JavaBean 對象中 -->  	<form action="/demo/demoservlet" method="post">  		姓名:<input type="text" name="name"><br>  		城市:<input type="text" name="city"><br>  		愛好:<input type="text" name="hobby"><br>  		<input type="submit" value="提交">  	</form>  </body>  </html>

然後創建DemoServlet.java文件

public class DemoServlet extends HttpServlet {  	public void doGet(HttpServletRequest request, HttpServletResponse response)  			throws ServletException, IOException {  		request.setCharacterEncoding("utf-8");//處理亂碼  		//將form參數自動封裝到Person對象  		Person person = new Person();  		try {  			BeanUtils.populate(person, request.getParameterMap());  		} catch (IllegalAccessException e) {  			e.printStackTrace();  		} catch (InvocationTargetException e) {  			e.printStackTrace();  		}  		System.out.println(person.getName());  		System.out.println(person.getCity());  		System.out.println(person.getHobby());  	}    	public void doPost(HttpServletRequest request, HttpServletResponse response)  			throws ServletException, IOException {  		doGet(request, response);  	}  }

運行一下該項目,對錶單進行如下輸入

點擊提交,控制台輸出如下信息

由此可以得知,表單中的數據被正確地保存到了bean對象中。該工具包的功能遠不止如此,我們改進一下該案例 將Person類作如下修改

public class Person {  	private String name;  	private String city;  	private String hobby;  	//添加age屬性  	private int age;    	public int getAge() {  		return age;  	}    	public void setAge(int age) {  		this.age = age;  	}    	public String getName() {  		return name;  	}    	public void setName(String name) {  		this.name = name;  	}    	public String getCity() {  		return city;  	}    	public void setCity(String city) {  		this.city = city;  	}    	public String getHobby() {  		return hobby;  	}    	public void setHobby(String hobby) {  		this.hobby = hobby;  	}  }

將demo.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>  	<!-- 使用BeanUtils 將 form參數封裝到JavaBean 對象中 -->  	<form action="/demo/demoservlet" method="post">  		姓名:<input type="text" name="name"><br>  		城市:<input type="text" name="city"><br>  		愛好:<input type="text" name="hobby"><br>  		<!-- 增加年齡輸入框 -->  		年齡:<input type="text" name="age"><br>  		<input type="submit" value="提交">  	</form>  </body>  </html>

對DemoServlet.java文件作如下修改

public class DemoServlet extends HttpServlet {    	public void doGet(HttpServletRequest request, HttpServletResponse response)  			throws ServletException, IOException {  		request.setCharacterEncoding("utf-8");//處理亂碼  		//將form參數自動封裝到Person對象  		Person person = new Person();  		try {  			BeanUtils.populate(person, request.getParameterMap());  		} catch (IllegalAccessException e) {  			e.printStackTrace();  		} catch (InvocationTargetException e) {  			e.printStackTrace();  		}  		System.out.println(person.getName());  		System.out.println(person.getCity());  		System.out.println(person.getHobby());  		//打印person對象的age屬性值  		System.out.println(person.getAge());  	}    	public void doPost(HttpServletRequest request, HttpServletResponse response)  			throws ServletException, IOException {  		doGet(request, response);  	}  }

重新運行一遍程序,對錶單進行輸入

控制台輸出信息為

會發現,即使Person類中存在數據類型不相同的屬性(即使在表單中輸入的年齡數據類型為String,卻依然可以存放入屬性類型為int的屬性age中),工具類仍然可以處理並且傳遞,是不是很good呢? 繼續升華一下我們的項目,在Person類中添加一個類型為Date的屬性birthday,並在demo.jsp文件中添加輸入生日的文本框,最後在DemoServlet.java文件中添加輸出birthday屬性的代碼。 對改進後的表單進行如下輸入

點擊提交按鈕後,網頁報錯了

報錯說明日期格式寫錯了,但是日期格式到底如何輸入呢?到這裡,就必須得明白封裝的原理,不然,接下來的代碼編寫將無法進行。 我們打開commons-beanutils文件夾,在apidocs目錄下有一個index.html文件,打開它,這就是工具包的文檔

點擊紅色方框進入查看,也許你一瞬間就明白了,裏面有各種數據格式的轉換器,所以為什麼String類型的age能夠轉換為int類型存入對象中,相信你一定明白了,它是通過IntegerConverter轉換器實現類型轉換的。 默認情況下,form表單中的String類型參數會封裝到JavaBean中的String類型屬性 當JavaBean中屬性類型與form表單提交的參數類型不一致時,就需要類型轉換器。 現在的目的就是將String類型的日期轉換為Date類型的日期。 會發現,在org.apache.commons.beanutils.converters包下雖然有DateConverter日期轉換器,但是文檔並沒有詳細說明它的用法和輸入日期的格式,既然如此,我們只能自定義一個日期轉換器來實現我們的目的。 通過文檔可以知道,所有的轉換器都實現了Converter接口,所以我們自定義轉換器也需要實現該接口。 編寫內部類MyDateConverter類並實現接口

class MyDateConverter implements Converter{  	//需要將value數據轉換為c的類型  	public Object convert(Class c, Object value) {  		String s = (String) value;//value代表的是用戶輸入的生日  		DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");  		try {  			Object result = dateFormat.parseObject(s);//將String解析為Date  		} catch (ParseException e) {  			e.printStackTrace();  		}  		return null;  	}  }

此時,自定義的日期轉換器就編寫完成了,然後,在調用populate方法前,應該註冊轉換器,所以整體DemoServlet.java文件作如下修改

public class DemoServlet extends HttpServlet {    	public void doGet(HttpServletRequest request, HttpServletResponse response)  			throws ServletException, IOException {  		request.setCharacterEncoding("utf-8");//處理亂碼  		//將form參數自動封裝到Person對象  		Person person = new Person();    		//在封裝數據之前,註冊轉換器  		ConvertUtils.register(new MyDateConverter(), Date.class);//第二個參數為想要轉換的數據類型    		try {  			BeanUtils.populate(person, request.getParameterMap());  		} catch (IllegalAccessException e) {  			e.printStackTrace();  		} catch (InvocationTargetException e) {  			e.printStackTrace();  		}  		System.out.println(person.getName());  		System.out.println(person.getCity());  		System.out.println(person.getHobby());  		System.out.println(person.getAge());  		System.out.println(person.getBirtyday());  	}    	public void doPost(HttpServletRequest request, HttpServletResponse response)  			throws ServletException, IOException {  		doGet(request, response);  	}    	class MyDateConverter implements Converter{    		//需要將value數據轉換為c的類型  		public Object convert(Class c, Object value) {  			String s = (String) value;//value代表的是用戶輸入的生日  			DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");  			try {  				Object result = dateFormat.parseObject(s);//將String解析為Date  				return result;  			} catch (ParseException e) {  				e.printStackTrace();  			}  			return null;  		}  	}  }

對錶單進行輸入

控制台輸出如下

由此說明,自定義的日期轉換器實現了日期轉換,我們的目的已經達到。