1、什麼是JavaBean?css
JavaBean是一個遵循特定寫法的Java類,它一般具備以下的特色:
html
這個Java類必須具備一個無參數的構造方法。
java
屬性私有化。
程序員
私有化的屬性化必須經過public類型的方法暴露給其餘程序,而且方法的命名也必須遵照必定的命名規範。
web
JavaBean在JavaEE開中中,一般用於封裝數據,對於遵循以上寫法的JavaBean組件,其餘程序能夠經過反射技術實例化JavaBean對象,而且經過反射哪些遵照命名規範的方法,從而獲取JavaBean的屬性,進而調用其屬性保存數據。
apache
2、JavaBean的屬性
jsp
JavaBean的屬性能夠是任意類型,而且一個JavaBean能夠有多個屬性。每一個屬性一般都須要具備對應的setter方法和getter方法,setter方法稱爲屬性修改器,getter方法稱爲屬性訪問器。
ide
屬性修改器必須以小寫的set前綴開頭,後跟屬性名,而且屬性名的第一個字母必需要大寫。
工具
屬性訪問器一般以小寫的get前綴開始,後跟屬性名,而且屬性名的第一個字母必須大寫。
post
一個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類,有三個屬性啊。
3、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,這樣是很是方便的。
4、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是一條正確之路。
5、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; } }
6、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); } }