總結:
1.severlet容器是通過JavaBean中的屬性方法名來獲取屬性名的,然后根據此屬性名來從request中取值 2.JavaBean中屬性方法的命名,set后的名稱要與你從request中傳遞過來的屬性要一致,除第一個字母不區分大小寫外,其他部分的大小寫有嚴格的區分。 3.設置JavaBean屬性的順序是按照屬性方法在JavaBean中出現的先后順序來設置的。
1.實驗:一個javabean程序+一個jsp頁面// javabeapackage mycom;
public class Test { private String name; private int age; public void setAge(int age) { this.age=age; } public void setName(String name) { this.name=name; } public String getName() { return name; } public int getAge() { return age; } }
//jsp頁面
<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %>
<jsp:useBean id="test" class="mycom.Test" scope="page">
<jsp:setProperty name="test" property="*" />
</jsp:useBean>
<!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=gb2312">
<title>測試</title>
</head>
<body>
<%=test.getName()%>
</body>
</html>
2. 實驗方式,通過改變url的方式,進行參數的傳遞,然后,查看jsp頁面中的結果:
我使用的resin,將上面的文件按要求放好后(這點俺就不強調了哈)。啟動resin后,我們在瀏覽器中輸入:http://localhost/mytest.jsp?name=mbq&age=21然后我們就可以看到顯示的內容是mbq,這表示已經關聯成功了。我現在想的第一個問題就是,request中的參數和bean中的屬性名稱到底有什么關系,容器是據什么來判斷的?好的,我們先假設容器是根據請求中的參數來尋找bean中的屬性設置方法,不過這有點問題了,就是如果請求中的參數對應的屬性設置方法沒有,那么調用bean的屬性方法的話就會出錯!基於此我們就反過來,就假設容器是根據bean的屬性設置方法名來獲得請求參數,這樣即使請求參數沒有的話,使用requset.getParameters(String pname)也只是返回null,而不是報錯。 ok,假設成立了,以第二種假設來做,改Test.java文件,將設置姓名的屬性方法名改為setNameTxt(String name),然后編譯下。接着刪除work目錄下的所有文件,然后重新啟動resin(以后的每次操作都這樣做)。我們同樣在瀏覽器中輸入:http://localhost/mytest.jsp?name=mbq&age=21,我們在瀏覽器中看到的結果是null。然后我們打開jsp編譯后的源程序,發現沒改之前源程序中的request.getParameters("name")變成了request.getParameters("nameTxt")。很明顯,這證明了我們的假設,即容器是根據bean的屬性設置方法來取參數,如果有則設置該bean的屬性。注意這里是屬性設置方法,而不是屬性!不信,你可以將屬性name改成任何名稱都是可以的。 好,現在來考慮第二個問題,那就是屬性設置方法名的命名有什么要求?由於JavaBean中的方法都是由一系列set和get方法組成的(當然還有其他的,比如is方法)。是不是一定要是set開頭呢?事實能說明一切,我們把上面的bean的屬性方法該為mysetName(String name),然后編譯重啟resin,在瀏覽器中一樣輸入:http://localhost/mytest.jsp?name=mbq&age=21,發現結果仍然是null,再看編譯后的源代碼,發現request.getParameters("name")不見了,呵,因為容器沒有發現該set方法嘛,所以容器是找所有以set方法開頭的方法。由前面可知,那緊跟在set后面的應該是某個屬性的名字了,對,是這樣的,set后面的字符串就應該是bean中某個屬性的名字,比如setName中的name就是該bean的屬性。那后面的屬性名的大小寫有什么要求呢?我們改寫bean的屬性方法為setNameValue()和setnamevalue()試試,屬性name不用改還是用它。然后在瀏覽器中輸入http://localhost/mytest.jsp?name=mbq&age=21,我們現在不管結果,我們關心的是源碼哈,然后看編譯后的源碼,發現getParameters的參數變成了nameValue,使用兩個的效果是一樣的。這樣外面又可以得出:容器在通過屬性設置方法取屬性名的時候自動將第一個字母轉換成小寫了,這個其實很好理解。因為java中的方法命名都是第一個單詞小寫,后面的單詞第一個字母大寫來約定的,所以為保持這個約定,容器自動的將第一個字母換成小寫了,雖然使用大小寫沒區別,但是都是約定成俗的嘛~~~ 第三個問題就是順序的問題了。這個現在也好說了,我們交換bean中setName和setAge兩個方法的位置。然后編譯,重啟resion,照樣輸入前面的內容。再查看編譯后的源文件,發現沒改之前的先取age,然后再取name,變成了現在的先取name,然后再取age了。可見容器在從request中取參數的時候是根據bean中屬性設置方法的先后順序來取的。另外類型轉換的問題,由於從request中取出的所有屬性都是字符串形式的,容器的內在機制會自動把這些字符串轉換成屬性設置方法中的參數對應的類型。