<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    少年阿賓

    那些青春的歲月

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks

    ModelDriven

     

    為什么需要ModelDriven

     

    所謂ModelDriven ,意思是直接把實體類當成頁面數(shù)據(jù)的收集對象。比如,有實體類User 如下:

     

    package cn.com.leadfar.struts2.actions;

     

    public class User {

        private int id ;

        private String username ;

        private String password ;

        private int age ;

        private String address ;

        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 int getAge() {

           return age ;

        }

        public void setAge( int age) {

           this . age = age;

        }

        public String getAddress() {

           return address ;

        }

        public void setAddress(String address) {

           this . address = address;

        }

        public int getId() {

           return id ;

        }

        public void setId( int id) {

           this . id = id;

        }

       

       

    }

     

     

    假如要寫一個Action ,用來添加User 。

    第一種做法是直接在Action 中定義所有需要的屬性,然后在JSP 中直接用屬性名稱來提交數(shù)據(jù):

    UserAction:

     

    public class UserAction {

        private int id ;

        private String username ;

        private String password ;

        private int age ;

        private String address ;

     

        public String add(){

          

           User user = new User();

           user.setId( id );

           user.setUsername( username );

           user.setPassword( password );

           user.setAge( age );

           user.setAddress( address );

          

           new UserManager().addUser(user);

          

           return "success" ;

        }

       

        public int getId() {

           return id ;

        }

        public void setId( int id) {

           this . id = id;

        }

        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 int getAge() {

           return age ;

        }

        public void setAge( int age) {

           this . age = age;

        }

        public String getAddress() {

           return address ;

        }

        public void setAddress(String address) {

           this . address = address;

        }

       

    }

     

    add_input.jsp:

     

         < form action = "test/user.action" method = "post" >

            < input type = "hidden" name = "method:add" >

            username: < input type = "text" name = "username" > < br />

            password: < input type = "text" name = "password" > < br />

            age: < input type = "text" name = "age" > < br />

            address: < input type = "text" name = "address" > < br />

            < input type = "submit" name = "submit" value = " 添加用戶 " >

         </ form > < br />

    上述做法不好之處是:如果實體類的屬性非常多,那么Action 中也要定義相同的屬性。

     

     

    第二種做法是將User 對象定義到UserAction 中,然后在JSP 中通過user 屬性來給user 賦值:

    UserAction:

     

    public class UserAction {

       

        private User user ;

       

        public String add(){

     

           new UserManager().addUser( user );

          

           return "success" ;

        }

     

        public User getUser() {

           return user ;

        }

     

        public void setUser(User user) {

           this . user = user;

        }

       

       

    }

     

    add_input.jsp:

     

         < form action = "test/user.action" method = "post" >

            < input type = "hidden" name = "method:add" >

            username: < input type = "text" name = "user.username" > < br />

            password: < input type = "text" name = "user.password" > < br />

            age: < input type = "text" name = "user.age" > < br />

            address: < input type = "text" name = "user.address" > < br />

            < input type = "submit" name = "submit" value = " 添加用戶 " >

         </ form > < br />

    這種做法不好的地方是:JSP 頁面上表單域中的命名變得太長

     

    第三種做法是利用ModelDriven 機制,讓UserAction 實現(xiàn)一個ModelDriven 接口,同時實現(xiàn)接口中的方法:getModel() 。如下所示:

     

    public class UserAction implements ModelDriven{

       

        private User user ;

       

        @Override

        public Object getModel() {

           if ( user == null ){

               user new User();

           }

           return user ;

        }

     

        public String add(){

     

           new UserManager().addUser( user );

          

           return "success" ;

        }

     

        public User getUser() {

           return user ;

        }

     

        public void setUser(User user) {

           this . user = user;

        }

    }

    JSP 的代碼如下:

     

         < form action = "test/user.action" method = "post" >

            < input type = "hidden" name = "method:add" >

            username: < input type = "text" name = "username" > < br />

            password: < input type = "text" name = "password" > < br />

            age: < input type = "text" name = "age" > < br />

            < input type = "submit" name = "submit" value = " 添加用戶 " >

         </ form > < br />

     

    可見,第三種做法是比較好的,Action 和JSP 寫起來都比較簡單。

     

     

    ModelDriven 背后的機制?

     

    ModelDriven 背后的機制就是ValueStack 。界面通過:username/age/address 這樣的名稱,就能夠被直接賦值給user 對象,這證明user 對象正是ValueStack 中的一個root 對象!

     

    那么,為什么user 對象會在ValueStack 中呢?它是什么時候被壓入ValueStack 的呢?答案是:ModelDrivenInterceptor (關(guān)于Interceptor 的概念,請參考后續(xù)章節(jié)的說明)。ModelDrivenInterceptor 是缺省的攔截器鏈的一部分,當一個請求經(jīng)過ModelDrivenInterceptor 的時候,在這個攔截器中,會判斷當前要調(diào)用的Action 對象是否實現(xiàn)了ModelDriven 接口,如果實現(xiàn)了這個接口,則調(diào)用getModel() 方法,并把返回值(本例是返回user 對象)壓入ValueStack 。

    請看ModelDrivenInterceptor 的代碼:

     

    public class ModelDrivenInterceptor extends AbstractInterceptor {

     

        protected boolean refreshModelBeforeResult false ;

     

        public void setRefreshModelBeforeResult( boolean val) {

            this . refreshModelBeforeResult = val;

        }

     

        @Override

        public String intercept(ActionInvocation invocation) throws Exception {

            Object action = invocation.getAction();

     

            if (action instanceof ModelDriven) {

                ModelDriven modelDriven = (ModelDriven) action;

                ValueStack stack = invocation.getStack();

                Object model = modelDriven.getModel();

                if (model !=  null ) {

                  stack.push(model);

                }

                if ( refreshModelBeforeResult ) {

                    invocation.addPreResultListener( new RefreshModelBeforeResult(modelDriven, model));

                }

            }

            return invocation.invoke();

        }

    從ModelDrivenInterceptor 中,即可以看到model 對象被壓入ValueStack 中!

     

    其中的 refreshModelBeforeResult 是為了接下來描述的一個問題而提供的解決方法。

     

    理解常見的陷阱及其解決方法

     

    假設(shè)我們要更新一個實體對象,那么第一步首先是打開更新界面,請看下述模擬打開更新界面的代碼:

     

    public class UserAction implements ModelDriven{

       

        private User user ;

       

        @Override

        public Object getModel () {

           if ( user == null ){

               user new User();

               //user.setUsername(" 這是原來的 User 對象 ");

           }

           return user ;

        }

       

        public String updateInput(){

          

           // 根據(jù) ID ,查詢數(shù)據(jù)庫,得到 User 對象

           user new UserManager().findUserById( user .getId());

          

          

           return "update_input" ;

        }

     

    上述代碼中,new UserManager().findUserById(user.getId()); 這一行,將從數(shù)據(jù)庫中查詢相應(yīng)的記錄,同時轉(zhuǎn)換為User 對象返回。而return  update_input  ;將轉(zhuǎn)向更新顯示頁面。

     

    更新頁面如下:

     

         < form action = "test/user.action" method = "post" >

            < input type = "hidden" name = "method:update" >

            id: < input type = "text" name = "id" value = "< s:property value = "id" /> "> < br />

            username: < input type = "text" name = "username" value = "< s:property value ="username" /> "> < br />

            password: < input type = "text" name = "password" value = "< s:property value ="password" /> "> < br />

            age: < input type = "text" name = "age" value = "< s:property value = "age" /> "> < br/>

            address: < input type = "text" name = "address" value = "< s:property value = "address"/> "> < br />

            < input type = "submit" name = "submit" value = " 更新用戶 " >

         </ form > < br />

     

     

    上述代碼運行起來之后,你在更新界面上將看不到數(shù)據(jù)(id 屬性有值,其它屬性無顯示)。關(guān)鍵的原因是在執(zhí)行到updateInput 之前,user 對象(在getMode() 方法中創(chuàng)建的對象)被壓到ValueStack 中,這時候,UserAction 和ValueStack 都指向同一個user對象;但緊接著,UserAction 中的user 被一個新的user 對象覆蓋,這時候,UserAction 和ValueStack 不再指向同一個user 對象!ValueStack 中是舊的user 對象,而UserAction 中是新的user 對象!我們在JSP 中,直接通過username/address 等直接訪問,當然是要訪問ValueStack 中的舊user 對象,所以它們的屬性都是空的(id 屬性除外) !

     

    理解上述問題很重要,當你理解了問題,那么問題的解決方法就可以有很多了:

    比如,你可以把新對象的屬性拷貝到舊對象上;比如,你可以先把舊對象從ValueStack 中移除,然后再把新對象壓入ValueStack等……

     

    在最新的struts2 版本中,ModelDrivenInterceptor 提供了一個配置參數(shù): refreshModelBeforeResult ,只要將它定義為true ,上述問題就被解決了!struts2 的解決方案就是:先把舊的model 對象從ValueStack 中移除,然后再把新的model 對象壓入ValueStack !







    引用地址:
    http://blog.csdn.net/zheng2008hua/article/details/6285737

    posted on 2011-12-15 12:44 abin 閱讀(1217) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 97人妻精品全国免费视频| 国产无遮挡色视频免费观看性色 | 亚洲激情在线视频| 亚洲精品在线播放| 亚洲一线产品二线产品| 爱情岛论坛免费视频| 中文字幕不卡免费视频| 最近免费中文在线视频| 成人五级毛片免费播放| 亚洲日本va午夜中文字幕久久| 久久精品国产亚洲av成人| 2020天堂在线亚洲精品专区| 免费视频成人国产精品网站| 久久精品一区二区免费看| 天天干在线免费视频| 在线a亚洲v天堂网2019无码| 亚洲国产精品线观看不卡 | 亚洲不卡视频在线观看| 亚洲a∨无码精品色午夜| 三年片在线观看免费西瓜视频| 一级女人18毛片免费| 亚洲国产av无码精品| 亚洲熟妇无码久久精品| 特级毛片A级毛片免费播放| 日日麻批免费40分钟无码| 国产青草视频免费观看97| 亚洲AV无码一区二区乱子伦| 亚洲人成电影网站色www| 野花香高清视频在线观看免费 | 24小时日本在线www免费的| 亚洲一区二区精品视频| 亚洲一区在线免费观看| 国产免费区在线观看十分钟| 中文字幕av无码无卡免费| 亚洲精品无码永久中文字幕| 亚洲欧美一区二区三区日产| 永久在线观看免费视频| 国产大片91精品免费看3| 亚洲高清日韩精品第一区| 大片免费观看92在线视频线视频 | 亚洲国产天堂久久综合|