J2EE_06 快速入门 Web通用分页

目录

 

一、前言

二、实现效果

三、代码示例

        ①MySQL部分:

        ②Jar包的导入介绍:

        ③MVC框架搭建:     

​编辑   

        ③配置web.xml和自定义xml文件(WEB-INF文件夹下)

        ④编写JSP显示界面文件


一、前言

        ①背景:

           面对编程而言,对于前台和后台或者网页显示数据的时候,可能会经常性的用到分页的功能,而我们在处理这种情况的时候,我们通常会写很多重复的代码,本文章讲的就是如何通过去解决重复分页代码问题。

        ②工具:1.Eclipse——安装        2.MySQL——安装​​​​​​​        3.Tomcat——安装

        ④jar包:1.jstl-1.2.jar、2.mysql-connector-java-5.1.44-bin.jar、3.pinyin4j-2.5.0.jar、4.standard-1.1.2.jar        jar包可以在浏览器查找

        本章中有一些是没有用上的通用代码,由于本章内容有限,仅供大家提供思路

二、实现效果

书籍分页效果

        本章重点是介绍技术的实现,因此界面相对而言比较简陋。

三、代码示例

        ①MySQL部分:

        首先我们得安装好mySQL数据库

        安装完成之后,我们进行表格的代码创建,我们需要先创建数据库本次使用的是ajf数据库,然后再创建表tb_book,以书籍表为例:

#使用你所创建的数据库
use ajf;
#创建表格
create table tb_book(
bid int not null primary key auto_increment comment '书籍编号',
bname varchar(30) not null comment '书本名称',
bpinyin varchar(30) comment '书本拼音',
bprice float default 0 comment '书本价格',
btype varchar(10) not null comment '书本类型'
) comment '书本信息表';
#自增序列:auto_increment
#mysql分页:limit 参数1,参数2
#参数1:从第几条数据开始(不包含起始位置)
#参数2:每次返回多少条数据
#第一页:从0开始,返3条
#第二页:从3开始,返3条	
#……
#以此类推		规律:页码:(page-1)*row		条数:row
#示例:
select * from tb_book limit 0,3;
#删除表格
drop table tb_book;
#查询表格
select * from tb_book;
#清空数据(不留痕迹)
truncate table tb_book;
#清空数据(可以恢复)
delete table tb_book;
#清空数据的范围大小:drop > truncate > delete

        ②Jar包的导入介绍:

         接下来就是准备导入一些jar包(工具包)了,注意:导入的jar包是在WEB-INF文件夹中的lib文件夹中

                jstl-1.2.jar、  standard-1.1.2.jar        属于:jstl中的jar包
                mysql-connector-java-5.1.44-bin.jar        属于:mySQLjar包
                pinyin4j-2.5.0.jar        属于:文字转拼音jar包
        当我们已经准备好jar包之后,那我们就可以按照MVC模式去搭建环境了。

        ③MVC框架搭建:     

  

        我们需要建立以下几个包:  1.utils    2.entity   3.dao    4.servlet   5.tag

        1.utils部分:        

        CommonUtils.java        ——遍历rs结果通用工具类

package com.web.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CommonUtils {

	// 反射封装ResultSet结果集
	public static <T> List<T> toList(ResultSet rs, Class cla) {
		// 定义返回结果
		List<T> lst = new ArrayList<T>();
		try {
			// 获取ResultSet中的列信息
			ResultSetMetaData metaData = rs.getMetaData();
			// 获取对象中的所有属性数组
			Field[] fields = cla.getDeclaredFields();
			// 循环遍历结果集ResultSet
			while (rs.next()) {
				// 通过反射机制实例化对象
				T obj = (T) cla.newInstance();
				// 循环遍历metaData
				for (int i = 0; i < metaData.getColumnCount(); i++) {
					// 获取SQL语句中的列名
					String colName = metaData.getColumnLabel(i + 1);
					// 循环遍历Fields数组
					for (Field field : fields) {
						// 获取属性名
						String fName = field.getName();
						// 判断数据表中的列名与实体中的属性名是否一致
						if (fName.toUpperCase().equals(colName.toUpperCase())) {
							// 拼接set方法 set+属性名首字母大写
							String methodName = "set" + fName.substring(0, 1).toUpperCase() + fName.substring(1);
							// 反射调用方法
							Method method = cla.getDeclaredMethod(methodName, field.getType());
							// 设置访问权限
							method.setAccessible(true);
							// 执行方法
							method.invoke(obj, rs.getObject(colName));
							break;
						}
					}
				}
				lst.add(obj);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return lst;
	}

	public static List<Map<String, Object>> toList(ResultSet rs) {
		// 定义返回结果
		List<Map<String, Object>> lst = new ArrayList<Map<String, Object>>();
		try {
			// 获取ResultSet中的列信息
			ResultSetMetaData metaData = rs.getMetaData();
			// 循环遍历结果集ResultSet
			while (rs.next()) {
				Map<String,Object> obj=new HashMap<String,Object>();
				// 循环遍历metaData
				for (int i = 0; i < metaData.getColumnCount(); i++) {
					// 获取SQL语句中的列名
					String colName = metaData.getColumnLabel(i + 1);
					obj.put(colName,rs.getObject(colName));
				}
				lst.add(obj);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return lst;
	}
}

        DBHelper.java        ——数据库帮助实现类

package com.web.utils;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * 提供了一组获得或关闭数据库对象的方法
 * 
 */
public class DBHelper {
	private static String driver;
	private static String url;
	private static String user;
	private static String password;

	static {// 静态块执行一次,加载 驱动一次
		try {
			InputStream is = DBHelper.class
					.getResourceAsStream("config.properties");

			Properties properties = new Properties();
			properties.load(is);

			driver = properties.getProperty("driver");
			url = properties.getProperty("url");
			user = properties.getProperty("user");
			password = properties.getProperty("pwd");

			Class.forName(driver);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	/**
	 * 获得数据连接对象
	 * 
	 * @return
	 */
	public static Connection getConnection() {
		try {
			Connection conn = DriverManager.getConnection(url, user, password);
			return conn;
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	public static void close(ResultSet rs) {
		if (null != rs) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}

	public static void close(Statement stmt) {
		if (null != stmt) {
			try {
				stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}

	public static void close(Connection conn) {
		if (null != conn) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}

	public static void close(Connection conn, Statement stmt, ResultSet rs) {
		close(rs);
		close(stmt);
		close(conn);
	}

	public static boolean isOracle() {
		return "oracle.jdbc.driver.OracleDriver".equals(driver);
	}

	public static boolean isSQLServer() {
		return "com.microsoft.sqlserver.jdbc.SQLServerDriver".equals(driver);
	}
	
	public static boolean isMysql() {
		return "com.mysql.jdbc.Driver".equals(driver);
	}

	public static void main(String[] args) {
		Connection conn = DBHelper.getConnection();
		DBHelper.close(conn);
		System.out.println("isOracle:" + isOracle());
		System.out.println("isSQLServer:" + isSQLServer());
		System.out.println("isMysql:" + isMysql());
		System.out.println("数据库连接(关闭)成功");
	}
}

        EncodingFilter.java        ——处理中文乱码情况过滤器

package com.web.utils;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 中文乱码处理
 * 
 */
public class EncodingFilter implements Filter {

	private String encoding = "UTF-8";// 默认字符集

	public EncodingFilter() {
		super();
	}

	public void destroy() {
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;

		// 中文处理必须放到 chain.doFilter(request, response)方法前面
		res.setContentType("text/html;charset=" + this.encoding);
		if (req.getMethod().equalsIgnoreCase("post")) {
			req.setCharacterEncoding(this.encoding);
		} else {
			Map map = req.getParameterMap();// 保存所有参数名=参数值(数组)的Map集合
			Set set = map.keySet();// 取出所有参数名
			Iterator it = set.iterator();
			while (it.hasNext()) {
				String name = (String) it.next();
				String[] values = (String[]) map.get(name);// 取出参数值[注:参数值为一个数组]
				for (int i = 0; i < values.length; i++) {
					values[i] = new String(values[i].getBytes("ISO-8859-1"),
							this.encoding);
				}
			}
		}

		chain.doFilter(request, response);
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		String s = filterConfig.getInitParameter("encoding");// 读取web.xml文件中配置的字符集
		if (null != s && !s.trim().equals("")) {
			this.encoding = s.trim();
		}
	}

}

        MD5.java        ——对字符串加密工具类

package com.web.utils;

/**
 * 使用MD5算法对字符串进行加密的工具类。 MD5即Message-Digest
 * Algorithm5(信息-摘要算法5),是一种用于产生数字签名的单项散列算法, 这个算法是不可逆的,
 * 也就是说即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串
 * 
 */
public class MD5 {
	/*
	 * 下面这些S11-S44实际上是一个4*4的矩阵,在原始的C实现中是用#define 实现的, 这里把它们实现成为static
	 * final是表示了只读,切能在同一个进程空间内的多个 Instance间共享
	 */
	private static final int S11 = 7;

	private static final int S12 = 12;

	private static final int S13 = 17;

	private static final int S14 = 22;

	private static final int S21 = 5;

	private static final int S22 = 9;

	private static final int S23 = 14;

	private static final int S24 = 20;

	private static final int S31 = 4;

	private static final int S32 = 11;

	private static final int S33 = 16;

	private static final int S34 = 23;

	private static final int S41 = 6;

	private static final int S42 = 10;

	private static final int S43 = 15;

	private static final int S44 = 21;

	private static final byte[] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0 };

	/*
	 * 下面的三个成员是MD5计算过程中用到的3个核心数据,在原始的C实现中 被定义到MD5_CTX结构中
	 * 
	 */
	private long[] state = new long[4]; // state (ABCD)

	private long[] count = new long[2];// number of bits, modulo 2^64(lsbfirst)

	private byte[] buffer = new byte[64]; // input buffer

	/*
	 * digest,是最新一次计算结果的2进制内部表示,表示128bit的MD5值.
	 */
	private byte[] digest = new byte[16];

	public MD5() {
		md5Init();
	}

	/*
	 * getMD5ofStr是类MD5最主要的公共方法,入口参数是你想要进行MD5变换的字符串
	 * 返回的是变换完的结果,这个结果是从公共成员digestHexStr取得的.
	 */
	public String getMD5ofStr(String inbuf) {
		md5Init();
		md5Update(inbuf.getBytes(), inbuf.length());
		md5Final();
		String digestHexStr = "";
		for (int i = 0; i < 16; i++) {
			digestHexStr += byteHEX(digest[i]);
		}
		return digestHexStr;

	}

	/* md5Init是一个初始化函数,初始化核心变量,装入标准的幻数 */
	private void md5Init() {
		count[0] = 0L;
		count[1] = 0L;
		// /* Load magic initialization constants.

		state[0] = 0x67452301L;
		state[1] = 0xefcdab89L;
		state[2] = 0x98badcfeL;
		state[3] = 0x10325476L;
		return;
	}

	/*
	 * F, G, H ,I 是4个基本的MD5函数,在原始的MD5的C实现中,由于它们是
	 * 简单的位运算,可能出于效率的考虑把它们实现成了宏,在java中,我们把它们 实现成了private方法,名字保持了原来C中的。
	 */

	private long F(long x, long y, long z) {
		return (x & y) | ((~x) & z);

	}

	private long G(long x, long y, long z) {
		return (x & z) | (y & (~z));

	}

	private long H(long x, long y, long z) {
		return x ^ y ^ z;
	}

	private long I(long x, long y, long z) {
		return y ^ (x | (~z));
	}

	/*
	 * FF,GG,HH和II将调用F,G,H,I进行近一步变换 FF, GG, HH, and II transformations for
	 * rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent
	 * recomputation.
	 */

	private long FF(long a, long b, long c, long d, long x, long s, long ac) {
		a += F(b, c, d) + x + ac;
		a = ((int) a << s) | ((int) a >>> (32 - s));
		a += b;
		return a;
	}

	private long GG(long a, long b, long c, long d, long x, long s, long ac) {
		a += G(b, c, d) + x + ac;
		a = ((int) a << s) | ((int) a >>> (32 - s));
		a += b;
		return a;
	}

	private long HH(long a, long b, long c, long d, long x, long s, long ac) {
		a += H(b, c, d) + x + ac;
		a = ((int) a << s) | ((int) a >>> (32 - s));
		a += b;
		return a;
	}

	private long II(long a, long b, long c, long d, long x, long s, long ac) {
		a += I(b, c, d) + x + ac;
		a = ((int) a << s) | ((int) a >>> (32 - s));
		a += b;
		return a;
	}

	/*
	 * md5Update是MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个
	 * 函数由getMD5ofStr调用,调用之前需要调用md5init,因此把它设计成private的
	 */
	private void md5Update(byte[] inbuf, int inputLen) {

		int i, index, partLen;
		byte[] block = new byte[64];
		index = (int) (count[0] >>> 3) & 0x3F;
		// /* Update number of bits */
		if ((count[0] += (inputLen << 3)) < (inputLen << 3))
			count[1]++;
		count[1] += (inputLen >>> 29);

		partLen = 64 - index;

		// Transform as many times as possible.
		if (inputLen >= partLen) {
			md5Memcpy(buffer, inbuf, index, 0, partLen);
			md5Transform(buffer);

			for (i = partLen; i + 63 < inputLen; i += 64) {

				md5Memcpy(block, inbuf, 0, i, 64);
				md5Transform(block);
			}
			index = 0;

		} else

			i = 0;

		// /* Buffer remaining input */
		md5Memcpy(buffer, inbuf, index, i, inputLen - i);

	}

	/*
	 * md5Final整理和填写输出结果
	 */
	private void md5Final() {
		byte[] bits = new byte[8];
		int index, padLen;

		// /* Save number of bits */
		Encode(bits, count, 8);

		// /* Pad out to 56 mod 64.
		index = (int) (count[0] >>> 3) & 0x3f;
		padLen = (index < 56) ? (56 - index) : (120 - index);
		md5Update(PADDING, padLen);

		// /* Append length (before padding) */
		md5Update(bits, 8);

		// /* Store state in digest */
		Encode(digest, state, 16);

	}

	/*
	 * md5Memcpy是一个内部使用的byte数组的块拷贝函数,从input的inpos开始把len长度的
	 * 字节拷贝到output的outpos位置开始
	 */

	private void md5Memcpy(byte[] output, byte[] input, int outpos, int inpos,
			int len) {
		int i;

		for (i = 0; i < len; i++)
			output[outpos + i] = input[inpos + i];
	}

	/*
	 * md5Transform是MD5核心变换程序,有md5Update调用,block是分块的原始字节
	 */
	private void md5Transform(byte block[]) {
		long a = state[0], b = state[1], c = state[2], d = state[3];
		long[] x = new long[16];

		Decode(x, block, 64);

		/* Round 1 */
		a = FF(a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */
		d = FF(d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */
		c = FF(c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */
		b = FF(b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */
		a = FF(a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */
		d = FF(d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */
		c = FF(c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */
		b = FF(b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */
		a = FF(a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */
		d = FF(d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */
		c = FF(c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */
		b = FF(b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */
		a = FF(a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */
		d = FF(d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */
		c = FF(c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */
		b = FF(b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */

		/* Round 2 */
		a = GG(a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */
		d = GG(d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */
		c = GG(c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */
		b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */
		a = GG(a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */
		d = GG(d, a, b, c, x[10], S22, 0x2441453L); /* 22 */
		c = GG(c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */
		b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */
		a = GG(a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */
		d = GG(d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */
		c = GG(c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */
		b = GG(b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */
		a = GG(a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */
		d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */
		c = GG(c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */
		b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */

		/* Round 3 */
		a = HH(a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */
		d = HH(d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */
		c = HH(c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */
		b = HH(b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */
		a = HH(a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */
		d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */
		c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */
		b = HH(b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */
		a = HH(a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */
		d = HH(d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */
		c = HH(c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */
		b = HH(b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */
		a = HH(a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */
		d = HH(d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */
		c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */
		b = HH(b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */

		/* Round 4 */
		a = II(a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */
		d = II(d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */
		c = II(c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */
		b = II(b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */
		a = II(a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */
		d = II(d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */
		c = II(c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */
		b = II(b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */
		a = II(a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */
		d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */
		c = II(c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */
		b = II(b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */
		a = II(a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */
		d = II(d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */
		c = II(c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */
		b = II(b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */

		state[0] += a;
		state[1] += b;
		state[2] += c;
		state[3] += d;

	}

	/*
	 * Encode把long数组按顺序拆成byte数组,因为java的long类型是64bit的, 只拆低32bit,以适应原始C实现的用途
	 */
	private void Encode(byte[] output, long[] input, int len) {
		int i, j;

		for (i = 0, j = 0; j < len; i++, j += 4) {
			output[j] = (byte) (input[i] & 0xffL);
			output[j + 1] = (byte) ((input[i] >>> 8) & 0xffL);
			output[j + 2] = (byte) ((input[i] >>> 16) & 0xffL);
			output[j + 3] = (byte) ((input[i] >>> 24) & 0xffL);
		}
	}

	/*
	 * Decode把byte数组按顺序合成成long数组,因为java的long类型是64bit的,
	 * 只合成低32bit,高32bit清零,以适应原始C实现的用途
	 */
	private void Decode(long[] output, byte[] input, int len) {
		int i, j;

		for (i = 0, j = 0; j < len; i++, j += 4)
			output[i] = b2iu(input[j]) | (b2iu(input[j + 1]) << 8)
					| (b2iu(input[j + 2]) << 16) | (b2iu(input[j + 3]) << 24);

		return;
	}

	/*
	 * b2iu是我写的一个把byte按照不考虑正负号的原则的"升位"程序,因为java没有unsigned运算
	 */
	private static long b2iu(byte b) {
		return b < 0 ? b & 0x7F + 128 : b;
	}

	/*
	 * byteHEX(),用来把一个byte类型的数转换成十六进制的ASCII表示,
	 * 因为java中的byte的toString无法实现这一点,我们又没有C语言中的 sprintf(outbuf,"%02X",ib)
	 */
	private static String byteHEX(byte ib) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
				'B', 'C', 'D', 'E', 'F' };
		char[] ob = new char[2];
		ob[0] = Digit[(ib >>> 4) & 0X0F];
		ob[1] = Digit[ib & 0X0F];
		String s = new String(ob);
		return s;
	}

	public static void main(String args[]) {
		String source = "888888";
		MD5 md5 = new MD5();
		String s1 = md5.getMD5ofStr(source);// length=32
		System.out.println(s1);
		//21218CCA77804D2BA1922C33E0151105
	}
}

        PinYinUtil.java        ——汉字转拼音工具类

package com.web.utils;

import java.util.regex.Pattern;

import net.sourceforge.pinyin4j.PinyinHelper;


/**
 * 拼音工具类,能将汉字转换成拼音的首字母
 */
public class PinYinUtil {
	/* 用于中文判断的正则表达式 */
	private static final String regexStr = "[\u4e00-\u9fa5]";

	/**
	 * 将一个字符串中的汉字转换成拼音首字母、非汉字则不变
	 * 
	 * @param cn
	 *            String
	 * @return String
	 */
	public static String toPinyin(String cn) {
		String pinyin = null;
		if (null == cn || 0 == cn.trim().length()) {
			return pinyin;
		}

		/* 去掉字符串前后的空格 */
		cn = cn.trim();
		char[] chineseCharacterArr = cn.toCharArray(); // 转换成汉字字符数组
		char[] letteCharacterArr = new char[chineseCharacterArr.length]; // 字母字符数组
		for (int i = 0; i < chineseCharacterArr.length; i++) {
			// 得到汉字拼音的首字母
			letteCharacterArr[i] = getFirstLetterFromPinyin(chineseCharacterArr[i]);
		}

		if (0 != letteCharacterArr.length) {
			pinyin = new String(letteCharacterArr);
			pinyin = pinyin.toUpperCase();
		}
		return pinyin;
	}

	/* 得到一个汉字的拼音的首字母 */
	private static char getFirstLetterFromPinyin(char cn) {
		// 判断cn是否为一个合法的汉字,不是则直接返回cn
		if (!isChineseCharacters(cn)) {
			return cn;
		}

		String[] pyArr = PinyinHelper.toHanyuPinyinStringArray(cn);
		char py = pyArr[0].charAt(0);
		return py;
	}

	/**
	 * 判断字符是否为一个汉字
	 * 
	 * @param cn
	 *            char
	 * @return boolean
	 */
	public static boolean isChineseCharacters(char cn) {
		boolean b = false;
		if (Pattern.matches(regexStr, String.valueOf(cn))) {
			b = true;
		}
		return b;
	}

	public static void main(String[] args) {
		String s = "任保存并加入题库";
		System.out.println(PinYinUtil.toPinyin(s).toLowerCase());
	}

}

                StringUtils.java        ——判断字符串是否为空方法类

package com.web.utils;

public class StringUtils {
	// 私有的构造方法,保护此类不能在外部实例化
	private StringUtils() {
	}

	/**
	 * 如果字符串等于null或去空格后等于"",则返回true,否则返回false
	 * 
	 * @param s
	 * @return
	 */
	public static boolean isBlank(String s) {
		boolean b = false;
		if (null == s || s.trim().equals("")) {
			b = true;
		}
		return b;
	}
	
	/**
	 * 如果字符串不等于null或去空格后不等于"",则返回true,否则返回false
	 * 
	 * @param s
	 * @return
	 */
	public static boolean isNotBlank(String s) {
		return !isBlank(s);
	}

}

        config.properties        ——连接数据库信息存放文件

#oracle9i
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@localhost:1521:orcl
#user=scott
#pwd=123


#sql2005
#driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
#url=jdbc:sqlserver://localhost:1433;DatabaseName=test1
#user=sa
#pwd=123


#sql2000
#driver=com.microsoft.jdbc.sqlserver.SQLServerDriver
#url=jdbc:microsoft:sqlserver://localhost:1433;databaseName=unit6DB
#user=sa
#pwd=888888


#mysql
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/AJF?useUnicode=true&characterEncoding=UTF-8&useSSL=false
#url=jdbc:mysql://localhost:3306/bookshop?useUnicode=true&characterEncoding=UTF-8
user=root
pwd=1234

        2.entity:

        Book.java        ——书籍实体类

package com.web.entity;

import java.io.Serializable;

/**
 * 书籍实体类(对应编写的mysql中的tb_book表中的字段)
 * @author Administrator
 *
 */
public class Book implements Serializable {

	/**
	 * 唯一编号
	 */
	private static final long serialVersionUID = 1L;

	private Integer bid;//书籍编号
	private String bname;//书籍名字
	private String bpinyin;//书籍拼音
	private Float bprice;//书籍价格
	private String btype;//书籍类型
	
	public Book() {
		
	}

	public Book(Integer bid, String bname, String bpinyin, Float bprice, String btype) {
		super();
		this.bid = bid;
		this.bname = bname;
		this.bpinyin = bpinyin;
		this.bprice = bprice;
		this.btype = btype;
	}

	public Book(String bname, String bpinyin, Float bprice, String btype) {
		super();
		this.bname = bname;
		this.bpinyin = bpinyin;
		this.bprice = bprice;
		this.btype = btype;
	}

	public Integer getBid() {
		return bid;
	}

	public void setBid(Integer bid) {
		this.bid = bid;
	}

	public String getBname() {
		return bname;
	}

	public void setBname(String bname) {
		this.bname = bname;
	}

	public String getBpinyin() {
		return bpinyin;
	}

	public void setBpinyin(String bpinyin) {
		this.bpinyin = bpinyin;
	}

	public Float getBprice() {
		return bprice;
	}

	public void setBprice(Float bprice) {
		this.bprice = bprice;
	}

	public String getbtype() {
		return btype;
	}

	public void setbtype(String btype) {
		this.btype = btype;
	}

	@Override
	public String toString() {
		return "Book [bid=" + bid + ", bname=" + bname + ", bpinyin=" + bpinyin + ", bprice=" + bprice + ", btype="
				+ btype + "]";
	}
}

        PageBean.java        ——书籍分页实体类

package com.web.entity;

import java.io.Serializable;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

public class PageBean implements Serializable {

	/**
	 * 唯一编号
	 */
	private static final long serialVersionUID = 1L;
	
	private Integer page = 1;//页码
	private Integer rows = 10;//行数
	private Integer total = 0;//总条数
	private boolean pageination = true;//是否分页
	
	//保存文件地址
	private String url;
	//保存参数
	private Map<String, String[]> map;
	
	public PageBean() {
		
	}
	
	/**
	 * 获取前端传入的请求参数
	 * @param req 请求对象
	 */
	public void setRequest(HttpServletRequest req) {
		//获取前端传入的请求参数(分页三要素)
		String page = req.getParameter("page");
		String rows = req.getParameter("rows");
		String pagination = req.getParameter("pagination");
		
		//将结果保存到本类对象中
		this.setPage(page);
		this.setRows(rows);
		this.setPageination(pagination);
		
		//获取上一次请求的请求路径
		// http://localhost:8080/pagination/bookAction.action
		// req.getRequestURI()==/pagination/bookAction.action
		// req.getContextPath()==/pagination
		// req.getServletPath()==/bookAction.action
		this.url = req.getRequestURI();
		
		// name="bookname"  -> put("bookname",new String[]{"1"})
		// <input type="hidden" name="bookname" value="1"/>
		//获取上一次请求的请求参数 Map<String,String[]>
		this.map = req.getParameterMap();
	}
	
	//获取最大页码
	public int getMaxPager() {
		int max = this.total/this.getRows();
		if(this.total%this.rows!=0)
			max++;
		return max;
	}
	//上一页
	public int getProviousPager() {
		int pro = this.page-1;
		//判断页码
		if(pro<1)
			pro=1;
		return pro;
	}
	
	//下一页
	public int getNextPager() {
		int next = this.page+1;
		if(next>=this.getMaxPager())
			next=this.getMaxPager();
		return next;
	}
	public PageBean(Integer page, Integer rows, Integer total, boolean pageination) {
		super();
		this.page = page;
		this.rows = rows;
		this.total = total;
		this.pageination = pageination;
	}
	
	
	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public Map<String, String[]> getMap() {
		return map;
	}

	public void setMap(Map<String, String[]> map) {
		this.map = map;
	}

	//计算开始的limit分页开始的位置
	public Integer getStartIndex() {
		return (page-1)*this.rows;
	}
	//页码
	public Integer getPage() {
		return page;
	}
	
	public void setPage(String page) {
		if(null!=page)
		this.page = Integer.parseInt(page);
	}
	//行数
	public Integer getRows() {
		return rows;
	}

	public void setRows(String rows) {
		if(null!=rows)
		this.rows = Integer.parseInt(rows);
	}
	//总条数
	public Integer getTotal() {
		return total;
	}

	public void setTotal(Integer total) {
		this.total = total;
	}

	public boolean isPageination() {
		return pageination;
	}

	public void setPageination(String pageination) {
		if(null!=pageination)
		this.pageination = Boolean.parseBoolean(pageination);
	}

	@Override
	public String toString() {
		return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pageination=" + pageination
				+ ", url=" + url + ", map=" + map + "]";
	}

}

        3.dao:

        BaseDao.java        ——简写增删改查通用方法类

package com.web.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import com.web.utils.DBHelper;

/**
 * 通用增删改查简写方法
 * 
 * @author Administrator
 *
 */
public class BaseDao {
	protected Connection conn = null;// 连接对象
	protected PreparedStatement stmt = null;// 执行对象
	protected ResultSet rs = null;// 结果集对象
	protected Integer n;

	/**
	 * 通用增删改方法
	 * 
	 * @param sql
	 *            普通sql
	 * @param obj
	 *            可变参数
	 * @return n 影响行数
	 */
	public Integer executeUpdate(String sql, Object... obj) {
		// 获取连接对象
		conn = DBHelper.getConnection();
		try {
			// 获取执行对象
			stmt = conn.prepareStatement(sql);
			// 判断是否存在数据
			// 需要给占位符进行赋值
			if (null != obj) {
				for (int i = 0; i < obj.length; i++) {
					stmt.setObject(i + 1, obj[i]);
				}
			}
			// 进行执行
			n = stmt.executeUpdate();
			System.out.println(n);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.close(conn, stmt, null);
		}
		// 结果返出
		return n;
	}

	/**
	 * 通用查询方法
	 * 
	 * @param sql
	 *            普通sql
	 * @param obj
	 *            可变参数
	 * @return rs 结果集对象
	 */
	public ResultSet executeQuery(String sql, Object... obj) {
		// 获取连接对象
		conn = DBHelper.getConnection();
		try {
			// 获取执行对象
			stmt = conn.prepareStatement(sql);
			// 判断是否存在数据
			// 需要给占位符进行赋值
			if (null != obj) {
				for (int i = 0; i < obj.length; i++) {
					stmt.setObject(i + 1, obj[i]);
				}
			}
			// 进行执行
			rs = stmt.executeQuery();
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 结果返出
		return rs;
	}
}

        BaseDaob.java        ——分页实现方法类

package com.web.dao;

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

import com.web.entity.PageBean;
import com.web.utils.DBHelper;

public class BaseDaob<T> {
	public static interface CallBack<K>{
		//该方法只用于遍历rs结果集对象中的数据,并返回List<T>结果
		//最后面谁要去遍历结果集,谁就得去实现这个接口的方法
		public List<K> foreachRs(ResultSet rs) throws SQLException;
	}
	
	
	public List<T> executeQuery(String sql, PageBean pb, CallBack<T> callback){
		Connection conn = null;//连接对象
		PreparedStatement stmt = null;//
		ResultSet rs = null;
		List<T> list = null;
		try {
			conn = DBHelper.getConnection();
			//获取连接对象
			stmt = conn.prepareStatement(sql);
			//判断是否分页
			if(null!=pb && pb.isPageination()) {
				//①确定是否分页
				//①根据条件获取总记录条数
				String countSQL = this.getCountSQL(sql);
				//创建执行对象
				stmt = conn.prepareStatement(countSQL);
				//执行SQL并返回总记录数
				rs = stmt.executeQuery();
				System.out.println(rs.toString());
				//由于只有单挑记录,因此使用if
				if(rs.next()) {
					pb.setTotal(rs.getInt(1));
				}
				//②根据满足条件获取查询SQL——limit
				sql = this.getPageSQL(sql, pb);
			}
			//②满足条件的分页查询SQL
			//①不分页(普通查询)
			//①根据满足条件查询数据
			//②根据满足条件获取查询SQL——limit
			//创建执行对象
			System.out.println(sql);
			stmt = conn.prepareStatement(sql);
			//执行
			rs = stmt.executeQuery();
			//将rs存入到foreachRs()方法中
			 list = callback.foreachRs(rs); 
			 return list;
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			DBHelper.close(conn, stmt, rs);
		}
		return list;
	}
	
	private String getCountSQL(String sql) {
		return "select count(0) from ("+sql+") temp";
	}
	
	private String getPageSQL(String sql, PageBean pb) {
		return sql+" limit "+pb.getStartIndex()+","+pb.getRows();
	}
	
}

        BookDao.java        ——书籍方法类

package com.web.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.web.dao.BaseDaob.CallBack;
import com.web.entity.Book;
import com.web.entity.PageBean;
import com.web.utils.DBHelper;
import com.web.utils.StringUtils;

public class BookDao extends BaseDao {
	private List<Book> list = null;
	private Book book = null;

	// 增
	/**
	 * 增加书籍
	 * 
	 * @param book
	 *            书籍信息
	 */
	public void addBook(Book book) {
		// System.out.println(book);
		Integer n = this.executeUpdate("insert into tb_book(bname,bpinyin,bprice,btype) values(?,?,?,?)",
				new Object[] { book.getBname(), book.getBpinyin(), book.getBprice(), book.getbtype() });
		// 判断抛出异常
		if (n == 0) {
			throw new RuntimeException("影响行数为0,执行失败");
		}
	}

	// 删

	// 改

	// 查
	public List<Book> queryBookDim(Book book, PageBean pb) {
		// 实例化list集合
		list = new ArrayList<Book>();
		//定义sql
		String sql = "select bid,bname,bpinyin,bprice,btype from tb_book where 1=1";
		// 判断book中bname属性是否为空
		if (StringUtils.isNotBlank(book.getBname())) {
			sql += " and bname like '%" + book.getBname() + "%'";
			// 按照编号降序排序
			sql += " order by bid desc";
		}
		System.out.println(sql);
		return new BaseDaob<Book>().executeQuery(sql, pb, new CallBack<Book>() {
			
			public List<Book> foreachRs(ResultSet rs) throws SQLException {
				list = new ArrayList<Book>();
				try {
					// 遍历
					while (rs.next()) {
						Book book = new Book();
						// 将数据封装到Book实体对象中
						book = new Book(rs.getInt("bid"), rs.getString("bname"), rs.getString("bpinyin"), rs.getFloat("bprice"),
								rs.getString("btype"));
						// 添加到集合中
						list.add(book);
					}
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					DBHelper.close(conn, stmt, rs);
				}
				return list;
			}
			
		});
		
	/*	System.out.println(sql);
		// 执行返回rs结果集对象
		ResultSet rs = this.executeQuery(sql);
		try {
			// 遍历保存数据
			while (rs.next()) {
				book = new Book(rs.getInt("bid"), rs.getString("bname"), rs.getString("bpinyin"), rs.getFloat("bprice"),
						rs.getString("btype"));
				// 添加到集合中
				list.add(book);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.close(conn, stmt, rs);
		}
		return list;*/
	}
}

        BookDaoTest.java        ——书籍方法测试类

package com.web.dao;

import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.web.entity.Book;
import com.web.entity.PageBean;
import com.web.utils.PinYinUtil;

/**
 * 测试BookDao类方法
 * @author Administrator
 *
 */
public class BookDaoTest {
/**
 * 规律:每执行一个测试方法,setUp()方法优先执行,测试方法再执行,最后执行tearDown()方法
 */
	
	Book book = null;//实体
	BookDao bookDao = new BookDao();
	@Before
	public void setUp() throws Exception {
		//System.out.println("setUp");
		book = new Book();
		
		
		
	}

	@After
	public void tearDown() throws Exception {
		//System.out.println("tearDown");
	}

	@Test
	public void testAddBook() {
		//System.out.println("testAddBook");
		//循环添加50条书籍信息
		for (int i = 1; i <= 50; i++) {
			book = new Book();
			book.setBname("史记第"+i+"章");
			book.setBpinyin(PinYinUtil.toPinyin("史记第"+i+"章").toLowerCase());
			book.setBprice(34.5f);
			book.setbtype("神话");
			//System.out.println(book);
			//调用添加数据的方法
			bookDao.addBook(book);
		}
	}

	@Test
	public void testQueryBookDim() {
		//System.out.println("testQueryBookDim");
		PageBean pb = new PageBean();
		pb.setPage("2");
		pb.setRows("5");
		List<Book> books = bookDao.queryBookDim(book, pb);
		System.out.println(books);
		System.out.println("总记录数:"+pb.getTotal());
		books.forEach(System.out::println);
	}

}

        4.servlet:

        BookServlet.java        ——实现数据(是否分页)显示servlet

package com.web.dao;

import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.web.entity.Book;
import com.web.entity.PageBean;
import com.web.utils.PinYinUtil;

/**
 * 测试BookDao类方法
 * @author Administrator
 *
 */
public class BookDaoTest {
/**
 * 规律:每执行一个测试方法,setUp()方法优先执行,测试方法再执行,最后执行tearDown()方法
 */
	
	Book book = null;//实体
	BookDao bookDao = new BookDao();
	@Before
	public void setUp() throws Exception {
		//System.out.println("setUp");
		book = new Book();
		
		
		
	}

	@After
	public void tearDown() throws Exception {
		//System.out.println("tearDown");
	}

	@Test
	public void testAddBook() {
		//System.out.println("testAddBook");
		//循环添加50条书籍信息
		for (int i = 1; i <= 50; i++) {
			book = new Book();
			book.setBname("史记第"+i+"章");
			book.setBpinyin(PinYinUtil.toPinyin("史记第"+i+"章").toLowerCase());
			book.setBprice(34.5f);
			book.setbtype("神话");
			//System.out.println(book);
			//调用添加数据的方法
			bookDao.addBook(book);
		}
	}

	@Test
	public void testQueryBookDim() {
		//System.out.println("testQueryBookDim");
		PageBean pb = new PageBean();
		pb.setPage("2");
		pb.setRows("5");
		List<Book> books = bookDao.queryBookDim(book, pb);
		System.out.println(books);
		System.out.println("总记录数:"+pb.getTotal());
		books.forEach(System.out::println);
	}

}

        5.tag:

        PaginationTag.java        ——自定义标签帮助类(通过该类实现分页)

package com.web.tag;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

import com.web.entity.PageBean;

public class PaginationTag extends BodyTagSupport {

	/**
	 * 唯一编号
	 */
	private static final long serialVersionUID = 1L;
	private PageBean pageBean;
	
	@Override
	public int doEndTag() throws JspException {
		return EVAL_PAGE;
	}

	@Override
	public int doStartTag() throws JspException {
		JspWriter out = pageContext.getOut();
		try {
			out.write(toHtml());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return SKIP_BODY;
	}
	
	private String toHtml() {
		//判断是否分页
		if(null==pageBean||!pageBean.isPageination())
			return "";
		else {
			StringBuilder sb=new StringBuilder();
			//TODO
			sb.append("<div style=\"float:right\">");
			
			//拼接Form表单
			sb.append("<form id=\"pageBeanForm\" action=\""+pageBean.getUrl()+"\" method=\"post\">");
			
			//设置page隐藏域
			sb.append("<input type=\"hidden\" name=\"page\"/>");
			
			//拼接请求参数集合
			Map<String, String[]> map = pageBean.getMap();
			//获取请求参数集合键值对
			Set<Entry<String,String[]>> entrySet = map.entrySet();
			//遍历请求参数键值对
			for (Entry<String, String[]> entry : entrySet) {
				//获取请求参数名,也就是来自于表单中的name属性名称
				String name=entry.getKey();
				//如果参数为page,则continue跳过
				if(name.equals("page"))
					continue;
				//获取请求参数对应的值,String[]
				String[] values=entry.getValue();
				//遍历value值
				for (String value : values) {
					//拼接请求参数
					sb.append("<input type='hidden' name='"+name+"' value='"+value+"'/>");
				}
			}
			
			sb.append("</form>");
			
			//拼接共几页/第几页
			sb.append("共"+pageBean.getMaxPager()+"页/第"+pageBean.getPage()+"页,");
			
			//拼接首页、上一页、下一页、末页
			if(pageBean.getPage()==1)
				sb.append("首页&nbsp;上一页&nbsp;");
			else {
				sb.append("<a href=\"javascript:gotoPage(1)\">首页</a>&nbsp;");
				sb.append("<a href=\"javascript:gotoPage("+pageBean.getProviousPager()+")\">上一页</a>&nbsp;");
			}
			if(pageBean.getPage()==pageBean.getMaxPager())
				sb.append("下一页&nbsp;末页&nbsp;");
			else {
				sb.append("<a href=\"javascript:gotoPage("+pageBean.getNextPager()+")\">下一页</a>&nbsp;");
				sb.append("<a href=\"javascript:gotoPage("+pageBean.getMaxPager()+")\">末页</a>&nbsp;");
			}
			
			//拼接跳转页码
			sb.append("<input type=\"text\" id=\"p\" style=\"width:20px;\"/>");
			sb.append("<input type=\"button\" value=\"GO\" onclick=\"javascript:skipPage();\"/>");
			
			//拼接javascript跳转方法
			sb.append("<script type=\"text/javascript\">\r\n" + 
					"function gotoPage(page){\r\n" + 
					"	document.getElementById(\"pageBeanForm\").page.value=page;\r\n" + 
					"	document.getElementById(\"pageBeanForm\").submit();\r\n" + 
					"}");
			
			sb.append("function skipPage(){\r\n" + 
					"	var page=document.getElementById(\"p\").value;\r\n" + 
					"	if(isNaN(page)||page<1||page>="+pageBean.getMaxPager()+"){\r\n" + 
					"		alert('请输入1~"+pageBean.getMaxPager()+"之间数字!');\r\n" + 
					"		return false;\r\n" + 
					"	}\r\n" + 
					"	gotoPage(page);\r\n" + 
					"}\r\n" + 
					"</script>");
			
			sb.append("</div>");
			return sb.toString();
		}
	}

	public PageBean getPageBean() {
		return pageBean;
	}

	public void setPageBean(PageBean pageBean) {
		this.pageBean = pageBean;
	}
}

        ③配置web.xml和自定义xml文件(WEB-INF文件夹下)

        web.xml        ——web项目中的标签配置文件(一般用于配置:servlet和filter和listener)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>Web_03</display-name>
  
  <!-- 配置过滤器 -->
   <filter>
  <filter-name>encodingFilter</filter-name>
  <filter-class>com.web.utils.EncodingFilter</filter-class>
    </filter>
  
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    
 
     <!-- 配置servlet -->
  <servlet>
  <servlet-name>bookSelect</servlet-name>
  <servlet-class>com.web.servlet.BookServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>bookSelect</servlet-name>
    <url-pattern>/bookServlet.do</url-pattern>
    </servlet-mapping>
    
       
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

        z.tld        ——自定义xml

<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
   "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- 标签库描述符 -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
	<!-- 代表标签库的版本号 -->
	<tlib-version>1.0</tlib-version>
	<!-- 代表jsp的版本 -->
	<jsp-version>1.2</jsp-version>
	<!-- 你的标签库的简称 -->
	<short-name>z</short-name>
	<!-- 你标签库的引用uri -->
	<uri>/zking</uri>

	<tag>
		<!-- 标签名 -->
		<name>pagination</name>
		<!-- 标签工具类 -->
		<!-- 利用反射机制,通过Class.forName(类的全路径名/包名+类名)的方式反射机制实例化标签助手类 -->
		<tag-class>com.web.tag.PaginationTag</tag-class>
		<!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 -->
		<body-content>empty</body-content>
		<!-- 自定义标签的属性定义,请注意一定要在标签类中提供对应的get/set方法 -->
		<attribute>
			<!-- 自定义标签的属性名称 -->
			<name>pageBean</name>
			<!-- true表示必填 -->
			<required>true</required>
			<!-- true支持动态值,可以向值里面填jsp表达式、EL表达式,false则不支持 -->
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>
</taglib>

        ④编写JSP显示界面文件

        bookList.jsp        ——书籍展示界面

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!-- 引入jstl -->
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- 引入自定义标签 -->
<%@taglib prefix="z" uri="/zking"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>书籍</title>
<!-- css样式 -->
<style type="text/css">
late {
	float: right;
}
</style>
</head>
<body>
	<center>
		<!-- 表单 -->
		<form action="bookServlet.do" method="post">
			<label>书本名称:</label> <input type="text" name="bname" /> <input
				type="submit" value="搜索" />
		</form>
		<br />
		<!-- 表格 -->
		<table width="100%" border="1" cellpadding="0" cellspacing="0"
			style="text-align: center">
			<tr>
				<th>书籍编号</th>
				<th>书籍名称</th>
				<th>书籍拼音</th>
				<th>书籍价格</th>
				<th>书籍类型</th>
			</tr>
			<!-- jstl遍历 -->
			<c:forEach items="${queryBookDim }" var="book">
				<tr>
					<td>${book.bid }</td>
					<td>${book.bname }</td>
					<td>${book.bpinyin }</td>
					<td>${book.bprice }</td>
					<td>${book.btype }</td>
				</tr>
			</c:forEach>
		</table>
	</center>
	<br>
	<br>
	<%-- ${pageBean } --%>
	<!-- 自定义版本 -->
	<%-- <div id="late">
		<form id="ff" action="${pageBean.getUrl() }" method="post">
			<input type="hidden" name="page" />
			<!-- 在此处循环遍历pageBean中的params并动态生成input type="hidden" -->
		</form>
		第${pageBean.getPage() }页/页${pageBean.getMaxPager() }码
		老版本:
		<a href="${pageBean.url }?page=1">首页</a>
		<a href="${pageBean.url }?page=${pageBean.getProviousPager() }">上一页</a>
		<a href="${pageBean.url }?page=${pageBean.getNextPager() }">下一页</a>
		<a href="${pageBean.url }?page=${pageBean.getMaxPager() }">尾页</a>
		<!-- 新版本: -->
		<a href="javascript:gotoPage(1)">首页</a> <a
			href="javascript:gotoPage(${pageBean.getProviousPager()})">上一页</a> <a
			href="javascript:gotoPage(${pageBean.getNextPager()})">下一页</a> <a
			href="javascript:gotoPage(${pageBean.getMaxPager()})">末页</a> <input
			type="text" id="skip" style="width: 15px" /> <input type="button"
			value="GO" onclick="javascript:skipPage(${pageBean.getMaxPager()})" />
	</div> --%>
	<!-- 引入自定义的jstl标签 -->
	<z:pagination pageBean="${pageBean }" />
	<!-- js代码 -->
	<!-- <script type="text/javascript">
function gotoPage(p){
	document.getElementById('ff').page.value=p;
	document.getElementById('ff').submit();
}
function skipPage(max){
	var page=document.getElementById('skip').value;
	if(isNaN(page)||page<1||page>max){
		alert('请输入1~'+max+'之间的数字!');
		return false;
	}
	gotoPage(page);
}
</script> -->
</body>
</html>

        以上就是本章的全部内容!感谢观看!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值