大家都知道Struts是一種基于MVC的結構,而這個MVC又怎么樣理解呢?書上闡述的一般都很詳細,而我的理解很直白,我們可以把業務邏輯放到每個JSP頁面中,當你訪問一個JSP頁面的時候,就可以看到業務邏輯得到的結果,而把這些業務邏輯與HTML代碼夾雜到了一起,一定會造成一些不必要的麻煩,可以不可以不讓我們的業務邏輯和那些HTML代碼夾雜到一起呢?多少得攙雜一些,那干脆,盡量少的吧,于是我們可以嘗試著把業務邏輯的運算過程放到一個Action里,我們訪問這個Action,之后Action執行業務邏輯,最后把業務邏輯的結果放到request中,并將頁面請求轉發給一個用于顯示結果的jsp頁面,這樣,這個頁面就可以少去很多的業務邏輯,而只是單純的去顯示一些業務邏輯計算結果的頁面而已。這時的Action稱為控制器,JSP頁可以叫做視圖了,而控制器操作的業務對象,無非就應該叫模型了!

從上面的話,我們來分析一下當我們要做一個分頁時所需要的部分,而在這之前,我們先看看他們的執行過程吧,首先我們第一次請求訪問一個頁面,它會把所有記錄的前N條顯示給我們,之后計算是否有下一頁,等類似的信息,當我們點下一頁的時候,就獲取下一頁的信息,我們還可以添加一個搜索,比如我們用于顯示學生的,可以安學生姓名查找,學號查找,班級查找。而對于顯示的對象,我們一般也都會封裝為javabean,所以用于放置查詢結果的容器是不定的,而這時,我們就需要用泛型來提升我們的代碼效率!

首先我們寫一個用于分頁顯示的javabean:

package com.boya.subject.model;

import java.util.Vector; 

public class Page
{
    private int current = 1;        //當前頁
    private int total = 0;         //總記錄數
    private int pages = 0;    //總頁數
    private int each = 5;         //每頁顯示
    private int start = 0;      //每頁顯示的開始記錄數
    private int end = 0;       //每頁顯示的結束記錄數
    private boolean next = false;        //是否有下一頁
    private boolean previous = false;  //是否有上一頁
    private Vector v = null;    //存放查詢結果的容器 

    public Page( Vector v ,int per)
    {
        this.v = v;
        each = per;
        total = v.size();   //容器的大小就是總的記錄數
        if ( total % each == 0 ) 
            pages = total / each;       //計算總頁數
        else
            pages = total / each + 1;
        if ( current >= pages )
        {
            next = false;
        }
        else
        {
            next = true;
        }
        if ( total < each )
        {
            start = 0;
            end = total;
        }
        else
        {
            start = 0;
            end = each;
        }
    }
    
    public int getCurrent()
    {
        return current;
    } 

    public void setCurrent( int current )
    {
        this.current = current;
    } 

    public int getEach()
    {
        return each;
    } 

    public void setEach( int each )
    {
        this.each = each;
    } 

    public boolean isNext()
    {
        return next;
    } 

    public void setNext( boolean next )
    {
        this.next = next;
    } 

    public boolean isPrevious()
    {
        return previous;
    } 

    public void setPrevious( boolean previous )
    {
        this.previous = previous;
    } 

    public int getEnd()
    {
        return end;
    } 

    public int getPages()
    {
        return pages;
    } 

    public int getStart()
    {
        return start;
    } 

    public int getTotal()
    {
        return total;
    } 

 //獲取下一頁的對象們   

public Vector getNextPage()
    {
        current = current + 1;
        if ( (current - 1) > 0 )
        {
            previous = true;
        }
        else
        {
            previous = false;
        }
        if ( current >= pages )
        {
            next = false;
        }
        else
        {
            next = true;
        }
        Vector os = gets();
        return os;
    }

 //獲取上一頁 

    public Vector getPreviouspage()
    {
        current = current - 1;
        if ( current == 0 )
        {
            current = 1;
        }
        if ( current >= pages )
        {
            next = false;
        }
        else
        {
            next = true;
        }
        if ( (current - 1) > 0 )
        {
            previous = true;
        }
        else
        {
            previous = false;
        }
        Vector os = gets();
        return os;
    }

 //一開始獲取的 

    public Vector gets()
    {
        if ( current * each < total )
        {
            end = current * each;
            start = end - each;
        }
        else
        {
            end = total;
            start = each * (pages - 1);
        }
        Vector gets = new Vector();
        for ( int i = start; i < end; i++ )
        {
            E o = v.get( i );
            gets.add( o );
        }
        return gets;
    }
}



 而對于按不同搜索,我們需要一個FormBean,一般的搜索,都是模糊搜索,搜索個大概,而且輸入的信息中文的比重也會很大,所以,我把對中文字符的轉換放到了這個BEAN里,在進行select * from * where like這樣的查詢時,如果是like ''這樣就可以得到所有的記錄了,我便用這個來對付沒有輸入查詢關鍵字的情況,而like '%*%'可以匹配關鍵字,而%%也在這里添加上了!

package com.boya.subject.view; 

import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping; 

public class SearchForm extends ActionForm
{
    private static final long serialVersionUID = 1L;
    private String key;
    private String from; 

    public String getFrom()
    {
        return from;
    } 

    public void setFrom( String from )
    {
        this.from = from;
    } 

      public void reset( ActionMapping mapping, HttpServletRequest req )
    {
        this.key = null;
    } 

    public String getKey()
    {
        return key;
    } 

    public void setKey( String key )
    {
        try
        {
            key = new String( key.getBytes( "iso-8859-1" ), "gb2312" );
        }
        catch ( UnsupportedEncodingException e )
        {
            e.printStackTrace();
        }
        this.key = "%" + key + "%";
    }
    
    public String getAny(){
        return "%%";
    }
}
前期都做好了,我現在就要開始訪問這個Action了,可是這個控制器還沒寫呢!這里是代碼 

public class AdminUserAction extends AdminAction
{
    private Vector ss; //用來裝結果的容器
    private Page ps; //分頁顯示的PAGE對象 

    protected ActionForward executeAction( ActionMapping mapping,
            ActionForm form, HttpServletRequest req, HttpServletResponse res )
            throws Exception
    {
        if ( !isSupper( req ) )
        {
            return notSupper( res );//如果不是超級管理員怎么辦?
        }
        Service service = getService();//獲取業務邏輯
        SearchForm sf = (SearchForm) form;//獲取搜索FORM
        String op = req.getParameter( "op" );//獲取用戶對頁面的操作
        String search = req.getParameter( "search" );//是否執行了搜索
        Vector temp = null; //用于存放臨時反饋給用戶的結果容器
                if ( op == null )//如果用戶沒有執行上/下一頁的操作
                {
                    if ( search != null )//用戶如果執行了搜索
                    {
                        if ( sf.getFrom().equalsIgnoreCase( "class" ) )//如果是按班級查找
                        {
                            ss = service.getAllStudentBySchoolClassForAdmin( sf
                                    .getKey() );//獲取from的關鍵字
                        }
                        else if ( sf.getFrom().equalsIgnoreCase( "name" ) )//如果是按姓名查找
                        {
                            ss = service.getAllStudentByNameForAdmin( sf
                                    .getKey() );
                        }
                        else if ( sf.getFrom().equalsIgnoreCase( "user" ) )//如果是按用戶名查找
                        {
                            ss = service.getAllStudentByUserForAdmin( sf
                                    .getKey() );
                        }
                        else
                        {
                            ss = service.getAllStudentBySnForAdmin( sf.getKey() );//按學號查找
                        }
                        form.reset( mapping, req );//重置搜索表單
                    }
                    else
                    {
                        ss = service.getAllStudentForAdmin( sf.getAny() ); //用戶未執行查找就顯示全部,
                    }
                    if ( ss != null && ss.size() != 0 )//如果查找不為空,有記錄,那就創建一個分頁對象
                    {
                        ps = new Page( ss, 10 );//將查詢結果和每頁顯示記錄數作為參數構件對象
                        temp = ps.gets();//并獲取第一頁
                    }
                }
                else//如果用戶執行了操作
                {
                    if ( op.equals( "next" ) )//操作是下一頁
                    {
                        temp = ps.getNextPage();
                    }
                    if ( op.equals( "previous" ) )//操作是上一頁
                    {
                        temp = ps.getPreviouspage();
                    }
                }
                req.setAttribute( "search", SelectUtil.studentSearch() );//把搜索用到的表單放到request中
                req.setAttribute( "students", temp );//該頁顯示的學生
                req.setAttribute( "page", ps );//分頁對象
                return mapping.findForward( "student" );//請求轉發
    }
}


用到SelectUtil中的代碼如下:
/**
     * 獲取學生查找類別的select
     * @return 學生查找類別
     * 2006-5-17 9:06:12
     */
    public static Vector studentSearch()
    {
        Vector s = new Vector();
        s.add( new LabelValueBean( "按學號查找", "sn" ) );
        s.add( new LabelValueBean( "按班級查找", "class" ) );
        s.add( new LabelValueBean( "按姓名查找", "name" ) );
        s.add( new LabelValueBean( "按用戶查找", "user" ) );
        return s;
    }
在看頁面視圖前先讓我們看看Model吧,

public class Student extends User
{
    private String sn;
    private SchoolClass schoolClass; //這里的班級做為了一種對象,我們在視圖顯示的時候就有了一層嵌套 

    public SchoolClass getSchoolClass()
    {
        return schoolClass;
    } 

    public void setSchoolClass( SchoolClass schoolClass )
    {
        this.schoolClass = schoolClass;
    } 

    public String getSn()
    {
        return sn;
    } 

    public void setSn( String sn )
    {
        this.sn = sn;
    } 

    public String getType()
    {
        return "student";
    }
}
在了解了model后,還是看看視圖吧,


先放個查詢表單:














由于模型中有嵌套,那么我們就將用到Nested標簽,其實沒有嵌套也可以使用這個標簽,下面的是用于顯示信息的,用迭迨器進行遍歷request范圍的students,你不安排范圍,他會自動找到的,并把每次遍歷的對象起名叫student,并作為層次的根元素,





//尋找了student的schoolClass屬性對象的schoolClass嵌套

      //student的名字

刪除



這里是顯示分頁對象的:

第頁
共頁
        //上一頁是否存在
        
               
                上一頁
                   
        
        上一頁    
        
       //下一頁是否存在
         
         
          下一頁
             
        下一頁    
        

共有條數據



到這里不知道您看明白了多少,在我的這個JSP頁里幾乎沒有任何的業務邏輯,這樣的設計就比把HTML和JAVA攙雜在一起好了很多。