1. 程式人生 > >分頁 Page<T>

分頁 Page<T>

一、import java.util.ArrayList;

import java.util.List;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.sekorm.transactor.common.utils.CookieUtils;
/**
* 分頁類
* @author ThinkGem
* @version 2013-7-2
* @param <T>
*/
public class Page<T> {

private int pageNo = 1; // 當前頁碼
private int pageSize = 10; // 頁面大小,設定為“-1”表示不進行分頁(分頁無效)

private long count;// 總記錄數,設定為“-1”表示不查詢總數

private int first;// 首頁索引
private int last;// 尾頁索引
private int prev;// 上一頁索引
private int next;// 下一頁索引

private boolean firstPage;//是否是第一頁
private boolean lastPage;//是否是最後一頁

private int length = 8;// 顯示頁面長度
private int slider = 1;// 前後顯示頁面長度

private List<T> list = new ArrayList<T>();

private String orderBy = ""; // 標準查詢有效, 例項: updatedate desc, name asc

private String funcName = "page"; // 設定點選頁碼呼叫的js函式名稱,預設為page,在一頁有多個分頁物件時使用。

private String funcParam = ""; // 函式的附加引數,第三個引數值。

private String message = ""; // 設定提示訊息,顯示在“共n條”之後

public Page() {
this.pageSize = -1;
}

/**
* 構造方法
* @param request 傳遞 repage 引數,來記住頁碼
* @param response 用於設定 Cookie,記住頁碼
*/
public Page(HttpServletRequest request, HttpServletResponse response){
this(request, response, -2);
}

/**
* 構造方法
* @param request 傳遞 repage 引數,來記住頁碼
* @param response 用於設定 Cookie,記住頁碼
* @param defaultPageSize 預設分頁大小,如果傳遞 -1 則為不分頁,返回所有資料
*/
public Page(HttpServletRequest request, HttpServletResponse response, int defaultPageSize){
// 設定頁碼引數(傳遞repage引數,來記住頁碼)
String no = request.getParameter("pageNo");
if (StringUtils.isNumeric(no)){
CookieUtils.setCookie(response, "pageNo", no);
this.setPageNo(Integer.parseInt(no));
}else if (request.getParameter("repage")!=null){
no = CookieUtils.getCookie(request, "pageNo");
if (StringUtils.isNumeric(no)){
this.setPageNo(Integer.parseInt(no));
}
}
// 設定頁面大小引數(傳遞repage引數,來記住頁碼大小)
String size = request.getParameter("pageSize");
if (StringUtils.isNumeric(size)){
CookieUtils.setCookie(response, "pageSize", size);
this.setPageSize(Integer.parseInt(size));
}else if (request.getParameter("repage")!=null){
size = CookieUtils.getCookie(request, "pageSize");
if (StringUtils.isNumeric(size)){
this.setPageSize(Integer.parseInt(size));
}
}else if (defaultPageSize != -2){
this.pageSize = defaultPageSize;
}
// 設定頁面分頁函式
String funcName = request.getParameter("funcName");
if (StringUtils.isNotBlank(funcName)){
CookieUtils.setCookie(response, "funcName", funcName);
this.setFuncName(funcName);
}else if (request.getParameter("repage")!=null){
funcName = CookieUtils.getCookie(request, "funcName");
if (StringUtils.isNotBlank(funcName)){
this.setFuncName(funcName);
}
}
// 設定排序引數
String orderBy = request.getParameter("orderBy");
if (StringUtils.isNotBlank(orderBy)){
this.setOrderBy(orderBy);
}
}

/**
* 構造方法
* @param pageNo 當前頁碼
* @param pageSize 分頁大小
*/
public Page(int pageNo, int pageSize) {
this(pageNo, pageSize, 0);
}

/**
* 構造方法
* @param pageNo 當前頁碼
* @param pageSize 分頁大小
* @param count 資料條數
*/
public Page(int pageNo, int pageSize, long count) {
this(pageNo, pageSize, count, new ArrayList<T>());
}

/**
* 構造方法
* @param pageNo 當前頁碼
* @param pageSize 分頁大小
* @param count 資料條數
* @param list 本頁資料物件列表
*/
public Page(int pageNo, int pageSize, long count, List<T> list) {
this.setCount(count);
this.setPageNo(pageNo);
this.pageSize = pageSize;
this.list = list;
}

/**
* 初始化引數
*/
public void initialize(){

//1
this.first = 1;

this.last = (int)(count / (this.pageSize < 1 ? 20 : this.pageSize) + first - 1);

if (this.count % this.pageSize != 0 || this.last == 0) {
this.last++;
}

if (this.last < this.first) {
this.last = this.first;
}

if (this.pageNo <= 1) {
this.pageNo = this.first;
this.firstPage=true;
}

if (this.pageNo >= this.last) {
this.pageNo = this.last;
this.lastPage=true;
}

if (this.pageNo < this.last - 1) {
this.next = this.pageNo + 1;
} else {
this.next = this.last;
}

if (this.pageNo > 1) {
this.prev = this.pageNo - 1;
} else {
this.prev = this.first;
}

//2
if (this.pageNo < this.first) {// 如果當前頁小於首頁
this.pageNo = this.first;
}

if (this.pageNo > this.last) {// 如果當前頁大於尾頁
this.pageNo = this.last;
}

}

/**
* 預設輸出當前分頁標籤
* <div class="page">${page}</div>
*/
@Override
public String toString() {

StringBuilder sb = new StringBuilder();

if (pageNo == first) {// 如果是首頁
sb.append("<li class=\"disabled\"><a href=\"javascript:\">&#171; 上一頁</a></li>\n");
} else {
sb.append("<li><a href=\"javascript:\" onclick=\""+funcName+"("+prev+","+pageSize+",'"+funcParam+"');\">&#171; 上一頁</a></li>\n");
}

int begin = pageNo - (length / 2);

if (begin < first) {
begin = first;
}

int end = begin + length - 1;

if (end >= last) {
end = last;
begin = end - length + 1;
if (begin < first) {
begin = first;
}
}

if (begin > first) {
int i = 0;
for (i = first; i < first + slider && i < begin; i++) {
sb.append("<li><a href=\"javascript:\" onclick=\""+funcName+"("+i+","+pageSize+",'"+funcParam+"');\">"
+ (i + 1 - first) + "</a></li>\n");
}
if (i < begin) {
sb.append("<li class=\"disabled\"><a href=\"javascript:\">...</a></li>\n");
}
}

for (int i = begin; i <= end; i++) {
if (i == pageNo) {
sb.append("<li class=\"active\"><a href=\"javascript:\">" + (i + 1 - first)
+ "</a></li>\n");
} else {
sb.append("<li><a href=\"javascript:\" onclick=\""+funcName+"("+i+","+pageSize+",'"+funcParam+"');\">"
+ (i + 1 - first) + "</a></li>\n");
}
}

if (last - end > slider) {
sb.append("<li class=\"disabled\"><a href=\"javascript:\">...</a></li>\n");
end = last - slider;
}

for (int i = end + 1; i <= last; i++) {
sb.append("<li><a href=\"javascript:\" onclick=\""+funcName+"("+i+","+pageSize+",'"+funcParam+"');\">"
+ (i + 1 - first) + "</a></li>\n");
}

if (pageNo == last) {
sb.append("<li class=\"disabled\"><a href=\"javascript:\">下一頁 &#187;</a></li>\n");
} else {
sb.append("<li><a href=\"javascript:\" onclick=\""+funcName+"("+next+","+pageSize+",'"+funcParam+"');\">"
+ "下一頁 &#187;</a></li>\n");
}

sb.append("<li class=\"disabled controls\"><a href=\"javascript:\">當前 ");
sb.append("<input type=\"text\" value=\""+pageNo+"\" onkeypress=\"var e=window.event||event;var c=e.keyCode||e.which;if(c==13)");
sb.append(funcName+"(this.value,"+pageSize+",'"+funcParam+"');\" onclick=\"this.select();\"/> / ");
sb.append("<input type=\"text\" value=\""+pageSize+"\" onkeypress=\"var e=window.event||event;var c=e.keyCode||e.which;if(c==13)");
sb.append(funcName+"("+pageNo+",this.value,'"+funcParam+"');\" onclick=\"this.select();\"/> 條,");
sb.append("共 " + count + " 條"+(message!=null?message:"")+"</a></li>\n");

sb.insert(0,"<ul>\n").append("</ul>\n");

sb.append("<div style=\"clear:both;\"></div>");

// sb.insert(0,"<div class=\"page\">\n").append("</div>\n");

return sb.toString();
}

/**
* 獲取分頁HTML程式碼
* @return
*/
public String getHtml(){
return toString();
}

public static void main(String[] args) {
Page<String> p = new Page<String>(3, 3,100);
System.out.println(p);
System.out.println("首頁:"+p.getFirst());
System.out.println("尾頁:"+p.getLast());
System.out.println("上頁:"+p.getPrev());
System.out.println("下頁:"+p.getNext());
}

/**
* 獲取設定總數
* @return
*/
public long getCount() {
return count;
}

/**
* 設定資料總數
* @param count
*/
public void setCount(long count) {
this.count = count;
if (pageSize >= count){
pageNo = 1;
}
}

/**
* 獲取當前頁碼
* @return
*/
public int getPageNo() {
return pageNo;
}

/**
* 設定當前頁碼
* @param pageNo
*/
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}

/**
* 獲取頁面大小
* @return
*/
public int getPageSize() {
return pageSize;
}

/**
* 設定頁面大小(最大500)
* @param pageSize
*/
public void setPageSize(int pageSize) {
this.pageSize = pageSize <= 0 ? 10 : pageSize;// > 500 ? 500 : pageSize;
}

/**
* 首頁索引
* @return
*/
@JsonIgnore
public int getFirst() {
return first;
}

/**
* 尾頁索引
* @return
*/
@JsonIgnore
public int getLast() {
return last;
}

/**
* 獲取頁面總數
* @return getLast();
*/
@JsonIgnore
public int getTotalPage() {
return getLast();
}

/**
* 是否為第一頁
* @return
*/
@JsonIgnore
public boolean isFirstPage() {
return firstPage;
}

/**
* 是否為最後一頁
* @return
*/
@JsonIgnore
public boolean isLastPage() {
return lastPage;
}

/**
* 上一頁索引值
* @return
*/
@JsonIgnore
public int getPrev() {
if (isFirstPage()) {
return pageNo;
} else {
return pageNo - 1;
}
}

/**
* 下一頁索引值
* @return
*/
@JsonIgnore
public int getNext() {
if (isLastPage()) {
return pageNo;
} else {
return pageNo + 1;
}
}

/**
* 獲取本頁資料物件列表
* @return List<T>
*/
public List<T> getList() {
return list;
}

/**
* 設定本頁資料物件列表
* @param list
*/
public Page<T> setList(List<T> list) {
this.list = list;
initialize();
return this;
}

/**
* 獲取查詢排序字串
* @return
*/
@JsonIgnore
public String getOrderBy() {
// SQL過濾,防止注入
String reg = "(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|"
+ "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)";
Pattern sqlPattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
if (sqlPattern.matcher(orderBy).find()) {
return "";
}
return orderBy;
}

/**
* 設定查詢排序,標準查詢有效, 例項: updatedate desc, name asc
*/
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}

/**
* 獲取點選頁碼呼叫的js函式名稱
* function ${page.funcName}(pageNo){location="${ctx}/list-${category.id}${urlSuffix}?pageNo="+i;}
* @return
*/
@JsonIgnore
public String getFuncName() {
return funcName;
}

/**
* 設定點選頁碼呼叫的js函式名稱,預設為page,在一頁有多個分頁物件時使用。
* @param funcName 預設為page
*/
public void setFuncName(String funcName) {
this.funcName = funcName;
}

/**
* 獲取分頁函式的附加引數
* @return
*/
@JsonIgnore
public String getFuncParam() {
return funcParam;
}

/**
* 設定分頁函式的附加引數
* @return
*/
public void setFuncParam(String funcParam) {
this.funcParam = funcParam;
}

/**
* 設定提示訊息,顯示在“共n條”之後
* @param message
*/
public void setMessage(String message) {
this.message = message;
}

/**
* 分頁是否有效
* @return this.pageSize==-1
*/
@JsonIgnore
public boolean isDisabled() {
return this.pageSize==-1;
}

/**
* 是否進行總數統計
* @return this.count==-1
*/
@JsonIgnore
public boolean isNotCount() {
return this.count==-1;
}

/**
* 獲取 Hibernate FirstResult
*/
public int getFirstResult(){
int firstResult = (getPageNo() - 1) * getPageSize();
if (firstResult >= getCount()) {
firstResult = 0;
}
return firstResult;
}
/**
* 獲取 Hibernate MaxResults
*/
public int getMaxResults(){
return getPageSize();
}

/*
* 獲取起始位置
*/
public Integer getStartIndex()
{
int startIndex = (pageNo - 1) * pageSize;
return startIndex;
}

/*
*獲取結束位置
*/
public Integer getEndIndex()
{
int endIndex = this.pageNo * this.pageSize;
return endIndex;
}

}
二、CookieUtils

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Cookie工具類
*/
public class CookieUtils {

/**
* 設定 Cookie(生成時間為1天)
* @param name 名稱
* @param value 值
*/
public static void setCookie(HttpServletResponse response, String name, String value) {
setCookie(response, name, value, 60*60*24);
}

/**
* 設定 Cookie
* @param name 名稱
* @param value 值
* @param maxAge 生存時間(單位秒)
* @param uri 路徑
*/
public static void setCookie(HttpServletResponse response, String name, String value, String path) {
setCookie(response, name, value, path, 60*60*24);
}

/**
* 設定 Cookie
* @param name 名稱
* @param value 值
* @param maxAge 生存時間(單位秒)
* @param uri 路徑
*/
public static void setCookie(HttpServletResponse response, String name, String value, int maxAge) {
setCookie(response, name, value, "/", maxAge);
}

/**
* 設定 Cookie
* @param name 名稱
* @param value 值
* @param maxAge 生存時間(單位秒)
* @param uri 路徑
*/
public static void setCookie(HttpServletResponse response, String name, String value, String path, int maxAge) {
Cookie cookie = new Cookie(name, null);
cookie.setPath(path);
cookie.setMaxAge(maxAge);
try {
cookie.setValue(URLEncoder.encode(value, "utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
response.addCookie(cookie);
}

/**
* 獲得指定Cookie的值
* @param name 名稱
* @return 值
*/
public static String getCookie(HttpServletRequest request, String name) {
return getCookie(request, null, name, false);
}
/**
* 獲得指定Cookie的值,並刪除。
* @param name 名稱
* @return 值
*/
public static String getCookie(HttpServletRequest request, HttpServletResponse response, String name) {
return getCookie(request, response, name, true);
}
/**
* 獲得指定Cookie的值
* @param request 請求物件
* @param response 響應物件
* @param name 名字
* @param isRemove 是否移除
* @return 值
*/
public static String getCookie(HttpServletRequest request, HttpServletResponse response, String name, boolean isRemove) {
String value = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(name)) {
try {
value = URLDecoder.decode(cookie.getValue(), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if (isRemove) {
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
}
}
return value;
}
}
三、Controller
String pageNo=request.getParameter("pageNo");
pageNo=pageNo==null?"1":pageNo;
request.setAttribute("pageNo", pageNo);
request.setAttribute("pageSize",pagSize);
request.setAttribute("funcName", "page");
Page<ContactsVo> page = new Page<ContactsVo>(request, response);
page.setCount(num);
page.setPageSize(pagSize);
page.setPageNo(Integer.parseInt(pageNo));
page.setList(list);
model.addAttribute("page", page);

四、html
function page(n,s){
$("#pageNo").val(n);
$("#pageSize").val(s);
$("#searchForm").submit();
return false;
}
<input id="pageNo" name="pageNo" type="hidden" value="${page.pageNo==null?1:page.pageNo}"/>
<input id="pageSize" name="pageSize" type="hidden" value="${page.pageSize}"/>
<div class="pagination">${page}</div>