兩畝三分地

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            17 隨筆 :: 20 文章 :: 2 評論 :: 0 Trackbacks

          2009年9月30日 #

               摘要: 之前項目有個模塊要求用樹形解決,附帶要實現checkbox,增刪修改以及copy/cut/paste等等功能; 因為之前寫的人用了xloadTree,其他功能都實現了,但是客戶要求要有cookie功能,實現不了麻煩啊~ 正巧現在在學習用Ext,發現Ext的tree本身就很強大基本的功能都可以實現。 Code highlighting produced by Actipro Cod...  閱讀全文
          posted @ 2010-08-08 23:17 Chucky 閱讀(1963) | 評論 (0)編輯 收藏

          Border布局作為Ext中整個框架的布局應該說很普遍,一般North放一個應用的Logo bar,West一般會作為導航欄的放置位置;
          而Center(East)往往作為整個應用的核心部分,而South位置也往往放置一些應用的版權等信息。

          而導航欄一般會采用的呈現方式一般無非是Treepanel或者根據模塊放置多個Panel,而多數會采用的布局方式,往往是
          Accordion的布局。比如像這樣(偷個懶直接用設計器寫的):
          MyViewportUi = Ext.extend(Ext.Viewport, {
              layout: 'border',
              initComponent: 
          function() {
                  
          this.items = [
                      {
                          xtype: 'panel',
                          title: 'north',
                          region: 'north'
                      },
                      {
                          xtype: 'panel',
                          title: 'west',
                          region: 'west',
                          width: 
          201,
                          split: 
          true,
                          layout: 'accordion',
                          activeItem: 
          0,
                          items: [
                              {
                                  xtype: 'panel',
                                  title: 'panel1',
                                  layout: 'column',
                                  width: 
          180,
                                  items: [
                                      {
                                          xtype: 'button',
                                          text: 'Button1',
                                          scale: 'large'
                                      },
                                      {
                                          xtype: 'button',
                                          text: 'Button2',
                                          scale: 'large'
                                      },
                                      {
                                          xtype: 'button',
                                          text: 'Button3',
                                          scale: 'large'
                                      },
                                      {
                                          xtype: 'button',
                                          text: 'Button4',
                                          scale: 'large'
                                      },
                                      {
                                          xtype: 'button',
                                          text: 'Button5',
                                          scale: 'large'
                                      },
                                      {
                                          xtype: 'button',
                                          text: 'Button6',
                                          scale: 'large'
                                      }
                                  ]
                              },
                              {
                                  xtype: 'panel',
                                  title: 'panel2'
                              },
                              {
                                  xtype: 'panel',
                                  title: 'panel3'
                              }
                          ]
                      },
                      {
                          xtype: 'panel',
                          title: 'east',
                          region: 'center'
                      },
                      {
                          xtype: 'panel',
                          title: 'south',
                          region: 'south'
                      }
                  ];
                  MyViewportUi.superclass.initComponent.call(
          this);
              }
          });
          一個基本的框架就產生了,而問題也隨之而來。最主要的問題是IE和FF顯示不一樣。應該說FF顯示很正常,按鍵根據導航欄的大小,改變每一行顯示的數量;
          而IE呢,在第一次導航欄寬帶變大的時候,一切正常;而當導航欄寬度縮小的時候,原來每行的按鍵數卻并不變。想想這Ext都3.2了,不會還有這么腦殘的bug吧;
          google了下,國內似乎對這個問題也沒有什么討論的;于是直接去官網的論壇問。

          最初別人的提議是,更改westPanel的屬性
          layout: {
              type: 'accordion',
              autoWidth: 
          false
          }
          等于禁止westPanel的子欄目自動變化寬度,試了如果westPanel的子欄目只有一個工作正常,但是如果多個的話,又悲劇了~

          因為每次只有1個子欄目的寬度在變化,所以產生這個問題也不足為奇了。

          最后某個網友提供了一個自己寫的補丁,問題解決了。
          Ext.layout.AccordionPatch = Ext.extend(Ext.layout.Accordion, {
              
              inactiveItems: [],
          //ADDED

              
          // private
              onLayout : function(ct, target){//ADDED
                  Ext.layout.AccordionPatch.superclass.onLayout.call(this, ct, target);
                  
          if(this.autoWidth === false) {
                      
          for(var i = 0; i < this.inactiveItems.length; i++) {
                          
          var item = this.inactiveItems[i];
                          item.setSize(target.getStyleSize());
                      }
                  }
              },
              
          // private
              beforeExpand : function(p, anim){//MODFIED
                  var ai = this.activeItem;
                  
          if(ai){
                      
          if(this.sequence){
                          
          delete this.activeItem;
                          ai.collapse({callback:
          function(){
                              p.expand(anim 
          || true);
                          }, scope: 
          this});
                          
          return false;
                      }
          else{
                          ai.collapse(
          this.animate);
                          
          if(this.autoWidth === false && this.inactiveItems.indexOf(ai) == -1)//*****
                              this.inactiveItems.push(ai);//*****
                      }
                  }
                  
          this.activeItem = p;
                  
          if(this.activeOnTop){
                      p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
                  }
                  
          if(this.autoWidth === false && this.inactiveItems.indexOf(this.activeItem) != -1)//*****
                      this.inactiveItems.remove(this.activeItem);//*****
                  this.layout();
              }
              
          });

          Ext.Container.LAYOUTS['accordionpatch'] 
          = Ext.layout.AccordionPatch; 
          配合補丁,westPanel的屬性也要有相應的變化
          layout: {
              type:
          'accordionpatch',
              autoWidth: false
          }




          posted @ 2010-08-07 13:24 Chucky 閱讀(324) | 評論 (0)編輯 收藏

               摘要: 發表,瀏覽,回復之后,我們將討論的是刪除和編輯留言。 因為這個只是一個簡單的留言板,沒有用戶認證之類繁瑣的事情,所以對于編輯和刪除留言,必須輸入 正確的id號和password;如果在發表或回復留言的時候沒有輸入密碼的話,就不能對留言進行編輯或者刪除。 這里將寫的EditAction class與之前的有所不同,extends org.apache.struts.actions.Dispat...  閱讀全文
          posted @ 2009-10-29 17:22 Chucky 閱讀(244) | 評論 (0)編輯 收藏

          整個項目第二個重點就是回復留言,我的思路是在瀏覽留言的時候,回復鍵傳送主題的ID,一個Action Class處理這個請求,
          將與這個ID相關的留言查詢出來,寫入ActionForm。
          1. 打開display.jsp文件,找到下面這幾行,后面添加一個form,用來提交查詢請求。
             1 <table>
             2     <tr>
             3         <td>
             4             <bean:write name="topic" property="post.subject"/> 留言者:<bean:write name="topic" property="post.name" /> 留言日:<bean:write name="topic" property="post.date" format="yyyy/MM/dd(E) HH:mm" />  No.<bean:write name="topic" property="post.id" />
             5         </td>
             6         <td>
             7             <html:form action="read">
             8                 <input type="hidden" name="id" value="<bean:write name='topic' property='post.id'/>"/>
             9               <html:submit value="回復" />
            10             </html:form>
            11       </td>
            12    </tr>
            13   </table>
            6-11行,就是新加入的對id的一個請求,這里我用了普通的html標志來提交請求,當然我們也可以用<html:hidden name="topic" property="post.id"/>,但是在處理請求的時候,相對的request.getParameter("id"),就要換成
            request.getParameter("post.id")了;或者我們可以在那個Topic類里,添加一個id字段,那么在瀏覽留言的時候(ListAction的execute方法,list.add(new Topic(post,replies)); 改成list.add(new Topic(post,replies,post.getId()));)<html:hidden name="topic" property="id"/>也可以這樣用了。

          2. 添加一個ActionForm bean ThreadForm.java,除了記錄一段留言外,還包括了行將用以回復的留言的預處理;
             1 public class ThreadForm extends org.apache.struts.action.ActionForm {
             2     
             3     private int id;
             4     private String name;
             5     private String subject;
             6     private String content;
             7     private String url;
             8     private String email;
             9     private int iconId;
            10     private String icon;
            11     private String password;
            12     private int replyId;
            13     private String font;
            14 
            15     private List icons;
            16 
            17     private Topic topic;
            18 
            19     // accessor methods..
            20     
            21 
            22     public ThreadForm() {
            23         super();
            24         // TODO Auto-generated constructor stub
            25         setUrl("http://");
            26         setFont("#800000");
            27         String sql = "select id,name,src from icon order by id";
            28         QueryRunner qr = DbHelper.getQueryRunner();
            29         List list = null;
            30         try {
            31             list = (List) qr.query(sql, new BeanListHandler(Icon.class));
            32             // TODO Auto-generated constructor stub
            33         } catch (SQLException ex) {
            34             Logger.getLogger(ThreadForm.class.getName()).log(Level.SEVERE, null, ex);
            35         }
            36         setIcons(list);
            37     }
            38     
            39   
            40 }
            41
            3-15行是負責對回復的預處理,ThreadForm()方法中主要也是處理圖標。

          3. 這個回復過程其實是2部,1.預處理:包括列出與ID相關的留言,預設回復的默認標題以及對應的回復id (replyId);2.回復留言,添加記錄。
            a.  PreReplyAction.java
            public class PreReplyAction extends org.apache.struts.action.Action {
                
                
            /* forward name="success" path="" */
                
            private static final String SUCCESS = "bbs.read";
                
                
            /**
                 * This is the action called from the Struts framework.
                 * 
            @param mapping The ActionMapping used to select this instance.
                 * 
            @param form The optional ActionForm bean for this request.
                 * 
            @param request The HTTP Request we are processing.
                 * 
            @param response The HTTP Response we are processing.
                 * 
            @throws java.lang.Exception
                 * 
            @return
                 
            */
                @Override
                
            public ActionForward execute(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response)
                       {
                    ThreadForm f 
            = (ThreadForm) form;
                    String id 
            = (String) request.getParameter("id");
                    String sql;
                    QueryRunner qr 
            = DbHelper.getQueryRunner();
                    
                    List list 
            = null;
                    sql 
            = "select * from guestbook where id = " + id;
                    
            try {
                        list 
            = (List) qr.query(sql, new BeanListHandler(Post.class));
                    } 
            catch (SQLException ex) {
                        Logger.getLogger(PreReplyAction.
            class.getName()).log(Level.SEVERE, null, ex);
                    }
                    Post post 
            = null;
                    post 
            = (Post)list.get(0);
                    List replies 
            = null;
                    sql 
            = "select * from guestbook where replyId =" + id + " order by id";
                    
            try {
                        replies 
            = (List) qr.query(sql, new BeanListHandler(Post.class));
                    } 
            catch (SQLException ex) {
                        Logger.getLogger(PreReplyAction.
            class.getName()).log(Level.SEVERE, null, ex);
                    }
                    
                    Topic topic 
            = new Topic(post,replies);
                    f.setTopic(topic);
                    f.setSubject(
            "Re :" + post.getSubject());
                    f.setReplyId(post.getId());

                    
            return mapping.findForward(SUCCESS);
                }
            }

            b. ReplyAction.java
             1 public class ReplyAction extends org.apache.struts.action.Action {
             2     
             3     /* forward name="success" path="" */
             4     private static final String SUCCESS = "bbs.reply";
             5     
             6     /**
             7      * This is the action called from the Struts framework.
             8      * @param mapping The ActionMapping used to select this instance.
             9      * @param form The optional ActionForm bean for this request.
            10      * @param request The HTTP Request we are processing.
            11      * @param response The HTTP Response we are processing.
            12      * @throws java.lang.Exception
            13      * @return
            14      */
            15     @Override
            16     public ActionForward execute(ActionMapping mapping, ActionForm form,
            17             HttpServletRequest request, HttpServletResponse response)
            18             throws Exception {
            19         ThreadForm f = (ThreadForm)form;
            20         String sql = "insert into guestbook (name,subject,email,url,content,iconId,password,font,replyId,date,lastReplyTime) " +
            21                 "values(?,?,?,?,?,?,?,?,?,now(),now())";
            22         String content = f.getContent();
            23         content = content.replaceAll(" ""&nbsp;");
            24         content = content.replaceAll("\n","<br>");
            25         String params[] = {f.getName(),f.getSubject(),f.getEmail(),f.getUrl(),content,new Integer(f.getIconId()).toString(),f.getPassword(),f.getFont(),new Integer(f.getReplyId()).toString()};
            26 
            27         QueryRunner qr = DbHelper.getQueryRunner();
            28         try {
            29             qr.update(sql, params);
            30         } catch (SQLException ex) {
            31             Logger.getLogger(ReplyAction.class.getName()).log(Level.SEVERE, null, ex);
            32         }
            33        sql = "update guestbook set lastReplyTime= now() where id = " + f.getReplyId();
            34         try {
            35             qr.update(sql);
            36         } catch (SQLException ex) {
            37             Logger.getLogger(ReplyAction.class.getName()).log(Level.SEVERE, null, ex);
            38         }
            39         return mapping.findForward(SUCCESS);
            40     }
            41 }
            這個基本和添加留言的一直,只是在insert回復記錄以后,更新主題留言的最近的回復時間,可以保證瀏覽留言的時候,該主題能在最前端。

          4. reply.jsp 基本和之前寫的jsp頁面區別不大,省略了。

          5. 添加相應的forwarding信息。
            <global-forwards>
                    
            <forward name="bbs.post" path="/result.jsp"/>
                    
            <forward name="bbs.list" path="/display.jsp"/>
                    
            <forward name="bbs.read" path="/reply.jsp" />
                    
            <forward name="bbs.reply" path="/list.do" />
                    
            <forward name="welcome"  path="/Welcome.do"/>
            </global-forwards>
            根據forward的指向,我們可以看到在reply.jsp按下回復鍵以后,直接轉向list.do動作。
            至于action-mapping 沒有什么要注意的。

          6. 整個回復過程就此完成。

          posted @ 2009-10-28 13:14 Chucky 閱讀(353) | 評論 (0)編輯 收藏

               摘要: 既然我們已經成功完成了第一個ActionForm Bean和與之相關的Action Class;后面的專題中將不再詳細的去寫與他們相關的開發步驟了。 現在我們開始寫留言板的主體部分,即對整個留言就行瀏覽。因為每個post都有一個replyId字段,用來對應其所回復的留言id;如果這個 replyId等于-1的話,即該留言沒有對應的回復。好了還是先從這個JSP頁面寫起。 displ...  閱讀全文
          posted @ 2009-10-23 17:40 Chucky 閱讀(279) | 評論 (0)編輯 收藏

          PostAction主要是處理留言添加工作。
          1. 和創建NewForm bean一樣,點擊Source Packages > com.bbs.struts,右鍵New > Java Package... 創建一個com.bbs.struts.action的package用于存放所有action類;

          2. 右鍵com.bbs.struts.action, New > Struts Action...如果New菜單里沒有的話,選擇other...,categories里選擇
            Struts,File types一欄里選擇Struts Action ...;

          3. 在New Struts Action面板里面,Class Name填PostAction;Action Path 填/post;按Next


          4. 按照下面的設置,完成對Action的設置


          5. 在struts-config.xml的文檔中,IDE自動添加了對PostForm的聲明。
            <action-mappings>
                    
            <action input="/post.jsp" name="NewForm" path="/post" scope="request" type="com.bbs.struts.action.PostAction"/>
                    
            <action path="/Welcome" forward="/welcomeStruts.jsp"/>
            </action-mappings>

          6. 右邊的Source Editor中,新建的PostAction.java已經打開了;接下來我們要把記錄在NewForm bean里的數據保存進數據庫,為了測試的需要,在添加數據以后,將添加成功與否的結果顯示在result.jsp上面。
             1     public ActionForward execute(ActionMapping mapping, ActionForm form,
             2             HttpServletRequest request, HttpServletResponse response) {
             3         NewForm f = (NewForm) form;
             4         String sql = "insert into guestbook (name,subject,email,url,content,iconId,password,font,replyId,date,lastReplyTime) " +
             5                 " values(?,?,?,?,?,?,?,?,-1,now(),now())";
             6 
             7         String content = f.getContent();
             8         content = content.replaceAll(" ""&nbsp;");
             9         content = content.replaceAll("\n""<br>");
            10 
            11         String params[] = {f.getName(), f.getSubject(), f.getEmail(), f.getUrl(), content, new Integer(f.getIconId()).toString(), f.getPassword(), f.getFont()};
            12 
            13         QueryRunner qr = DbHelper.getQueryRunner();
            14 
            15         String result = null;
            16         try {
            17             if (qr.update(sql, params) == 1){
            18                 result = "更新成功";
            19             }else{
            20                 result = "更新失敗";
            21             }
            22         } catch (SQLException ex) {
            23             Logger.getLogger(PostAction.class.getName()).log(Level.SEVERE, null, ex);
            24         }
            25         f.setResult(result);
            26         return mapping.findForward(SUCCESS);
            27     }
            7,8,9行主要是將content里的空格和回車符號轉成html中所對應的空格和回車。

          7. 在PostAction.java,IDE自動給我們設置了一個 private static final String SUCCESS = "success"; 這是為action forward所設置的forward標志,success的名稱我們可以自己取,比如我們可以把它改成bbs.post。關鍵是在結束對這個action class的編程以后,我們需要在struts-config.xml中添加forward聲明。在source editor中打開struts-config.xml,右鍵菜單Struts > Add Forward,在Add Forward的面板里如下設置,按Add完成添加。

          按F6 運行項目,瀏覽器輸入:http://localhost:8080/BBS/post.jsp對程序進行測試。如果添加成功的話,下一頁將有更新成功的字樣。
          posted @ 2009-10-23 00:31 Chucky 閱讀(452) | 評論 (0)編輯 收藏

          ActionForm Bean在Struts里用來保存網頁request傳遞之間的數據。比如我們現在寫的NewForm Bean用來收集表格內的信息,
          類似于servlet的request.getParamenter()的作用;當用戶提交以后,數據將保存在bean內,然后再做處理。
          1. 點擊Source Packages > com.bbs.struts,右鍵New > Java Package... 創建一個com.bbs.struts.form的package用于存放
            所有form;

          2. 右鍵com.bbs.struts.form, New > Struts ActionForm Bean...如果New菜單里沒有的話,選擇other...,categories里選擇
            Struts,File types一欄里選擇Struts ActionForm Bean...;

          3. 為這個ActionForm取名叫NewForm,然后按Finish完成。
            IDE將創建一個NewForm bean,并在右邊的Source Editor里面打開它。默認的話,IDE將創造2個一個String型的name和int型的number,2個屬性;并且定義了它們的accessor方法。另外IDE將在struts-config.xml里面,添加對這個bean的聲明;
            <form-beans>
                    
            <form-bean name="NewForm" type="com.bbs.struts.form.NewForm"/>
            </form-beans>

          4. 在Source Editor里面,將原來的name,number字段刪除,并刪除與之相關的accessor方法。然后為NewForm添加以下字段,這些字段與之前的post.jsp所用到的字段一一對應。
                private String name;
                
            private String subject;
                
            private String content;
                
            private String url;
                
            private String email;
                
            private int iconId;
                
            private String password;
                
            private String font;

                
            private List icons;
                
            private String result;
            利用insert code...功能,添加相應的accessor方法。

          5. 考慮到因為圖標的列其實在生成這個網頁的時候就自動添加的,所以在這個ActionForm bean的Constructor的方法里面,就要處理icon了,還有就是對字色,網絡鏈接做一下預處理:
                public NewForm() {
                    
            super();
                    
            // TODO Auto-generated constructor stub
                    setUrl("http://");
                    setFont(
            "#800000");
                    String sql 
            = "select id,name,src from icon order by id";
                    QueryRunner qr 
            = DbHelper.getQueryRunner();
                    List list 
            = null;
                    
            try {
                        list 
            = (List) qr.query(sql, new BeanListHandler(Icon.class));
                        
            // TODO Auto-generated constructor stub
                    } catch (SQLException ex) {
                        Logger.getLogger(NewForm.
            class.getName()).log(Level.SEVERE, null, ex);
                    }
                    setIcons(list);
                }

          6. 同樣在validate方法里,添加對subject驗證,如果subject為空的話,改名“無題”。
               public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
                    ActionErrors errors 
            = new ActionErrors();

                    
            if (getSubject() == null || getSubject().length() < 1) {
                        setSubject(
            "無題");
                    }
                    
            return errors;
                }

          7. 第一個ActionForm Bean就完成了。

          posted @ 2009-10-22 23:15 Chucky 閱讀(234) | 評論 (0)編輯 收藏


          之前的準備工作完成,現在算是正式進入struts項目的環節了,首先我們寫一個發表留言的jsp頁面。
          1. 右鍵點擊BBS項目, 選擇 New > JSP, 命名新文件為post. 點擊Finish. post.jsp將在右邊的編輯器里打開了。

          2. 首先在編輯器中,將<title></title>中間的文字改成發表留言。

          3. 在文件頂部,添加以下2個taglib:
            <%@taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
            <%@taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
            bean tag為用戶提供了若干tag,主要針對表單中form bean;html tag用來代替普通的html標簽,達到簡化操作的目的。

          4. 在<body>里面添加:
            <html:form action="post">

            </html:form>

          5. 從IDE的Palette面板的HTML的分類里將Table拉入<html:form action="post">之間,設置rows 8, columns 2。

          6. 在<td>之間添加數值
            <html:form action="post">
                        
            <table border="1">
                            
            <tbody>
                                
            <tr>
                                    
            <td>名字</td>
                                    
            <td><html:text property="name" /></d>
                                
            </tr>
                                
            <tr>
                                    
            <td>郵件</td>
                                    
            <td><html:text property="email" /></td>
                                
            </tr>
                                
            <tr>
                                    
            <td>題目</td>
                                    
            <td><html:text property="subject" /> <html:submit value="發送"/><html:cancel value="重置"/></td>
                                
            </tr>
                                
            <tr>
                                    
            <td colspan="2">正文<br>
                                        
            <html:textarea cols="60" rows="8" property="content" />
                                    
            </td>
                                
            </tr>
                                
            <tr>
                                    
            <td>網站</td>
                                    
            <td><html:text property="url"/></td>
                                
            </tr>
                                
            <tr>
                                    
            <td>圖標</td>
                                    
            <td>
                                        
            <html:select property="iconId">
                                            
            <logic:iterate id="icon" name="NewForm" property="icons">
                                             
            <option value="<bean:write name='icon' property='id'/>"><bean:write name="icon" property="name"/></option>
                                            
            </logic:iterate>
                                        
            </html:select>
                                    
            </td>
                                
            </tr>
                                
            <tr>
                                    
            <td>密碼</td>
                                    
            <td><html:password property="password"/>(英數8文字內)</td>
                                
            </tr>
                                
            <tr>
                                    
            <td>字色</td>
                                    
            <td>
                                        
            <html:radio property="font" value="#800000"><font color="#800000"></font></html:radio>
                                        
            <html:radio property="font" value="#DF0000"><font color="#DF0000"></font></html:radio>
                                        
            <html:radio property="font" value="#008040"><font color="#008040"></font></html:radio>
                                        
            <html:radio property="font" value="#0000FF"><font color="#0000FF"></font></html:radio>
                                        
            <html:radio property="font" value="#C100C1"><font color="#C100C1"></font></html:radio>
                                        
            <html:radio property="font" value="#FF80C0"><font color="#FF80C0"></font></html:radio>
                                        
            <html:radio property="font" value="#FF8040"><font color="#FF8040"></font></html:radio>
                                        
            <html:radio property="font" value="#000080"><font color="#000080"></font></html:radio>
                                    
            </td>
                                
            </tr>
                            
            </tbody>
                        
            </table>
                    
            </html:form>
                
            </body>

            第一個JSP頁面就完成了。
          考慮到后面的測試,再創建一個result.jsp頁面;當post成功/失敗的話,通過result.jsp來查看結果
          <%@page contentType="text/html" pageEncoding="UTF-8"%>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
             "http://www.w3.org/TR/html4/loose.dtd"
          >
          <%@taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
          <html>
              
          <head>
                  
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
                  
          <title>留言板</title>
              
          </head>
              
          <body>
                  
          <h1><bean:write name="NewForm" property="result" /></h1>
              
          </body>
          </html>



          posted @ 2009-10-21 18:20 Chucky 閱讀(233) | 評論 (0)編輯 收藏

          正如之前所說的,開發一個struts應用和一般的web應用并沒有什么兩樣。

          1. 創建數據庫
          create database guestbook;

          a. guestbook表:用于記錄留言的所有信息
          CREATE TABLE `guestbook` (
          `id`  
          int(11NOT NULL AUTO_INCREMENT ,
          `name`  
          varchar(40) ,
          `email`  
          varchar(60),
          `url`  
          varchar(60),
          `subject`  
          varchar(200),
          `content`  
          varchar(1024),
          `font`  
          varchar(100),
          `date`  
          datetime ,
          `replyId`  
          int(11)DEFAULT '-1' ,
          `iconId`  
          int(3),
          `lastReplyTime`  
          datetime ,
          `password`  
          varchar(16),
          PRIMARY KEY (`id`)
          );

           字段 說明
           id  留言編號
           name  留言人姓名
           email  email地址
           url  url地址
           subject  留言標題
           content  留言內容
           iconId  留言使用的表情圖標編號
           font  內容字體顏色
           date  留言時間
           replyId  回復留言ID,默認為-1表示不是回復
           lastReplyTime  最近回復時間
           password  留言所用的密碼(用于編輯)

          b. ICON表:用于記錄所有的圖標記錄
          CREATE TABLE `icon` (
          `id`  
          int(11NOT NULL AUTO_INCREMENT ,
          `name`  
          varchar(20),
          `src`  
          varchar(200),
          `alt`  
          varchar(100),
          PRIMARY KEY (`id`)
          );

           字段 說明
           id  圖標編號
           name  圖標名稱
           src  圖標的位置
           alt  圖標的說明

          2. JDBC Resource與鏈接池
          • 給剛剛建的database建立一個連接,Services標簽,點擊Databases的MySql Server at localhost:3306;
          • 選擇剛剛建的guestbook,按右鍵點擊connect;我們可以看到在databases的列表里多了jdbc:mysql://localhost:3306/guestbook的鏈接;
          • 回到projects標簽,點擊項目名稱BBS,按右鍵選擇New > Other... 在Categories里面選擇GlassFish;File types項目下面,選擇JDBC Connection Pool,按Next;
          • 在New JDBC Connection Pool面板里,JDBC Connection Pool Name里輸入GuestBookPool(隨意),Extract from Existiong Connection的下拉菜單里選擇剛剛建立的database連接jdbc:mysql://localhost:3306/guestbook,
            其他設置使用默認值即可,按finish結束連接池的創建。
          • 同樣在Categories里面選擇GlassFish;File types項目下面,選擇JDBC Resource,按Next;
          • 在New JDBC Resource面板里,Using Existing JDBC Connection Pool里選擇GuestBookPool(與之前創建的連接池對應);
            JNDI Name輸入jdbc/bbs(隨意),按finish,完成JDBC Resource配置。
          3.中文亂碼處理 
            記得在做上一個Servlet的項目的時候,在每個servlet處理request的時候(processRequest()方法),都做過一個request.setCharacterEncoding("UTF-8")的操作;將request的內容轉成UTF-8的內碼,以解決中文亂碼問題。
            在Struts的項目里面,我們仍然會遇到中文亂碼問題。而我們通過一個創建的CharacterEncodingFilter的輔助類來解決問題。
          •   CharacterEncodingFilter.java
            package com.bbs.struts.util;

            import java.io.IOException;
            import javax.servlet.Filter;
            import javax.servlet.FilterChain;
            import javax.servlet.FilterConfig;
            import javax.servlet.ServletException;
            import javax.servlet.ServletRequest;
            import javax.servlet.ServletResponse;

            /**
             *
             * 
            @author Chucky
             
            */
            public class CharacterEncodingFilter implements Filter {

                
            public void init(FilterConfig filterConfig) throws ServletException {
                }

                
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                    request.setCharacterEncoding(
            "UTF-8");
                    chain.doFilter(request, response);
                }

                
            public void destroy() {

                }

            }
             
          • 打開web.xml,在Filters的面板中添加以下內容
          中文亂碼的問題解決了!

          4. DbUtils
          在處理數據連接的問題上,還是使用DbUtils這個類,詳細請看Blog系統開發 5. JDBC的基本操作與DbUtils的使用 內容
          這里還是寫一個DbHelper的輔助類,來簡化連接的操作。
          DbHelper.java
          package com.bbs.struts.util;

          import java.util.logging.Level;
          import java.util.logging.Logger;
          import javax.naming.Context;
          import javax.naming.InitialContext;
          import javax.naming.NamingException;
          import javax.sql.DataSource;
          import org.apache.commons.dbutils.QueryRunner;

          /**
           *
           * 
          @author Chucky
           
          */
          public class DbHelper {

              
          public static QueryRunner getQueryRunner() {
                  Context context 
          = null;
                  DataSource ds 
          = null;
                  
          try {
                      context 
          = new InitialContext();
                      ds 
          = (DataSource) context.lookup("jdbc/bbs");
                  } 
          catch (NamingException ex) {
                      Logger.getLogger(DbHelper.
          class.getName()).log(Level.SEVERE, null, ex);
                  }

                  QueryRunner qr 
          = new QueryRunner(ds);
                  
          return qr;
              }
          }
          注意context.lookup()中的數據源,要與之前的數據源匹配。

          因為這個bbs的網頁設計是按照日月星辰的留言板的頁面制作的,所以類似icon之類的數據,直接添加到數據庫(假設所有的icon都在
          img 目錄下,icon素材可以直接到星辰去抓的,sql的腳本)


          posted @ 2009-10-21 17:31 Chucky 閱讀(441) | 評論 (0)編輯 收藏

          根據之前所建立的guestbook表和icon表;現在我們建立Icon類和Post類;
          1. Icon類 Icon.java
          public class Icon {
              
          private int id;
              
          private String name;
              
          private String src;
              
          private String alt;
          }
          在Icon.java的Source Editor上按右鍵,點擊Insert Code... 選擇Getter and Setter...;
          在Generate Getter and Setter面板內,選擇所有的屬性;IDE將自動生成setter/getter方法。

          同樣建立一個Post類,除了原來guestbook里的字段以外,為了編程的方便再添加一個Icon的屬性,相當于Icon類里的src值。
          public class Post{
              private
           int id;
              
          private String name;
              
          private String subject;
              
          private String content;
              
          private String url;
              
          private String email;
              
          private int iconId;
              
          private String icon;
              
          private String password;
              
          private Date date;
              
          private Date lastReplyTime;
              
          private int replyId;
              
          private String font;
          }
          添加相應的getter/setter方法。

          除了以上2個類,再建一個Topic類,這個類是一個post和它所有回復的一個集合。
          public class Topic {
              
          private Post post;
              
          private List replies;
          }
          添加相應的getter/setter方法。




          posted @ 2009-10-21 17:05 Chucky 閱讀(228) | 評論 (0)編輯 收藏

          在使用Netbeans的時候,除了Struts應用所需需要的Struts庫文件與配置文件以外,創建一個Struts應用與
          創建其他任何一個網絡應用沒有什么區別。其實創建一個Struts應用的方法和任何一個其他網絡應用的方法
          都一樣。
          • 選擇File > New Project. 在Categories里面選擇Web。Projects項目下面,選擇Web Application然后按Next。
          • 在輸入項目名稱和位置的面板里面,輸入BBS作為項目名稱,然后按Next;
          • 在服務器與設置面板里面,選擇選擇一個你準備用來deploy應用的服務器(如:GlassFish v2.1),同時注意面板下方的
            Context Path的路徑與我們的項目名稱一致,按Next;
          • 在Framework面板里,選擇Struts

            將Application Resource里的名稱com.myapp.struts.ApplicationResource改成com.bbs.struts.ApplicationResource .
          • 按下Finish,Struts的一個應用就建立完成了。
          在項目管理器里面,所有的Struts指定的配置文件以及應用deploy所用的文件,都被放置在Configuration Files的目錄里。
          打開web.xml,我們可以看一下文件是如何管理Struts的。
          <?xml version="1.0" encoding="UTF-8"?>
          <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation
          ="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
              
          <servlet>
                  
          <servlet-name>action</servlet-name>
                  
          <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
                  
          <init-param>
                      
          <param-name>config</param-name>
                      
          <param-value>/WEB-INF/struts-config.xml</param-value>
                  
          </init-param>
                  
          <init-param>
                      
          <param-name>debug</param-name>
                      
          <param-value>2</param-value>
                  
          </init-param>
                  
          <init-param>
                      
          <param-name>detail</param-name>
                      
          <param-value>2</param-value>
                  
          </init-param>
                  
          <load-on-startup>2</load-on-startup>
                  
          </servlet>
              
          <servlet-mapping>
                  
          <servlet-name>action</servlet-name>
                  
          <url-pattern>*.do</url-pattern>
              
          </servlet-mapping>
              
          <session-config>
                  
          <session-timeout>
                      30
                  
          </session-timeout>
              
          </session-config>
              
          <welcome-file-list>
                  
          <welcome-file>index.jsp</welcome-file>
                  
          </welcome-file-list>
              
          </web-app>

          posted @ 2009-10-20 18:07 Chucky 閱讀(205) | 評論 (0)編輯 收藏

          到16節 和項目相關的東西,覺得已經沒什么要寫的了;基本還剩下一些css之類的頁面設計和美化工作。
          這方面沒有什么感覺,總之把跟這個項目相關的東西放在一起(src和web相關的東西);有興趣可以下來看看。
          blog_servlet

          Ok 跟blog_servlet相關的東西到這里結束了,下周開始做blog Struts相關的項目。

          posted @ 2009-10-08 19:04 Chucky 閱讀(112) | 評論 (0)編輯 收藏

               摘要: 對于表格數據處理的話,displayTag有很大的優勢;但是有些時候還得自己動手做點工作; 我自己寫了一個PageTag的類來處理一些簡單的工作。 PageTag.java Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->&n...  閱讀全文
          posted @ 2009-10-07 18:58 Chucky 閱讀(247) | 評論 (0)編輯 收藏

               摘要: 上一節談了displaytag的基本用法,這一節就結合項目來看一下。按照常理,可能使用到displaytag的地方, 集中在管理頁面里,譬如對博文的管理或者是針對comments的管理;相對而言category似乎并不需要使用分頁; 很少會有人開幾十個不同的分類吧 XD。 好吧,我們來比較一下,displaytag和原來的代碼有什么不同。 這是原先的頁面 網頁的code: ...  閱讀全文
          posted @ 2009-10-07 16:37 Chucky 閱讀(213) | 評論 (0)編輯 收藏

          隨著博文的增加或者評論的增加,是必要考慮一下分頁問題。
          在這個項目里,對于分頁問題,我采取2種處理的方法。對于管理頁面表格型的記錄采用displayTag組件;
          而對于那些博文或者評論采用自己寫的PageTags類來管理。

          1. displayTag組件

          上面的圖片可以看出:事實上這個display tag庫就是用來顯示表格的;給它一個對象的list,它將搞定類似顯示列,排序,分頁等等事務,并以表格的形式顯示出來。

          a. 安裝:
             將displaytag-version.jar 文件與以下5個文件一起放置在應用的WEB-INF/lib目錄里
          • commons-logging
          • commons-lang
          • commons-collections
          • commons-beanutils
          • log4j
             在使用的時候,在jps頁面中,
          <%@ taglib uri="http://displaytag.sf.net" prefix="display" %>

          b. 使用:
             這里使用blog列表做例子
           <% List blogs = (List) request.getAttribute("blogs");%>
              
          <h2>文章管理</h2>
          <display:table name="blogs" htmlId="tab" pagesize="10" />
          每頁顯示10條記錄

          對于每條記錄我們可能有顯示要求
          <display:table name="blogs" id=" blog" htmlId="tab" pagesize="10" >
              
          <display:column property="id" title="編號"/>
              
          <display:column property="title" title="主題"/>
              
          <display:column property="category" title="類別"/>
              
          <display:column property="date" format="{0,date,yyyy-MM-dd  HH:mm:ss}" title="日期",sortable="true"/>
              
          <display:column title="操作">
                  
          <href="/Blogs/BlogServlet?method=edit&id=${blog.id}"><img src="/Blogs/admin/img/edit.gif" border=0 /></a>
                          
          <href="/Blogs/BlogServlet?method=delete&id=${blog.id}" onclick="javascript:return del()"><img src="/Blogs/admin/img/delete.gif" border=0 /></a>|
                          
          <href="/Blogs/CommentServlet?method=list&bid=${blog.id}">管理評論</td> 
              
          </display:column>
              
          </display:table>
          比如id字段顯示為 標號;title主題;category類別;日期么安裝年-月-日 小時:分鐘:秒的格式顯示;并且可以手動選擇排序。
          是不是很簡單。

          c.其他問題:
            配置文件displaytag.properties,需要放置在src目錄的根部,主要顯示一些文字之類的設置,支持localization,但是要注意的是,文件必須轉換成unicode才可以正常顯著。
          以下是displaytag_Zh_CN.properties的示例:
           1 #sort.behavior=list
           2 #sort.amount=list
           3 #basic.empty.showtable=true
           4 #basic.msg.empty_list=No results matched your criteria.
           5 #paging.banner.placement=top
           6 #paging.banner.onepage=<span class="pagelinks"></span>
           7 export.types=csv excel xml pdf rtf
           8 export.excel=true
           9 export.csv=true
          10 export.xml=true
          11 export.pdf=true
          12 export.rtf=true
          13 export.excel.class=org.displaytag.export.excel.DefaultHssfExportView
          14 export.pdf.class=org.displaytag.export.DefaultPdfExportView
          15 export.rtf.class=org.displaytag.export.DefaultRtfExportView
          16 # if set, file is downloaded instead of opened in the browser window
          17 #export.[mymedia].filename=
          18 paging.banner.placement=bottom
          19 # messages
          20 
          21 basic.msg.empty_list=\u6CA1\u6709\u7B26\u5408\u6761\u4EF6\u7684\u8BB0\u5F55
          22 basic.msg.empty_list_row=<tr class="empty"><td colspan="{0}">\u6CA1\u6709\u7B26\u5408\u6761\u4EF6\u7684\u8BB0\u5F55</td></tr>
          23 error.msg.invalid_page=\u65E0\u6548\u9875\u9762
          24 
          25 export.banner=<div class="exportlinks">Export options: {0}</div>
          26 export.banner.sepchar= |
          27 
          28 paging.banner.item_name=
          29 paging.banner.items_name=
          30 
          31 paging.banner.no_items_found=
          32 paging.banner.one_item_found=
          33 paging.banner.all_items_found=
          34 paging.banner.some_items_found=
          35 
          36 paging.banner.full=<span class="pagelinks"><font align>[<a href="{1}">|<</a>/<a href="{2}"><</a>] {0[<a href="{3}">></a>/<a href="{4}">>|</a>]</span>
          37 paging.banner.first=<span class="pagelinks">[\u9996\u9875/\u4E0A\u4E00\u9875] {0[<a href="{3}">\u4E0B\u4E00\u9875</a>/<a href="{4}">\u5C3E\u9875</a>]</span>
          38 paging.banner.last=<span class="pagelinks">[<a href="{1}">\u9996\u9875</a>/<a href="{2}">\u4E0A\u4E00\u9875</a>] {0[\u4E0B\u4E00\u9875/\u5C3E\u9875]</span>
          39 paging.banner.onepage=<span class="pagelinks">{0}</span>
          40 
          41 paging.banner.page.selected=<strong>{0}</strong>
          42 paging.banner.page.link=<a href="{1}" title="{0}">{0}</a>
          43 paging.banner.page.separator=, \
          38行paging.banner.placement=bottom 指定分頁欄出現在表格的下面,當然還有top/both兩個選擇。
            
           

          posted @ 2009-10-05 17:07 Chucky 閱讀(269) | 評論 (0)編輯 收藏

          到11節基本的東西都已經實現了,剩下的都是一點細節問題;比如由于注冊用戶和普通瀏覽用戶權限不同,所以大家看的也有所不同;
          在項目設計的時候,普通用戶可以看博客,發表評論;為了避免不必要的麻煩,將普通用戶的操作特別的寫一個servlet,這樣也比較容易控制。
          HomeServlet主要就是負責這個任務。
          在HomeServlet里面主要就是兩個方法,為了配合以后的頁面設計,相對之前的BlogServlet等等,相對復雜一點(其實還好)。

          讓我們來看看這個Sql語句的作用
          sql= select b.id as id,b.title as title,b.content as content,b.date as date,c.name as category,categoryId,comments from
          (
          select blog.id as id ,blog.title as title,blog.category_id as categoryId,count(comment.blog_id) as comments,blog.content as content,blog.date as date from blog
          left
           join comment on blog.id = comment.blog_id group by blog.id) as b, category c
          where categoryId = c.id
          order by date desc;
          首先
          select blog.id as id ,blog.title as title,blog.category_id as categoryId,count(comment.blog_id) as comments,blog.content as content,blog.date as date from blog
          left join comment on blog.id = comment.blog_id group by blog.id
          comment表中對blog_id一致的記錄做統計,與blog表左連接;
          然后再blog新表與category根據categoryId做連接。

          然后修改一下Blog類,添加一個comments屬性(記錄此blog對象所包含的評論數目)。

          2.對blog.content做下處理,在顯示所有博文的時候,對blog.content的內容做一個簡報。
          很簡單的一個getBriefContent()方法:
          public String getBriefContent() {
                  StringBuffer briefContent 
          = new StringBuffer(content);
                  
          int length = 200;
                  
          if (briefContent.length() < length) {
                      length 
          = briefContent.length();
                  }
                  briefContent 
          = briefContent.delete(length, briefContent.length());

                  
          //filter html mark;
                  briefContent.append(" ..");
                  
          return briefContent.toString();
              }
          限定200字符長度,如果博文內容多于200字符,那么取前200字符;否則直接貼上博文內容。

          3.對blog.content另一個修改。因為寫博文的時候,可能所選用的字體啊什么每次都不同,以至于在瀏覽所有博文的時候會很亂;
          所以以下doFilter(StringBuffer sb)方法,主要對文字進行過濾,將充滿HTML MARK的文章過濾一下。
          private StringBuffer doFilter(StringBuffer source) {
                  StringBuffer header 
          = new StringBuffer(source);
                  
          while((header.indexOf("<")!=-1)&&(header.indexOf(">")!=-1)){
                     
          int startPos = header.indexOf("<");
                     
          int endPos = header.indexOf(">");
                      header 
          = header.delete(startPos, endPos+1);
                  }
                  
          return header;
              }
          因此getBriefContent()方法也要插上一句(Line 3):
           1 public String getBriefContent() {
           2         StringBuffer briefContent = new StringBuffer(content);
           3         briefContent = doFilter(briefContent);
           4         int length = 200;
           5         if (briefContent.length() < length) {
           6             length = briefContent.length();
           7         }
           8         briefContent = briefContent.delete(length, briefContent.length());
           9 
          10         //filter html mark;
          11         briefContent.append(" ..");
          12         return briefContent.toString();
          13     }



          posted @ 2009-10-05 16:26 Chucky 閱讀(147) | 評論 (0)編輯 收藏

          我們大家都有使用博客或者其他類似系統的經驗,往往都是通過用戶驗證以后,才進行其他的操作。
          上一節,在處理完login事務以后,我們可以訪問某個頁面對自己的博文或者博文分類等等進行操作。
          但是由于網頁的關系,如果沒有對每頁進行用戶認證,而我們知道準確的地址的話,我們可以直接訪問地址來對數據進行操作。
          比如:
          http://localhost:8080/Blog/BlogServlet?method=list
          可以查看所有的博文;而
          http://localhost:8080/Blog/BlogServlet?method=delete&cid=1
          這個地址可以對編號為1的博文進行刪除操作。
          所以我們必須對每一頁或者沒一次操作進行用戶認證。因為user對象是放置在session中的,所有我們可以每次通過檢測session內容來達到驗證的效果。

          在這里,我寫了一個輔助類UserValidator,來簡化操作。
          package com.blog.utils;

          import com.blog.User;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpSession;

          /**
           *
           * 
          @author Chucky
           
          */
          public class UserValidator {
              
          public static boolean isValid(HttpServletRequest request){
                  HttpSession session 
          = request.getSession();
                  User user 
          = (User) session.getAttribute("user");
                  
          return user!=null?true:false;
              }
          }
          一般Servlet的里面,可以直接把UserValidator的檢驗直接放置在processRequest方法里,如果檢驗失敗的話,轉到用戶登錄界面
           1 protected void processRequest(HttpServletRequest request, HttpServletResponse response)
           2             throws ServletException, IOException {
           3         response.setContentType("text/html;charset=UTF-8");
           4         request.setCharacterEncoding("UTF-8");
           5 
           6         String method = request.getParameter("method");
           7 
           8         if (!UserValidator.isValid(request)) {
           9             response.sendRedirect(request.getContextPath()+"/admin/");
          10         } else {
          11             if (method.equals("add")) {
          12                 add(request, response);
          13             } else if (method.equals("delete")) {
          14                 delete(request, response);
          15             } else if (method.equals("edit")) {
          16                 preEdit(request, response);
          17             } else if (method.equals("update")) {
          18                 update(request, response);
          19             } else if (method.equals("list")) {
          20                 list(request, response);
          21             } else if (method.equals("get")) {
          22                 get(request, response);
          23             } else if (method.equals("preAdd")) {
          24                 preAdd(request, response);
          25             }
          26         }
          27     }
          而一些直接讀取的jsp頁面,也可以把驗證直接寫在頁面里。
          <% User user = (User)session.getAttribute("user");
             if (user == null){
             
          response.sendRedirect(request.getContextPath()+"/admin/");
             }
          %>


          posted @ 2009-09-30 16:47 Chucky 閱讀(217) | 評論 (0)編輯 收藏

          UserServlet主要用于用戶登錄,退出以及密碼修改方面的事務。鑒于對網絡應用的安全性考慮,
          所以user將被寫在session里面,用以在某些管理頁面達到認證作用。
           1 private void login(HttpServletRequest request, HttpServletResponse response)
           2             throws ServletException, IOException {
           3         String userName = request.getParameter("username");
           4         String password = request.getParameter("password");
           5         String sql = "select id,username,password from users where username = ? and password = ?";
           6         String params[] = {userName, password};
           7         List users = null;
           8 
           9         QueryRunner qr = DbHelper.getQueryRunner();
          10         try {
          11             users = (List) qr.query(sql, new BeanListHandler(User.class), params);
          12         } catch (SQLException ex) {
          13             Logger.getLogger(UserServlet.class.getName()).log(Level.SEVERE, null, ex);
          14         }
          15         if (users.size()!=0) {
          16             User user = (User) users.get(0);
          17             HttpSession session = request.getSession();
          18             session.setAttribute("user", user);
          19             response.sendRedirect(request.getContextPath()+"/BlogServlet?method=list");
          20         } else {
          21             request.setAttribute("message""錯誤的用戶名或密碼");
          22             request.getRequestDispatcher("/admin/login.jsp").forward(request, response);
          23         }
          24     }

          logout相對很簡單,使session失效即可
          1 private void logout(HttpServletRequest request, HttpServletResponse response)
          2             throws ServletException, IOException {
          3         HttpSession session = request.getSession();
          4         session.invalidate();
          5         response.sendRedirect(request.getContextPath());
          6     }

          modifyPassword
           1  private void modify(HttpServletRequest request, HttpServletResponse response)
           2             throws ServletException, IOException {
           3         String oldPassword = request.getParameter("oldPassword");
           4         String newPassword = request.getParameter("newPassword");
           5         String confirmPassword = request.getParameter("confirmPassword");
           6 
           7         HttpSession session = request.getSession();
           8         User user = (User) session.getAttribute("user");
           9         if (!user.getPassword().equals(oldPassword)) {
          10             request.setAttribute("message""與原密碼不匹配");
          11         } else {
          12             if (!newPassword.equals(confirmPassword)) {
          13                 request.setAttribute("message""新密碼與確認密碼不匹配");
          14             } else {
          15                 String sql = "update users set password =? where id = "+ user.getId();
          16                 QueryRunner qr = DbHelper.getQueryRunner();
          17                 try {
          18                     qr.update(sql, newPassword);
          19                 } catch (SQLException ex) {
          20                     Logger.getLogger(UserServlet.class.getName()).log(Level.SEVERE, null, ex);
          21                 }
          22                  request.setAttribute("message""密碼修改成功");
          23             }
          24         }
          25         request.getRequestDispatcher("/admin/modifyPassword.jsp").forward(request, response);
          26     }


          posted @ 2009-09-30 14:22 Chucky 閱讀(204) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 南投市| 玉溪市| 富民县| 中卫市| 葵青区| 镇远县| 郁南县| 石景山区| 化德县| 文登市| 长春市| 永泰县| 庄浪县| 锡林浩特市| 绥芬河市| 双流县| 冀州市| 河东区| 达孜县| 武冈市| 灵宝市| 寻乌县| 西乌珠穆沁旗| 安吉县| 大同市| 湄潭县| 特克斯县| 涟源市| 青浦区| 拉孜县| 丹东市| 中牟县| 广平县| 信阳市| 德钦县| 宜兰市| 苍南县| 新泰市| 彭山县| 囊谦县| 博客|