抱歉這篇才寫。上班沒有多少時間??!
TableModelBean.java 這是核心業務類,既要被Action使用又要被dwr使用。
由于我注釋寫了一些,所以就不詳細介紹了
public class TableModelBean {
    
    
//表格的第一列
    public static final int COLUMN_1 = 0;
    
    
//表格的第二列
    public static final int COLUMN_2 = 1;
    
    
//表格的第三列
    public static final int COLUMN_3 = 2;

    
//每一列的排序升序降序標記 true升序,false降序
    private boolean[] columnFlags = falsefalsefalse };
    
    
//表格分頁總頁面數
    private int totalPage = 0;
    
    
//表格當前頁
    private int currentPage = 0;
    
    
//表格總行數
    private int rowsCount = 0;

    
//沒用
    private String[] pagers = "" };

    
//存放全體記錄的容器
    private List rows = new ArrayList();

    
//存放當前記錄的容器
    private List currentPageRows = new ArrayList();

    
//數據庫操作類
    private static ModelOneDAO dao;

    
//每頁記錄數設為20
    private static final int PAGE_SIZE = 20;

    
//初始排序行為第一行
    private int sortedColumn = 1;

    
/**
     *  構造函數
     
*/

    
public TableModelBean() {
        dao 
= new ModelOneDAO();
        init();
    }


    
/**
     *  初始化
     
*/

    
private void init() {
        
try {
            rows 
= dao.getSortedRows(sortedColumn, columnFlags[sortedColumn]);
            setRowsCount(rows.size());
            setTotalPage(getTotalPageByRow(rows.size(), PAGE_SIZE));
            setCurrentPage(
1);
        }
 catch (SQLException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


    
/**
     * 返回當前頁的內容
     * @return Returns the currentPage.
     
*/

    
public int getCurrentPage() {
        
return currentPage;
    }


    
/**
     * 設置當前頁
     * @param currentPage
     *            The currentPage to set.
     
*/

    
public void setCurrentPage(int currentPage) {
        
this.currentPage = currentPage;

        currentPageRows.clear();
        
int firstIndex = PAGE_SIZE * (currentPage - 1);
        
int lastIndex = (firstIndex + PAGE_SIZE) < rowsCount ? firstIndex
                
+ PAGE_SIZE : rowsCount;
        
for (int i = firstIndex; i < lastIndex; i++{
            currentPageRows.add(rows.
get(i));
        }

    }


    
/**
     * 取得所有行
     * @return Returns the rows.
     
*/

    
public List getRows() {
        
return rows;
    }



    
/**
     * 取的分頁數
     * @return Returns the totalPage.
     
*/

    
public int getTotalPage() {
        init();
        
return totalPage;
    }


    
/**
     * 設置分頁數
     * @param totalPage
     *            The totalPage to set.
     
*/

    
public void setTotalPage(int totalPage) {
        
this.totalPage = totalPage;
    }


    
/**
     * 取得紀錄數
     * @return Returns the totalRows.
     
*/

    
public int getRowsCount() {
        
return rowsCount;
    }


    
/**
     *    設置記錄數
     *  @param totalRows
     *            The totalRows to set.
     
*/

    
public void setRowsCount(int rowsCount) {
        
this.rowsCount = rowsCount;
    }


    
/**
     * 取得當前頁中的記錄數
     * @return Returns the currentPageRows.
     
*/

    
public List getCurrentPageRows() {
        
return currentPageRows;
    }


    
/**
     * 取得page頁中的記錄,當page大于totalPage時返回最后頁
     * 因為是上面的getCurrentPageRows函數的重載,所以在dwr中不能正常使用。
     * 于是出現了getRowsByPageNo方法。
     * @param page
     * @return the currentPageRows.
     
*/

    
public List getCurrentPageRows(int page) {
        currentPageRows.clear();
        
int firstIndex = PAGE_SIZE * (page - 1);
        
int lastIndex = (firstIndex + PAGE_SIZE) < rowsCount ? firstIndex
                
+ PAGE_SIZE : rowsCount;
        
for (int i = firstIndex; i < lastIndex; i++{
            currentPageRows.add(rows.
get(i));
        }

        
return currentPageRows;
    }


    
/**
     * 取得page頁中的記錄,當page大于totalPage時返回最后頁
     * @param page
     * @return 包含當前頁記錄的List
     
*/

    
public List getRowsByPageNo(int page) {
        init();
        page 
= page > totalPage ? totalPage : page;
        List result 
= new ArrayList();
        
int firstIndex = PAGE_SIZE * (page - 1);
        
int lastIndex = (firstIndex + PAGE_SIZE) < rowsCount ? firstIndex
                
+ PAGE_SIZE : rowsCount;
        
for (int i = firstIndex; i < lastIndex; i++{
            result.add(rows.
get(i));
        }

        
return result;
    }


    
/**
     * 按照某一列進行排序,再返回當前頁中的數據
     * @param currentPage
     * @param columnNo
     * @return the Rows of current Page that sorted by columnNo
     
*/

    
public List getCurrentPageSortedByColumnRows(int currentPage, int columnNo) {
        init();
        sortBy(columnNo);
        currentPageRows.clear();
        
int firstIndex = 20 * (currentPage - 1);
        
int lastIndex = (firstIndex + 20< rowsCount ? firstIndex + 20
                : rowsCount;
        
for (int i = firstIndex; i < lastIndex; i++{
            currentPageRows.add(rows.
get(i));
        }

        
return currentPageRows;
    }


    
/**
     * 返回一個分頁數組。用處不太大,客戶端用Javascript也可以計算。
     * @return Returns the pages.
     
*/

    
public String[] getPagers() {
        pagers 
= new String[totalPage];
        
for (int i = 1; i <= totalPage; i++{
            pagers[i 
- 1= i + "";
        }

        
return pagers;
    }


    
/**
     * 按照某一列進行排序
     * @param columnNo
     
*/

    
public void sortBy(int columnNo) {
        
this.sortedColumn = columnNo;
        columnFlags[columnNo] 
= (!columnFlags[columnNo]);
        
try {
            rows 
= dao.getSortedRows(columnNo, columnFlags[columnNo]);
        }
 catch (SQLException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


    
/**
     * 刪除某一列,按照主鍵(第一列)
     * @param key
     * @return
     
*/

    
public boolean deleteRow(int key) {
        
try {
            dao.deleteRow(key);
        }
 catch (SQLException e) {
            e.printStackTrace();
            
return false;
        }

        
return true;
    }


    
/**
     * 要新增加一個數據前先計算出Id.
     * 這個例子只是用來演示用的,如果多人訪問會出現并發問題
     * @return
     
*/

    
public int getNextId() {
        
try {
            
return dao.getNextId();
        }
 catch (SQLException e) {
            e.printStackTrace();
            
return -1;
        }

    }


    
/**
     * 增加一行
     * @param trb
     * @return
     
*/

    
public boolean addRow(TableRowBean trb) {
        
try {
            dao.addRow(trb);
            
return true;
        }
 catch (SQLException e) {
            e.printStackTrace();
            
return false;
        }

    }


    
/**
     * 更改一行
     * @param trb
     * @return
     
*/

    
public boolean updateRow(TableRowBean trb) {
        
try {
            dao.updateRow(trb);
            
return true;
        }
 catch (SQLException e) {
            e.printStackTrace();
            
return false;
        }

    }


    
/**
     * 按照key取回單行信息
     * @param key
     * @return
     
*/

    
public TableRowBean getSingleRow(int key) {
        TableRowBean row;
        
try {
            row 
= dao.getSingleRow(key);
        }
 catch (SQLException e) {
            row 
= new TableRowBean();
            e.printStackTrace();
        }

        
return row;
    }


    
/**
     * 輔助方法計算分頁數
     * @param rowSize
     * @param pageSize
     * @return
     
*/

    
private static int getTotalPageByRow(int rowSize, int pageSize) {
        
int result = 0;
        result 
= rowSize % pageSize == 0 ? rowSize / pageSize : rowSize
                
/ pageSize + 1;
        
return result;
    }

}
接下來就是寫配置文件了。主要的配置文件有三個web.xml struts-config.xml dwr.xml
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
                         "http://java.sun.com/dtd/web-app_2_3.dtd"
>
<web-app>
    
<filter>
        
<filter-name>EncodingFilter</filter-name>
        
<filter-class>org.mstar.strutsajax.EncodingFilter</filter-class>
        
<init-param>
                
<param-name>encoding</param-name>
                
<param-value>gb2312</param-value>
        
</init-param>
    
</filter>
    
<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>
        
<load-on-startup>1</load-on-startup>
    
</servlet>
    
<servlet>
        
<servlet-name>dwr-invoker</servlet-name>
        
<display-name>DWR Servlet</display-name>
        
<description>Direct Web Remoter Servlet</description>
        
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
        
<init-param>
            
<param-name>config</param-name>
            
<param-value>WEB-INF/dwr.xml</param-value>
        
</init-param>
        
<init-param>
            
<param-name>debug</param-name>
            
<param-value>true</param-value>
        
</init-param>
        
<load-on-startup>1</load-on-startup>
    
</servlet>
    
<servlet-mapping>
        
<servlet-name>action</servlet-name>
        
<url-pattern>*.do</url-pattern>
    
</servlet-mapping>
    
<servlet-mapping>
        
<servlet-name>dwr-invoker</servlet-name>
        
<url-pattern>/dwr/*</url-pattern>
    
</servlet-mapping>
    
<welcome-file-list>
        
<welcome-file>index.jsp</welcome-file>
        
<welcome-file>login.jsp</welcome-file>
    
</welcome-file-list>
    
<taglib>
        
<taglib-uri>/WEB-INF/struts-bean</taglib-uri>
        
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
    
</taglib>
    
<taglib>
        
<taglib-uri>/WEB-INF/struts-logic</taglib-uri>
        
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
    
</taglib>
    
<taglib>
        
<taglib-uri>/WEB-INF/struts-html</taglib-uri>
        
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
    
</taglib>
</web-app>
其中要注意這段Servlet的聲明
<servlet>
        
<servlet-name>dwr-invoker</servlet-name>
        
<display-name>DWR Servlet</display-name>
        
<description>Direct Web Remoter Servlet</description>
        
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
        
<init-param>
            
<param-name>config</param-name>
            
<param-value>WEB-INF/dwr.xml</param-value>
        
</init-param>
        
<init-param>
            
<param-name>debug</param-name>
            
<param-value>true</param-value>
        
</init-param>
        
<load-on-startup>1</load-on-startup>
    
</servlet>
debug打開的話,你就可以看到每一個遠程調用。對開發很有用。
struts-config我就不寫了,大家對這個比較了解,要看的話,下載我的源碼,在最后面我會寫上。
重點是dwr.xml.這里是你要提供遠程接口信息
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
    
<init>
        
<converter id="tablerowbean" class="org.mstar.strutsajax.converter.TableRowConverter"/>
      
</init>
    
<allow>
        
<create creator="new" javascript="UserLogic">
            
<param name="class" value="org.mstar.strutsajax.ajax.UserLogic"/>
            
<include method="validate"/>
        
</create>
        
<create creator="new" javascript="TableModel" scope="session">
            
<param name="class" value="org.mstar.strutsajax.form.TableModelBean"/>
            
<include method="sortBy"/>
            
<include method="getRowsCount"/>
            
<include method="getTotalPage"/>
            
<include method="setCurrentPage"/>
            
<include method="getCurrentPageRows"/>
            
<include method="getCurrentPageSortedByColumnRows"/>
            
<include method="getRowsByPageNo"/>
            
<include method="deleteRow"/>
            
<include method="getNextId"/>
            
<include method="addRow"/>
            
<include method="updateRow"/>
            
<include method="getSingleRow"/>
        
</create>
        <convert converter="tablerowbean" match="org.mstar.strutsajax.form.TableRowBean"/>
    
</allow>
</dwr>
詳細配置你可以看dwr的文檔。
這里要說的就是,convert,對于你自己的類型如TableRowBean必須寫一個Converter來轉化它,我的TableRowConverter其實就是繼承與BeanConverter然后什么事情也沒做。但是我如果自己用BeanConverter就不行,不知道為什么。其他的都比較好理解。
當然我還有一個weblogic.xml,因為我是發布在weblogic上的。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN"    "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
<weblogic-web-app>
    
<jsp-descriptor>
        
<jsp-param>
            
<param-name>debug</param-name>
            
<param-value>true</param-value>
        
</jsp-param>
    
</jsp-descriptor>
    
<context-root>struts-ajax</context-root>
</weblogic-web-app>
剩下了就是JSP頁面了。我再寫一篇吧。