Struts2學習(四):Action執行的時候發生了什麼

“分流”是指根據我們所請求的url把request交給某個指定的action來處理。那麼在這個FilterDispatcher中還有一些什麼操作呢?在Struts1中我們經常要把一個ActionForm和一個Action相關聯,ActionForm中封裝了表單的所有值,並且這些都是在ActionServlet中完成的,因此我們在action中可以直接通過ActionForm得到表當中的值,那麼Struts2中又是怎麼做的呢?我們怎麼取得那些值呢?我發現可以這麼做:對錶單中每一個要獲取的值,在action中相應添加這樣的一個域(也就是屬性),然後再設置相應的set和get方法,即採用javabean風格,貌似這個現在比較流行。比方說在前面的例子中,在sayHello.jsp的表單中有一個文本域,它的name=”name”,在我的action文件HelloWorld.java中有一個域private String name;同時還分別設置了相應的setName和getName方法,現在我把setName方法改爲如下:

public void setName(String name) {

       System.out.println("name:"+name);     

this.name = name;

}

OK,在瀏覽器中輸入http://localhost:8888/Struts/sayHello.jsp,這時我們發現後臺打印出了name:CMTobby,CMTobby是我輸入的name的值,這說明setName方法被執行了,奇怪啊,我們根本沒有顯式的調用這個方法啊,它是什麼時候調用的呢?現在我們在setName方法裏面設置一個斷點,然後再在execute方法裏面設置一個斷點,再次運行我們的程序,結果顯示setName方法在execute方法前面執行。

接着,無聊的我又做了一些測試:

1.把setName改爲setName1,結果頁面輸出:Hello null,並且setName1爲執行

2.在sayHello.jsp的form之外加了一個文本框,取名address,在HelloWorld中增加相應的域address、setAddress方法和getAddress方法,通過斷點測試發現,setAddress方法不會執行。

基於以上測試,我認爲在執行action的操作之前,首先會根據請求頁面的form表當中所包含的參數來調用action中相應的set****方法,比如說,本例中,form中有name屬性,因此會在執行execute之情調用setName方法,而address因爲不在form中所以不會調用setAddress方法.

在處理完請求之後如何把用戶所請求的值回傳到結果頁面當中呢?在HelloWorld.jsp中我們用了<s:property value="name" />,嘿嘿,難道又是隱式的調用了getName方法嗎?於是我在HelloWorld.java的getName方法處設置了一個斷點,再次運行我們的程序,果然getName被隱式的調用了。

此外如果我把<s:property value="name" />中value的值改爲別的如name1,這時頁面出錯,一片空白。我接着又把getName方法改爲getName1,這時頁面仍然一片空白,因爲取不到name屬性的值。如果我把<s:property value="name" />改爲

<s:property value="name1" />,同時也把getName改爲getName1,那麼顯示就正常了,這個表明框架會根據屬性的名字去調用相應的get方法。

上述機制是不是和我們前面所討論的BeanUtils的copyProperties方法一樣,實際上很多ORM框架都採用的這個機制,都是首先得到屬性名再調用相應的set或者get方法,而不是直接訪問的域。

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