`
JavaCrazyer
  • 浏览: 2990015 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类

自定义分页标签详解

阅读更多

关于自定义分页标签的使用,我想大家都见过许多人写过,我今天也来凑个热闹写下我见到的自定义标签的使用步骤

既然是自定义标签那么肯定少不了类和tld文件这两大因素,因为这两个才能构成标签

首先奉献上最核心的自定义分页标签类的写法PagerTag.java,前提是要继承自TagSupport类

package com.javacrazyer.web.tag;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;


/**
 * 分页标签处理类
 */
public class PagerTag extends TagSupport {
	private static final long serialVersionUID = 5729832874890369508L;
	private String url;         //请求URI
	private int pageSize = 10;  //每页要显示的记录数
	private int pageNo = 1;     //当前页号
	private int recordCount;    //总记录数

	@SuppressWarnings("unchecked")
	public int doStartTag() throws JspException {
		int pageCount = (recordCount + pageSize - 1) / pageSize;  //计算总页数
		
		//拼写要输出到页面的HTML文本
		StringBuilder sb = new StringBuilder();
		
		
		sb.append("<style type=\"text/css\">");
		sb.append(".pagination {padding: 5px;float:right;font-size:12px;}");
		sb.append(".pagination a, .pagination a:link, .pagination a:visited {padding:2px 5px;margin:2px;border:1px solid #aaaadd;text-decoration:none;color:#006699;}");
		sb.append(".pagination a:hover, .pagination a:active {border: 1px solid #ff0000;color: #000;text-decoration: none;}");
		sb.append(".pagination span.current {padding: 2px 5px;margin: 2px;border: 1px solid #ff0000;font-weight: bold;background-color: #ff0000;color: #FFF;}");
		sb.append(".pagination span.disabled {padding: 2px 5px;margin: 2px;border: 1px solid #eee; color: #ddd;}");
		sb.append("</style>\r\n");
		sb.append("<div class=\"pagination\">\r\n");
		if(recordCount == 0){
			sb.append("<strong>没有可显示的项目</strong>\r\n");
		}else{
			//页号越界处理
			if(pageNo > pageCount){		pageNo = pageCount;	}
			if(pageNo < 1){		pageNo = 1;	}
			
			sb.append("<form method=\"post\" action=\"").append(this.url)
				.append("\" name=\"qPagerForm\">\r\n");
			
			//获取请求中的所有参数
			HttpServletRequest request = (HttpServletRequest) pageContext
					.getRequest();
			Enumeration<String> enumeration = request.getParameterNames();
			String name = null;  //参数名
			String value = null; //参数值
			//把请求中的所有参数当作隐藏表单域
			while (enumeration.hasMoreElements()) {
				name =  enumeration.nextElement();
				value = request.getParameter(name);
				// 去除页号
				if (name.equals("pageNo")) {
					if (null != value && !"".equals(value)) {
						pageNo = Integer.parseInt(value);
					}
					continue;
				}
				sb.append("<input type=\"hidden\" name=\"")
				  .append(name)
				  .append("\" value=\"")
				  .append(value)
				  .append("\"/>\r\n");
			}
	
			// 把当前页号设置成请求参数
			sb.append("<input type=\"hidden\" name=\"").append("pageNo")
				.append("\" value=\"").append(pageNo).append("\"/>\r\n");
			
			// 输出统计数据
			sb.append("&nbsp;共<strong>").append(recordCount)
				.append("</strong>项")
				.append(",<strong>")
				.append(pageCount)
				.append("</strong>页:&nbsp;\r\n");
			
			//上一页处理
			if (pageNo == 1) {
				sb.append("<span class=\"disabled\">&laquo;&nbsp;上一页")
					.append("</span>\r\n");
			} else {
				sb.append("<a href=\"javascript:turnOverPage(")
				  .append((pageNo - 1))
				  .append(")\">&laquo;&nbsp;上一页</a>\r\n");
			}
			
			//如果前面页数过多,显示"..."
			int start = 1; 
			if(this.pageNo > 4){
				start = this.pageNo - 1;
				sb.append("<a href=\"javascript:turnOverPage(1)\">1</a>\r\n");
				sb.append("<a href=\"javascript:turnOverPage(2)\">2</a>\r\n");
				sb.append("&hellip;\r\n");
			}
			//显示当前页附近的页
			int end = this.pageNo + 1;
			if(end > pageCount){
				end = pageCount;
			}
			for(int i = start; i <= end; i++){
				if(pageNo == i){   //当前页号不需要超链接
					sb.append("<span class=\"current\">")
						.append(i)
						.append("</span>\r\n");
				}else{
					sb.append("<a href=\"javascript:turnOverPage(")
						.append(i)
						.append(")\">")
						.append(i)
						.append("</a>\r\n");
				}
			}
			//如果后面页数过多,显示"..."
			if(end < pageCount - 2){
				sb.append("&hellip;\r\n");
			}
			if(end < pageCount - 1){
				sb.append("<a href=\"javascript:turnOverPage(")
				.append(pageCount - 1)
				.append(")\">")
				.append(pageCount - 1)
				.append("</a>\r\n");
			}
			if(end < pageCount){
				sb.append("<a href=\"javascript:turnOverPage(")
				.append(pageCount)
				.append(")\">")
				.append(pageCount)
				.append("</a>\r\n"); 
			}
			
			//下一页处理
			if (pageNo == pageCount) {
				sb.append("<span class=\"disabled\">下一页&nbsp;&raquo;")
					.append("</span>\r\n");
			} else {
				sb.append("<a href=\"javascript:turnOverPage(")
					.append((pageNo + 1))
					.append(")\">下一页&nbsp;&raquo;</a>\r\n");
			}
			sb.append("</form>\r\n");
	
			// 生成提交表单的JS
			sb.append("<script language=\"javascript\">\r\n");
			sb.append("  function turnOverPage(no){\r\n");
			sb.append("    if(no>").append(pageCount).append("){");
			sb.append("      no=").append(pageCount).append(";}\r\n");
			sb.append("    if(no<1){no=1;}\r\n");
			sb.append("    document.qPagerForm.pageNo.value=no;\r\n");
			sb.append("    document.qPagerForm.submit();\r\n");
			sb.append("  }\r\n");
			sb.append("</script>\r\n");
		}
		sb.append("</div>\r\n");
		
		//把生成的HTML输出到响应中
		try {
			pageContext.getOut().println(sb.toString());
		} catch (IOException e) {
			throw new JspException(e);
		}
		return SKIP_BODY;  //本标签主体为空,所以直接跳过主体
	}

	public void setUrl(String url) {
		this.url = url;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}
	public void setRecordCount(int recordCount) {
		this.recordCount = recordCount;
	}
}

 WEB-INF/pager.tld的写法

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
	<tlib-version>0.9</tlib-version>
   <!--标签头-->
	<short-name>w</short-name>
    <!--将来在页面用taglib引用时的uri属性,这部分的名字可以随便写,只要是符合HTTP网址形式的	-->
	<uri>http://javacrazyer.iteye.com/tags/pager</uri>
	
	<!-- 自定义标签的描述信息 -->
	<tag>
		<!-- 标签名 -->
		<name>pager</name>
		<!-- 对应的标签处理类全限定名 -->
		<tag-class>com.javacrazyer.web.tag.PagerTag</tag-class>
		<!-- 标签主体的类型 -->
		<body-content>empty</body-content>
		<!-- 当前页号属性的描述信息 -->
		<attribute>
			<!-- 属性名 -->
			<name>pageNo</name>
			<!-- 该属性是否为必要的 -->
			<required>true</required>
			<!-- 属性值是否可以在JSP运行时期动态产生 -->
			<rtexprvalue>true</rtexprvalue>
			<!-- 属性的数据类型 -->
			<type>int</type>
		</attribute>
		<!-- 总记录数属性的描述信息 -->
		<attribute>
			<name>recordCount</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
			<type>int</type>
		</attribute>
		<!-- 总页数属性的描述信息 -->
		<attribute>
			<name>pageSize</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
			<type>int</type>
		</attribute>
		<!-- 分页标签要跳转的URI属性的描述信息 -->
		<attribute>
			<name>url</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
			<type>java.lang.String</type>
		</attribute>
	</tag>
</taglib>

 

好了,就上面的两个基本要素就已经构成了完整的分页标签,下面就差在页面的使用方式了

一般的使用步骤为在JSP页面中:

先倒入标签库:<%@taglib uri="http://javacrazyer.iteye.com/tags/pager" prefix="w"%>

然后使用: <w:pager pageSize="${pageSize}" pageNo="${pageNo}" url="do.jsp" recordCount="${pm.recordCount}"/>

 

具体使用示例,上面两个类保持不变

这个例子可以说非常好的纯servlet项目的例子,大家今后编程如果没有用到任何框架的话,我希望这个例子能给你带来点启示

前提是导入所有需要的jar包:包括common-dbcp.jar(数据源需要用到),common-dbutils-1.2.jar(数据库CURD操作需要用到,可取代最原始的JDBC操作),junit.jar(测试用到)以及数据库驱动包

关于上面的common-dbutils非常有用,尤其是在非框架项目中,后面我提供下载



 

 

首先数据库,这个数据库脚本是我用navicat导出来的

/*
Navicat MySQL Data Transfer
Source Host     : localhost:3306
Source Database : jstl
Target Host     : localhost:3306
Target Database : jstl
Date: 2010-11-18 14:30:30
*/

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for news
-- ----------------------------
DROP TABLE IF EXISTS `news`;
CREATE TABLE `news` (
  `detail` varchar(255) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1253 DEFAULT CHARSET=utf8;

 

实体类News.java

package com.javacrazyer.domain;

public class News {
	private int id;
	private String name;
	private String detail;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDetail() {
		return detail;
	}

	public void setDetail(String detail) {
		this.detail = detail;
	}

	@Override
	public String toString() {
		return "News [detail=" + detail + ", id=" + id + ", name=" + name + "]";
	}
	

}

 NewsDao.java

package com.javacrazyer.dao;

import com.javacrazyer.common.PageModel;
import com.javacrazyer.domain.News;

public interface NewsDao {
	PageModel<News> findByPager(int pageNo, int pageSize);

	void createNews(News news);
	
	void update(News news);
	
	void delete(int id);
	
	News findbyId(int id);
	
	int findTotalSize();
	

}

NewsImplDao.java

package com.javacrazyer.daoimpl;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.javacrazyer.common.ConnectionFactory;
import com.javacrazyer.common.DAOException;
import com.javacrazyer.common.PageModel;
import com.javacrazyer.dao.NewsDao;
import com.javacrazyer.domain.News;

public class NewsDaoImpl implements NewsDao {
	private QueryRunner qr = new QueryRunner();
	public void createNews(News news) {
		
		Connection conn = null;
		String sql = "insert into news(name,detail) "
				+ " values(?,?)";
		Object[] param = { news.getName(),news.getDetail() };
		try {
			conn = ConnectionFactory.getConn();
			qr.update(conn, sql, param);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new DAOException("新增新闻信息时出现异常", e);
		} finally {
			DbUtils.closeQuietly(conn);
		}

	}

	public PageModel<News> findByPager(int pageNo, int pageSize) {
		PageModel<News> pm=new PageModel<News>();
		Connection conn=null;
		String sql="select *from news limit ?,?";
		Object[] param={(pageNo-1)*pageSize,pageSize};
		List<News> cates=null;
		int count;
		try {
			conn=ConnectionFactory.getConn();
			cates=(List<News>)qr.query(conn, sql, new BeanListHandler(News.class), param);
			pm.setDatas(cates);
			pm.setRecordCount(findTotalSize());
		} catch (SQLException e) {			
			e.printStackTrace();
			throw new DAOException("分页查询出错",e);
		}finally{
			DbUtils.closeQuietly(conn);
		}
		return pm;
	}

	public void delete(int id) {
		Connection conn = null;
		String sql = "delete from news where id=?";
		Object[] param = { id };
		try {
			conn = ConnectionFactory.getConn();
			qr.update(conn, sql, param);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new DAOException("删除新闻信息时出现异常", e);
		} finally {
			DbUtils.closeQuietly(conn);
		}
	}

	public News findbyId(int id) {
		News news=null;
		Connection conn=null;
		String sql="select * from news where id=?";
		Object[] param={id};
		try {
			conn=ConnectionFactory.getConn();
			news=(News)qr.query(conn,sql, new BeanHandler(News.class), param);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new DAOException("根据ID查询新闻信息时出现异常",e);
		}finally{
			DbUtils.closeQuietly(conn);
		}
		return news;
	}

	public void update(News news) {
		Connection conn=null;
		String sql="update news set name=?,detail=? where id=?";
		Object[] param={news.getName(),news.getDetail(),news.getId()};
		try {
			conn=ConnectionFactory.getConn();
			qr.update(conn, sql, param);
			
		} catch (SQLException e) {
			e.printStackTrace();
			throw new DAOException("更新新闻信息出错",e);
		}finally{
			DbUtils.closeQuietly(conn);
		}		
	}

	public int findTotalSize() {
		Connection conn=null;
		String sql="select count(id) from news";
		int count=0;
		try {
			conn=ConnectionFactory.getConn();
			count=((Long)qr.query(conn,sql,new ScalarHandler())).intValue();
			
		} catch (SQLException e) {
			e.printStackTrace();
			throw new DAOException("查询记录总数出错",e);
		}finally{
			DbUtils.closeQuietly(conn);
		}
		return count;
	}

}

 PageModel.java

package com.javacrazyer.common;

import java.util.List;

/** 
 * 分页组件(包含当前页结果数据列表和总记录数) 
 * 注意,它不是持久化实体类 
 *  
 */  
public class PageModel<T> {  
    private int recordCount;  
    private List<T> datas;  
      
      
    public int getRecordCount() {  
        return recordCount;  
    }  
    public void setRecordCount(int recordCount) {  
        this.recordCount = recordCount;  
    }  
    public List<T> getDatas() {  
        return datas;  
    }  
    public void setDatas(List<T> datas) {  
        this.datas = datas;  
    }  
}  

 

 数据库连接工具类

package com.javacrazyer.common;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;

/**
 * 
 * 数据库连接工厂类
 * 
 */
public class ConnectionFactory {
    private static DataSource dss=null;
	static{
		Properties pr=new Properties();
		try {
			pr.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		BasicDataSource ds=new BasicDataSource();
		ds.setDriverClassName(pr.getProperty("driver_name"));
		ds.setUrl(pr.getProperty("url"));
		ds.setUsername(pr.getProperty("username"));
		ds.setPassword(pr.getProperty("password"));
		dss=ds;
	}
	private ConnectionFactory(){}
	public static Connection getConn() throws SQLException{
		return dss.getConnection();
	}

}

  上面代码用到的config.properties

#mysql
driver_name=com.mysql.jdbc.Driver
url=jdbc:mysql:///jstl
username=root
password=root

DAO实例工具类,类似于Spring的BeanFactory

package com.javacrazyer.common;

import java.io.IOException;
import java.util.Properties;

/**
 * 
 * 
 *  自定义简单工厂
 */
public class DAOFactory {
	public static Properties pr = new Properties();
	static {
		try {
			pr.load(Thread.currentThread().getContextClassLoader()
					.getResourceAsStream("daoname.properties"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static Object newInstance(String name){
	    Object obj=null;
		String daoImplName = pr.getProperty(name);
		if(null!=daoImplName){
			try {
				obj=Class.forName(daoImplName).newInstance();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else{
			throw new RuntimeException("指定名称的DAO类未找到");
		}
		return obj;
	}
}

  上面代码用到的配置daoname.properties

newsdao=com.javacrazyer.daoimpl.NewsDaoImpl
coursedao=com.javacrazyer.web.tag.CourseDAOImpl
teacherdao=com.javacrazyer.web.tag.TeacherDAOImpl
catedao=com.javacrazyer.web.tag.CategoryDAOImpl
gradao=com.javacrazyer.web.tag.GraduateDAOImpl
accountdao=com.javacrazyer.web.tag.AccountDAOImpl

 平时开发中常用到的常量存放类

package com.javacrazyer.common;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 系统常量类
 * 
 * @author tjitcast.com
 */
public class Constant {
	
	
	/** 状态:可用 */
	public static final int STATUS_ACTIVE = 1;
	/** 状态:不可用 */
	public static final int STATUS_INACTIVE = 0;

	/** 课程类型:全日制 */
	public static final int COURSE_FULL_TIME = 1;
	/** 课程类型:业务 */
	public static final int COURSE_SPARE_TIME = 2;
	/** 课程类型:免费 */
	public static final int COURSE_FREE_TIME = 3;

	/** 账号类型:超级管理员 */
	public static final int ACCOUNT_SUPER = 100;
	/** 账号类型:普通管理员 */
	public static final int ACCOUNT_COMMON = 50;

	/** 账号状态:激活 */
	public static final int ACCOUNT_STATUS_ACTIVE = 1;
	/** 账号状态:未激活 */
	public static final int ACCOUNT_STATUS_INACTIVE = 0;
	/** 账号状态:锁定 */
	public static final int ACCOUNT_STATUS_LOCK = -1;

	/** 每页要显示的记录数:10 */
	public static final int PAGE_SIZE =10;

	private static Map<Integer, String> statusMap = new LinkedHashMap<Integer, String>();

	static {
		// 对状态Map进行初始化
		statusMap.put(Integer.valueOf(STATUS_ACTIVE), "可用");
		statusMap.put(Integer.valueOf(STATUS_INACTIVE), "不可用");
	}

	public static Map<Integer, String> getStatusMap() {
		return statusMap;
	}

}

 

开发中常用到的用来判断空值,类型转换,集合操作等等的自定义常用工具类

/**
 *  ClassName: DataValidateUtil.java
 *  created on Jul 10, 2009
 *  Copyrights 2009 www.tjicast.com All rights reserved.
 *  site: http://www.tjitcast.com
 *  email: tjhr@csdn.net
 *  phone: 022-83726777,89721888
 */
package com.javacrazyer.common;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;

/**
 * 对一些常用数据进行操作的工具类
 * 
 */
public class DataOptUtil {
	
	
	/** 日期长格式 */
	public static final String DATE_PATTERN_LONG = "yyyy-MM-dd HH:mm:ss";
	/** 日期格式 */
	public static final String DATE_PATTERN = "yyyy-MM-dd";
	
	public static boolean isNotNull(String str){
		if(null != str && !"".equals(str)){
			return true;
		}else{
			return false;
		}
	}
	
	public static int parseInt(String str){
		if(isNotNull(str)){
			return Integer.parseInt(str);
		}else{
			throw new RuntimeException("字符串为空,不能转换成数字");
		}
	}
	
	public static Date parseDate(String str, String pattern){
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		Date date = null;
		if(isNotNull(str)){
			try {
				date = sdf.parse(str);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}else{
			throw new RuntimeException("字符串为空,不能转换成日期");
		}
		return date;
	}
	
	public static Date parseDate(String str){
		return parseDate(str, DataOptUtil.DATE_PATTERN);
	}
	
	public static Date parseLongDate(String str){
		return parseDate(str, DataOptUtil.DATE_PATTERN_LONG);
	}
	
	public static String date2String(Date date, String pattern){
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.format(date);
	}
	
	public static String Date2String(Date date){
		return date2String(date, DataOptUtil.DATE_PATTERN);
	}
	
	public static String Date2LongString(Date date){
		return date2String(date, DataOptUtil.DATE_PATTERN_LONG);
	}
	
	public static int getSize(Collection<?> coll){
		int size = coll == null ? 0 : coll.size();
		return size;
	}
	
	public static int getSize(Map<?,?> map){
		int size = map == null ? 0 : map.size();
		return size;
	}
	
	public static int getLength(Object[] obj){
		int length = 0;
		length = obj == null ? 0 : obj.length;
		return length;
	}
}

 

还有一个自定义非受检异常类

package com.javacrazyer.common;

/**
 *
 * 自定义的非受检异常
 * 
 */
public class DAOException extends RuntimeException {

	private static final long serialVersionUID = 1047748781772098415L;

	public DAOException() {
		super();
	}

	public DAOException(String message, Throwable cause) {
		super(message, cause);
	}

	public DAOException(String message) {
		super(message);
	}

	public DAOException(Throwable cause) {
		super(cause);
	}
	
}

 

页面方面

index.html

<html>
	<head>
		 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
		<meta http-equiv="refresh" content="0; url=do.jsp" />
	</head>
</html>

 

do.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="com.javacrazyer.common.DAOFactory"%>
<%@page import="com.javacrazyer.dao.NewsDao"%>
<%@page import="com.javacrazyer.common.PageModel"%>
<%@page import="com.javacrazyer.common.DataOptUtil"%>
<%@page import="com.javacrazyer.common.Constant"%>
<%@page import="com.javacrazyer.domain.News"%>
<%
NewsDao dao=(NewsDao)DAOFactory.newInstance("newsdao");

int pageNo = 1;
String temp = request.getParameter("pageNo");
if (DataOptUtil.isNotNull(temp)) {
	pageNo = Integer.parseInt(temp);
}
int categoryid = 1;
String temp1 = request.getParameter("category_id");
if (DataOptUtil.isNotNull(temp1)) {
	categoryid = Integer.parseInt(temp1);
}
PageModel<News> pm=dao.findByPager(pageNo,Constant.PAGE_SIZE);
request.setAttribute("pm",pm);
request.setAttribute("pageNo", Integer.valueOf(pageNo));
request.setAttribute("pageSize", Constant.PAGE_SIZE);
request.getRequestDispatcher("/index.jsp").forward(request,response);
%>

 index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://javacrazyer.iteye.com/tags/pager" prefix="w"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
   <h3>新闻列表</h3><hr/>
   <table>
   <tr><td>新闻编号</td><td>新闻标题</td><td>新闻内容</td></tr> 
   <c:forEach items="${pm.datas}" var="news">
   <tr><td>${news.id}</td><td>${news.name }</td><td>${news.detail}</td></tr>
   </c:forEach>
   </table>
   <w:pager pageSize="${pageSize}" pageNo="${pageNo}" url="do.jsp" recordCount="${pm.recordCount}"/>
  </body>
</html>

 实际运行出来的效果



虽然自定义标签使用成功了,但总不可能每次开发项目都写下这个类和加上TLD文件吧,比较简洁的方式就是将编译类编译好的class文件和tld一起打成jar包,以后直接导入到项目lib中就可以使用了

 

具体步骤:将整个目录com/javacrazyer/web/tag/PagerTag.class放到一个目录中去,同时将META-INF拷贝到与com目录相同的目录下,最后将WEB-INF下的pager.tld拷贝到MET-INF下


META-INF中的文件
 

最后将com文件夹与META-INF文件选中右键添加到压缩文件,选中ZIP压缩格式



改名为jar后缀后确定,这样在同一目录就会多出一个jar来了


 

 

以后只要在需要的地方导入该分页JAR包,并且在网页上

<%@taglib uri="http://javacrazyer.iteye.com/tags/pager" prefix="w"%>

 <w:pager pageSize="${pageSize}" pageNo="${pageNo}" url="do.jsp"

 

 

 

 

 

 

  • 大小: 15.2 KB
  • 大小: 11.4 KB
  • 大小: 2.6 KB
  • 大小: 2.1 KB
  • 大小: 32.9 KB
  • 大小: 2 KB
  • JSTL_Pager.rar (991.6 KB)
  • 描述: 完整分页标签项目
  • 下载次数: 567
分享到:
评论
5 楼 sub12050223 2016-03-18  
4 楼 q280499693 2015-01-21  
主要这边少的jar包是,jstl.jar ,jsp-api.jar,commons-pool.jar如果有兴趣的朋友可以找到对应的jar包跑起来看看吧。
3 楼 q280499693 2015-01-21  
楼主,myeclipse项目,用eclipse跑起来各种缺jar包,还要我一个一个找。。。。。。不过总体来说还行,就是不知道以后能不能用上,如果有需要的朋友可以找我要吧,jar包什么我这都有,或者看看楼主能不能整理后再发一下。下边我是准备把这个tag移植到别的项目试试,嘿嘿!
2 楼 lbylbl23 2013-02-20  
少了一个dbcp.jar
1 楼 lbylbl23 2013-02-19  
试了,报错啊
org.apache.jasper.JasperException: An exception occurred processing JSP page /do.jsp at line 21

18: if (DataOptUtil.isNotNull(temp1)) {
19: categoryid = Integer.parseInt(temp1);
20: }
21: PageModel<News> pm=dao.findByPager(pageNo,Constant.PAGE_SIZE);
22: request.setAttribute("pm",pm);
23: request.setAttribute("pageNo", Integer.valueOf(pageNo));
24: request.setAttribute("pageSize", Constant.PAGE_SIZE);


Stacktrace:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:519)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:410)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

相关推荐

    struts2自定义标签案例详解

    下面以一个自定义的分页标签为例,进行说明。 其实,开发自定义标签并不需要Struts2的支持,一般情况下,只需要继承javax.servlet.jsp.tagext.BodyTagSupport类,重写doStartTag,doEndTag等方法即可。这里在实现...

    JSTL JSP 自定义标签 分页

    1.分页标签库 PageModel pagem = new PageModel(); pagem.setDtotal(168); pagem.setPerPageNum(10); pagem.executeCalculate(); if(null!=request.getParameter("cpage")){ pagem.setCpage(Integer.valueOf...

    java自定义标签分页

    采用自定义标签实现java代码轻松实现分页的功能,有图片详解有源码共享,有文档详细说明,源码详细易懂,

    低清版 大型门户网站是这样炼成的.pdf

    3.6.1 actionerror与actionmessage标签详解 166 3.6.2 fielderror标签详解 167 3.6.3 tree与treenode标签详解 168 3.7 struts 2全力支持ajax 174 3.7.1 struts 2中原始ajax技术应用 174 3.7.2 基于dwr的ajax...

    campus-market_springboot_后台管理系统_stand3fu_数据权限控制_

    springboot框架原理、freemark模板标签语法、jpa数据库操作及自动建表、统一上传文件实现方法、自定义注解实现统一验证方法、权限拦截器实现权限统一管理、自定义分页插件封装、调用控制台命令对数据库进行自动备份...

    Springboot角色权限后台管理系统脚手架实战开发教程包含完整源码

    springboot框架原理、freemark模板标签语法、jpa数据库操作及自动建表、统一上传文件实现方法、自定义注解实现统一验证方法、权限拦截器实现权限统一管理、自定义分页插件封装、调用控制台命令对数据库进行自动备份...

    最新Python3.5零基础+高级+完整项目(28周全)培训视频学习资料

    自定义分页 Cookie是什么鬼 基于Cookie实现用户登录 基于cookie实现定制显示数据条数 带签名的Cookie CBV和FBV用户认证装饰器 本周作业 第22周 上节回顾 Django之url、Views Django之Model操作 Django之模版 ...

    新坐标企业网站管理系统 v1.0.rar

    6、长文章自定义分页,以及自动清除分页。 7、添加flv视频后可自动播放,内置三种视频播放器。 8、评论管理、ajax评论系统,无刷新提交数据。 会员管理系统 1、前台快速注册。 2、也可以由管理员在后台添加会员...

    苹果8XPC和手机二合一完整版

    if标签,支持多重嵌套,每个层级的if标签不能相同 例: {if-A:[vod:num] &gt; 1 }....{endif-A} {if-A:[vod:num] mod 2=0}....{else-A}....{endif-A} {if-A:[vod:num] mod 2=0}....{elseif-A}....{else-A}....{endif-A}...

    python入门到高级全栈工程师培训 第3期 附课件代码

    07 自定义分页组件 08 DjangoForm组件初识 第59章 01 Form组件之生成HTML标签 02 Form组件之详解字段 03 Form组件之常用标签示例 04 Form组件之动态绑定数据 第60章 Django序列化共6课 第61章 01 上节内容回顾...

    新坐标企业网站管理系统 1.0

    6、长文章自定义分页,以及自动清除分页。 7、添加flv视频后可自动播放,内置三种视频播放器。 8、评论管理、ajax评论系统,无刷新提交数据。 会员管理系统 1、前台快速注册。 2、也可以由管理员在后台添加...

    精通AngularJS part1

    编写自定义过滤器——分页示例131 从JavaScript代码中访问过滤器133 过滤器做什么与不做什么134 过滤器与DOM操作135 过滤器中代价高昂的数据变换136 不稳定的过滤器136 48摘要138 第5章创建高级表单139 51...

    史上最全韩顺平传智播客PHP就业班视频,10月份全集

    9-23 6.session⑤-session配置 session的gc机制 自定义session处理器 9-24 0.回顾 9-24 1.回顾2 9-24 2.php文件编程①-文件操作原理 如何获取文件信息 如何读文件 9-24 3.php文件编程②-如何写文件 拷贝文件 创建和...

    (全)传智播客PHP就业班视频完整课程

    9-23 6.session⑤-session配置 session的gc机制 自定义session处理器 9-24 0.回顾 9-24 1.回顾2 9-24 2.php文件编程①-文件操作原理 如何获取文件信息 如何读文件 9-24 3.php文件编程②-如何写文件 拷贝文件 创建和...

    史上最全传智播客PHP就业班视频课,8月份视频

    9-23 6.session⑤-session配置 session的gc机制 自定义session处理器 9-24 0.回顾 9-24 1.回顾2 9-24 2.php文件编程①-文件操作原理 如何获取文件信息 如何读文件 9-24 3.php文件编程②-如何写文件 拷贝文件 创建和...

    韩顺平PHP JS JQUERY 所有视频下载种子 货真价实

    9-23 6.session⑤-session配置 session的gc机制 自定义session处理器 9-24 0.回顾 9-24 1.回顾2 9-24 2.php文件编程①-文件操作原理 如何获取文件信息 如何读文件 9-24 3.php文件编程②-如何写文件 拷贝文件 创建和...

    史上最全韩顺平传智播客PHP就业班视频,9月份全集

    9-23 6.session⑤-session配置 session的gc机制 自定义session处理器 9-24 0.回顾 9-24 1.回顾2 9-24 2.php文件编程①-文件操作原理 如何获取文件信息 如何读文件 9-24 3.php文件编程②-如何写文件 拷贝文件 创建和...

    IBM WebSphere Portal门户开发笔记01

    6、自定义登录跳转页面 45 7、判断用户是否登录标签 46 8、portal登录注销再登录只出现一张图片 46 9、登录失败及修改提示信息 46 10、设置超时跳转页面 47 11、 输出登录用户名称 47 12、输出注销 48 13 、动态链接...

    Ext+JS高级程序设计.rar

    1.3 DomQuery详解 20 1.4 模板介绍 23 1.5 实用功能 24 1.6 定时执行代码 25 1.7 本章小结 26 第2章 Ext Core实例系统设计 27 2.1 需求分析 27 2.2 系统设计 28 2.3 功能结构图 29 2.4 开发与运行环境 31 2.5 数据库...

    机智内容管理系统2.0

    这是一个简单但又伸缩性很强的CMS,简单自定义标签即可构造各种形式的展示模块. 全站生成静态化,使网站运行速度更快. 并且本CMS为开源免费提供广大用户使用. 作者QQ: 13699576 mail: badwolf@qq.com 网站: ...

Global site tag (gtag.js) - Google Analytics