目录
3.2.2 导入完成jar包,我们开始编写src中的各类包中的类
3.2.3 完成以上操作,我们开始编写前端JSP页面层的编写
3.2.3 完成页面编写,我们在WEB-INF开始需要配置MVC以及自定义分页标签的编写
一、什么是MVC?
MVC全名:Model View Controller,其中Model(模型层)、View(视图层)、Controller(控制层)
它是一种软件设计典范,用于业务逻辑处理、数据、界面显示分离,
常用模式:
model1:jsp+jdbc
model2:mvc
问:三层架构和MVC的区别?
答:三层架构是一个经典的分层思想,将开发模式分为三层,每个人专注自己擅长模块即可
MVC是一种设计模式,其目的是让html和业务逻辑分开
二、MVC结构及原理
V(视图层)
C(控制层)
M(模型层)
注:1)不能跨层调用;
2)只能由上往下进行调用;View -> Controller -> Model
2.1自定义MVC工作原理图:
*.action 调度 截取*(请求路径名) 处理具体业务逻辑
JSP -----------> Servlet(中央控制器)--------------------->Action(子控制器)--->Model(Dao、DB)
三、项目布局
我们使用MVC架构来搭建一个简单的图书管理系统
实现效果:
自定义MVC展示
3.1 数据库表的构建
①首先我们先编写MySQL中的SQL语句,就是创建表格,具体代码如下:
这里我使用的工具是navicat编写
/*
Navicat Premium Data Transfer
Source Server : localhost
Source Server Type : MySQL
Source Server Version : 50723
Source Host : localhost:3306
Source Schema : ajf
Target Server Type : MySQL
Target Server Version : 50723
File Encoding : 65001
Date: 09/07/2022 09:31:19
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for tb_book
-- ----------------------------
DROP TABLE IF EXISTS `tb_book`;
#创建数据库——使用数据库——创建表格——插入数据
#这里我使用的是AJF数据库
use ajf;
CREATE TABLE `tb_book` (
`bid` int(11) NOT NULL AUTO_INCREMENT COMMENT '书籍编号',
`bname` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '书本名称',
`bpinyin` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '书本拼音',
`bprice` float DEFAULT 0 COMMENT '书本价格',
`btype` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '书本类型',
PRIMARY KEY (`bid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 104 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '书本信息表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_book
-- ----------------------------
#数据是随便加的
INSERT INTO `tb_book` VALUES (1, '史记第1章', 'sjd1z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (2, '史记第2章', 'sjd2z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (3, '史记第3章', 'sjd3z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (4, '史记第4章', 'sjd4z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (5, '史记第5章', 'sjd5z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (6, '史记第6章', 'sjd6z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (7, '史记第7章', 'sjd7z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (8, '史记第8章', 'sjd8z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (9, '史记第9章', 'sjd9z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (10, '史记第10章', 'sjd10z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (11, '史记第11章', 'sjd11z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (12, '史记第12章', 'sjd12z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (13, '史记第13章', 'sjd13z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (14, '史记第14章', 'sjd14z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (15, '史记第15章', 'sjd15z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (16, '史记第16章', 'sjd16z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (17, '史记第17章', 'sjd17z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (18, '史记第18章', 'sjd18z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (19, '史记第19章', 'sjd19z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (20, '史记第20章', 'sjd20z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (21, '史记第21章', 'sjd21z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (22, '史记第22章', 'sjd22z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (23, '史记第23章', 'sjd23z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (24, '史记第24章', 'sjd24z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (25, '史记第25章', 'sjd25z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (26, '史记第26章', 'sjd26z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (27, '史记第27章', 'sjd27z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (28, '史记第28章', 'sjd28z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (29, '史记第29章', 'sjd29z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (30, '史记第30章', 'sjd30z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (31, '史记第31章', 'sjd31z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (32, '史记第32章', 'sjd32z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (33, '史记第33章', 'sjd33z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (34, '史记第34章', 'sjd34z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (35, '史记第35章', 'sjd35z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (36, '史记第36章', 'sjd36z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (37, '史记第37章', 'sjd37z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (38, '史记第38章', 'sjd38z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (39, '史记第39章', 'sjd39z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (40, '史记第40章', 'sjd40z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (41, '史记第41章', 'sjd41z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (42, '史记第42章', 'sjd42z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (43, '史记第43章', 'sjd43z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (44, '史记第44章', 'sjd44z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (45, '史记第45章', 'sjd45z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (46, '史记第46章', 'sjd46z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (47, '史记第47章', 'sjd47z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (48, '史记第48章', 'sjd48z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (50, '史记第50章', 'sjd50z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (52, '稀有', 'xy', 100, '哈哈');
INSERT INTO `tb_book` VALUES (53, '王者', 'wz', 100, '可以');
INSERT INTO `tb_book` VALUES (54, '史记第1章', 'sjd1z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (55, '史记第2章', 'sjd2z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (56, '史记第3章', 'sjd3z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (57, '史记第4章', 'sjd4z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (58, '史记第5章', 'sjd5z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (59, '史记第6章', 'sjd6z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (60, '史记第7章', 'sjd7z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (61, '史记第8章', 'sjd8z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (62, '史记第9章', 'sjd9z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (63, '史记第10章', 'sjd10z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (64, '史记第11章', 'sjd11z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (65, '史记第12章', 'sjd12z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (66, '史记第13章', 'sjd13z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (67, '史记第14章', 'sjd14z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (68, '史记第15章', 'sjd15z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (69, '史记第16章', 'sjd16z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (70, '史记第17章', 'sjd17z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (71, '史记第18章', 'sjd18z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (72, '史记第19章', 'sjd19z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (73, '史记第20章', 'sjd20z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (74, '史记第21章', 'sjd21z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (75, '史记第22章', 'sjd22z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (76, '史记第23章', 'sjd23z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (77, '史记第24章', 'sjd24z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (78, '史记第25章', 'sjd25z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (79, '史记第26章', 'sjd26z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (80, '史记第27章', 'sjd27z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (81, '史记第28章', 'sjd28z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (82, '史记第29章', 'sjd29z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (83, '史记第30章', 'sjd30z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (84, '史记第31章', 'sjd31z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (85, '史记第32章', 'sjd32z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (86, '史记第33章', 'sjd33z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (87, '史记第34章', 'sjd34z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (88, '史记第35章', 'sjd35z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (89, '史记第36章', 'sjd36z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (90, '史记第37章', 'sjd37z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (91, '史记第38章', 'sjd38z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (92, '史记第39章', 'sjd39z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (93, '史记第40章', 'sjd40z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (94, '史记第41章', 'sjd41z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (95, '史记第42章', 'sjd42z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (96, '史记第43章', 'sjd43z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (97, '史记第44章', 'sjd44z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (98, '史记第45章', 'sjd45z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (99, '史记第46章', 'sjd46z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (100, '史记第47章', 'sjd47z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (101, '史记第48章', 'sjd48z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (102, '史记第49章', 'sjd49z', 34.5, '神话');
SET FOREIGN_KEY_CHECKS = 1;
3.2 创建一个JavaWeb项目
由于为了提高编程效率,项目中还缺少方法接口定义以及业务逻辑层的处理,还请大家理解!
我们需要按照以上来构建我们的图书管理项目
3.2.1 我们先导入指定的jar包文件
commons-beanutils-1.8.0.jar ——JAVA BEAN的工具包,Java反射机制来完毕代码中所须要的功能
commons-logging.jar ——使用spring的必备包,用来记录程序运行时的活动的日志记录
dom4j-1.6.1.jar ——优秀的JavaXML API,用来读写XML文件
jaxen-1.1-beta-6.jar ——使用XPath以简化dom4j查找节点时必须导入jaxen-1.1-beta-6.jar,否则会出现异常
jstl-1.2.jar ——SP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能
mvc.jar ——自定义MVCjar包
mysql-connector-java-5.1.44-bin.jar ——连接MySQLjar包
pinyin4j-2.5.0.jar ——拼音转换jar包
standard-1.1.2.jar ——是jar包,于jstl-1.2版本合用
3.2.2 导入完成jar包,我们开始编写src中的各类包中的类
util包: 路径:com.zking.mvcplus.util
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
#这里我们使用的是Oracle,所以其它的可以不使用
#mysql
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/AJF?useUnicode=true&characterEncoding=UTF-8&useSSL=false
user=root
pwd=1234
CommonUtils.java ——反射遍历rs通用类
package com.zking.mvcplus.util;
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.zking.mvcplus.util;
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.zking.mvcplus.util;
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();
}
}
}
PageBean.java ——分页类
package com.zking.mvcplus.util;
import java.io.Serializable;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
public class PageBean implements Serializable {
//页码
private int page=1;
//每页显示条数
private int rows=10;
//总记录数
private int total=0;
//是否分页标记
private boolean pagination=true;
//上一次请求的路径
private String url;
//请求参数Map集合
private Map<String,String[]> map;
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;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public boolean isPagination() {
return pagination;
}
public void setPagination(boolean pagination) {
this.pagination = pagination;
}
//重载setPage/setRows/setPagination方法
public void setPage(String page) {
if(null!=page&&!"".equals(page))
this.page=Integer.parseInt(page);
}
public void setRows(String rows) {
if(null!=rows&&!"".equals(rows))
this.rows=Integer.parseInt(rows);
}
public void setPagination(String pagination) {
if(null!=pagination&&!"".equals(pagination))
this.pagination=Boolean.parseBoolean(pagination);
}
public void setRequest(HttpServletRequest req) {
//获取前端提交的page/rows/pagination参数
String page=req.getParameter("page");
String rows=req.getParameter("rows");
String pagination=req.getParameter("pagination");
//设置属性
this.setPage(page);
this.setPagination(pagination);
this.setRows(rows);
//设置上一次请求的路径
//第一次请求:
//http://localhost:8080/项目名/请求路径.action?page=1
//第二次请求:下一页 page=2
//项目名+请求路径.action
//req.getContextPath()+req.getServletPath()==req.getRequestURI()
this.url=req.getRequestURI();
//获取请求参数集合
// checkbox name='hobby'
// Map<String,String[]> hobby==key value==new String[]{"篮球","足球",..}
this.map=req.getParameterMap();
}
/**
* 获取分页的起始位置
* @return
*/
public int getStartIndex() {
//第1页:(1-1)*10 ==0 limit 0,10
//第2页:(2-1)*10 ==10 limit 10,10
//..
return (this.page-1)*this.rows;
}
//获取末页、上一页、下一页
/**
* 获取末页
* @return
*/
public int getMaxPager() {
int maxPager=this.total/this.rows;
if(this.total%this.rows!=0)
maxPager++;
return maxPager;
}
/**
* 获取上一页
* @return
*/
public int getPreviousPager() {
int previousPager=this.page-1;
if(previousPager<=1)
previousPager=1;
return previousPager;
}
/**
* 获取下一页
* @return
*/
public int getNextPager() {
int nextPager=this.page+1;
if(nextPager>getMaxPager())
nextPager=getMaxPager();
return nextPager;
}
@Override
public String toString() {
return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination
+ ", url=" + url + ", map=" + map + "]";
}
}
PinYinUtil.java ——拼音转换类
package com.zking.mvcplus.util;
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.zking.mvcplus.util;
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);
}
}
entity包 路径:com.zking.mvcplus.entity
Book.java ——书籍实体类
package com.zking.mvcplus.util;
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);
}
}
dao包 路径:com.zking.mvcplus.dao
BaseDao.java ——简写增删改查方法实体类
package com.zking.mvcplus.dao;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import com.zking.mvcplus.util.DBHelper;
import com.zking.mvcplus.util.PageBean;
public class BaseDao<T> {
public static interface CallBack<K>{
//该方法只用于循环遍历ResultSet结果集,并返回List<T>结果
public List<K> foreachRs(ResultSet rs) throws SQLException;
}
/**
* 通过的增删改方法
* @param sql sql语句
* @param params sql语句的参数数组
*/
public void executeUpdate(String sql,Object[] params) {
Connection conn=null;
PreparedStatement stmt=null;
try {
conn=DBHelper.getConnection();
stmt=conn.prepareStatement(sql);
ParameterMetaData metaData = stmt.getParameterMetaData();
for (int i = 0; i < metaData.getParameterCount(); i++) {
stmt.setObject(i+1, params[i]);
}
int i = stmt.executeUpdate();
if(i<1)
throw new RuntimeException("执行失败,影响行数为0!");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
DBHelper.close(conn, stmt, null);
}
}
/**
* 通用分页方法(既支持分页,也可以不分页)
* @param sql 普通的SQL
* @param pageBean 分页对象(包含分页三要素)
* @return 返回查询结果集
*/
public List<T> executeQuery(String sql,
PageBean pageBean,CallBack<T> callback){
Connection conn=null;
PreparedStatement stmt=null;
ResultSet rs=null;
try {
//获取连接对象
conn=DBHelper.getConnection();
//判断是否分页
if(null!=pageBean&&pageBean.isPagination()) {
//1.分页(总记录数、分页查询)
//1) 根据满足条件获取总记录数的SQL
String countSQL = this.getCountSQL(sql);
//创建执行对象
stmt=conn.prepareStatement(countSQL);
//执行SQL并返回总记录数
rs=stmt.executeQuery();
if(rs.next()) {
int total = rs.getInt(1);
pageBean.setTotal(total);
}
//2) 根据满足条件获取查询分页结果集的SQL limit
sql=this.getPagerSQL(sql, pageBean);
}
//创建执行对象
stmt=conn.prepareStatement(sql);
//执行SQL并返回总记录数
rs=stmt.executeQuery();
//将rs结果集存入到foreachRs方法中
return callback.foreachRs(rs);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
DBHelper.close(conn, stmt, rs);
}
return null;
}
/**
* 将普通的SQL语句转换成查询总记录数的SQL语句
* select * from t_book
* select * from t_book where ...
* select book_id,book_name from t_book
* select book_id,book_name from t_book where ...
* ------->
* select count(0) from t_book where ...
* @param sql 普通的SQL
* @return 查询总记录数的SQL
*/
private String getCountSQL(String sql) {
return "select count(0) from ("+sql+") temp";
}
/**
* 将普通的SQL语句转换成查询分页结果集的SQL(说白了就是拼接limit)
* select * from t_book
* select * from t_book where ...
* select book_id,book_name from t_book
* select book_id,book_name from t_book where ...
* ------->
* select * from t_book limit
* @param sql 普通的SQL
* @param pageBean 分页对象
* @return 分页查询的SQL
*/
private String getPagerSQL(String sql,PageBean pageBean) {
return sql+" limit "+pageBean.getStartIndex()+","+pageBean.getRows();
}
}
BookDao.java ——书籍方法实体类
package com.zking.mvcplus.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import com.zking.mvcplus.entity.Book;
import com.zking.mvcplus.util.CommonUtils;
import com.zking.mvcplus.util.PageBean;
import com.zking.mvcplus.util.PinYinUtil;
import com.zking.mvcplus.util.StringUtils;
public class BookDao extends BaseDao<Book> {
/**
* 1.书本新增
* @param book
*/
public void addBook(Book book) {
String sql="insert into tb_book(bname,bpinyin,"
+ "bprice,btype) values(?,?,?,?)";
super.executeUpdate(sql, new Object[] {
book.getBname(),
PinYinUtil.toPinyin(book.getBname()).toLowerCase(),
book.getBprice(),
book.getBtype()
});
}
/**
* 2.书本编辑
* @param book
*/
public void editBook(Book book) {
String sql="update tb_book set bname=?,bpinyin=?,"
+ "bprice=?,btype=? where bid=?";
super.executeUpdate(sql, new Object[] {
book.getBname(),
PinYinUtil.toPinyin(book.getBname()).toLowerCase(),
book.getBprice(),
book.getBtype(),
book.getBid()
});
}
/**
* 3.书本删除
* @param book
*/
public void delBook(Book book) {
String sql="delete from tb_book where bid=?";
super.executeUpdate(sql, new Object[] {
book.getBid()
});
}
/**
* 4.根据书本ID查询单个书本信息
* @param book
* @return
*/
public Book queryBookById(Book book) {
String sql="select bid,bname,bpinyin,"
+ "bprice,btype from tb_book "
+ "where bid="+book.getBid();
System.out.println(sql);
List<Book> lst = super.executeQuery(sql, null, new CallBack<Book>() {
@Override
public List<Book> foreachRs(ResultSet rs) throws SQLException {
return CommonUtils.toList(rs, Book.class);
}
});
if(null!=lst&&lst.size()!=0)
return lst.get(0);
else
return null;
}
/**
* 5.分页查询
* @param book
* @return
*/
public List<Book> queryBookPager(Book book,PageBean pageBean) {
String sql="select bid,bname,bpinyin,"
+ "bprice,btype from tb_book "
+ "where 1=1";
//按照书本名称模糊查询
if(StringUtils.isNotBlank(book.getBname()))
sql+=" and bname like '%"+book.getBname()+"%'";
//按照书本编号降序排序
sql+=" order by bid desc";
System.out.println(sql);
return super.executeQuery(sql, pageBean, new CallBack<Book>() {
@Override
public List<Book> foreachRs(ResultSet rs) throws SQLException {
return CommonUtils.toList(rs, Book.class);
}
});
}
}
BookDaoTest.java ——方法测试类 junit
package com.zking.mvcplus.dao;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.zking.mvcplus.entity.Book;
import com.zking.mvcplus.util.PageBean;
public class BookDaoTest {
Book book=null;
BookDao bookDao=new BookDao();
@Before
public void setUp() throws Exception {
book=new Book();
}
@After
public void tearDown() throws Exception {
}
@Test
public void testAddBook() {
book.setBname("围城");
book.setBprice(100f);
book.setBtype("散文");
bookDao.addBook(book);
}
@Test
public void testEditBook() {
book.setBid(81);
book.setBname("凡人修仙传");
book.setBprice(120f);
book.setBtype("修仙");
bookDao.editBook(book);
}
@Test
public void testDelBook() {
book.setBid(80);
bookDao.delBook(book);
}
@Test
public void testQueryBookById() {
book.setBid(80);
Book b = bookDao.queryBookById(book);
System.out.println(b);
}
@Test
public void testQueryBookPager() {
PageBean pageBean=new PageBean();
List<Book> books = bookDao.queryBookPager(book, pageBean);
System.out.println("总记录数:"+pageBean.getTotal());
books.forEach(System.out::println);
}
}
action包 路径:com.zking.mvcplus.action
BookAction.java ——servlet后端处理
package com.zking.mvcplus.action;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zking.mvc.framework.DispatcherAction;
import com.zking.mvc.framework.DriverModel;
import com.zking.mvcplus.dao.BookDao;
import com.zking.mvcplus.entity.Book;
import com.zking.mvcplus.util.PageBean;
/**
* XxxAction extends Action -> execute 做一件事情
* XxxAction extends DispatcherAction 做多件事情
* 注意:
* 1)该子控制器类Action中提供一组与execute方法相同的参数和返回值,只有方法名不相同的方法
* 2)必须要传递methodName的参数,该参数表示方法名,用于反射调用方法
* 3)每一次创建子控制器类Action,请先到mvc.xml配置文件中定义对应关系(重要!!)
* @author Administrator
*
*/
public class BookAction extends DispatcherAction implements DriverModel<Book> {
private Book book=new Book();
private BookDao bookDao=new BookDao();
@Override
public Book getModel() {
return book;
}
/**
* 书本新增
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String addBook(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
bookDao.addBook(book);
return "list";
}
/**
* 书本编辑
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String editBook(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
bookDao.editBook(book);
return "list";
}
/**
* 书本删除
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String delBook(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
bookDao.delBook(book);
return "list";
}
/**
* 分页查询书本信息
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String queryBookPager(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
PageBean pageBean=new PageBean();
pageBean.setRequest(req);
List<Book> books = bookDao.queryBookPager(book, pageBean);
//将查询的书本分页结果集和PageBean对象保存到request中
req.setAttribute("books", books);
req.setAttribute("pageBean", pageBean);
return "success";
}
/**
* 查询单个书本对象,跳转到编辑或者详情页面
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String selectOne(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
//根据书本ID查询单个书本信息
Book b = bookDao.queryBookById(book);
//将查询书本对象保存到request中
req.setAttribute("book", b);
//根据前端传入的参数type判断跳转到编辑还是详情页面
String type = req.getParameter("type");
//判断类型
if("edit".equals(type))
return "edit";
else
return "detail";
}
}
tag包 路径:com.zking.mvcplus.tag
PaginationTag.java ——分页实现类
package com.zking.mvcplus.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.zking.mvcplus.util.PageBean;
public class PaginationTag extends BodyTagSupport {
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.isPagination())
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("首页 上一页 ");
else {
sb.append("<a href=\"javascript:gotoPage(1)\">首页</a> ");
sb.append("<a href=\"javascript:gotoPage("+pageBean.getPreviousPager()+")\">上一页</a> ");
}
if(pageBean.getPage()==pageBean.getMaxPager())
sb.append("下一页 末页 ");
else {
sb.append("<a href=\"javascript:gotoPage("+pageBean.getNextPager()+")\">下一页</a> ");
sb.append("<a href=\"javascript:gotoPage("+pageBean.getMaxPager()+")\">末页</a> ");
}
//拼接跳转页码
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;
}
}
然后就是src根目录下的自定义标签的xml文件编写
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE config[
<!ELEMENT config (action*)>
<!ELEMENT action (forward*)>
<!ELEMENT forward EMPTY>
<!ATTLIST action
path CDATA #REQUIRED
type CDATA #REQUIRED
>
<!ATTLIST forward
name CDATA #REQUIRED
path CDATA #REQUIRED
redirect (true|false) "false"
>
]>
<!--
config标签:可以包含0~N个action标签
-->
<config>
<action type="com.zking.mvcplus.action.BookAction" path="/bookAction">
<forward name="list" path="/bookAction.action?methodName=queryBookPager" redirect="true"/>
<forward name="success" path="/bookList.jsp"/>
<forward name="edit" path="/editBook.jsp"/>
<forward name="detail" path="/bookDetail.jsp"/>
</action>
</config>
3.2.3 完成以上操作,我们开始编写前端JSP页面层的编写
addBook.jsp ——增加书籍的界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>Insert title here</title>
</head>
<body>
<h1>书本新增</h1>
<form action="bookAction.action?methodName=addBook" method="post">
<label>书本名称:</label><input type="text" name="bname"/><br/>
<label>书本价格:</label><input type="text" name="bprice"/><br/>
<label>书本类型:</label><input type="text" name="btype"/><br/>
<input type="submit" value="新增"/>
</form>
</body>
</html>
bookDetail.jsp ——书本详情界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>Insert title here</title>
</head>
<body>
<h1>书本详情</h1>
${book }
</body>
</html>
bookList.jsp ——书本主界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@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>Insert title here</title>
</head>
<body>
<form action="bookAction.action?methodName=queryBookPager" method="post">
<label>书本名称:</label><input type="text" name="bname"/>
<input type="submit" value="查询"/>
</form>
<a href="addBook.jsp">书本新增</a>
<table width="100%" border="1" cellpadding="0" cellspacing="0">
<tr>
<th>书本编号</th>
<th>书本名称</th>
<th>书本拼音</th>
<th>书本价格</th>
<th>书本类型</th>
<th>操作</th>
</tr>
<c:forEach items="${books }" var="b">
<tr>
<td>${b.bid }</td>
<td>${b.bname }</td>
<td>${b.bpinyin }</td>
<td>${b.bprice }</td>
<td>${b.btype }</td>
<td>
<a href="bookAction.action?methodName=selectOne&type=edit&bid=${b.bid }">编辑</a>
<a href="bookAction.action?methodName=selectOne&type=detail&bid=${b.bid }">详情</a>
<a onclick="return confirm('确认要删除吗?');" href="bookAction.action?methodName=delBook&bid=${b.bid }">删除</a>
</td>
</tr>
</c:forEach>
</table>
<z:pagination pageBean="${pageBean }"/>
</body>
</html>
editBook.jsp ——修改书本界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>Insert title here</title>
</head>
<body>
<h1>书本编辑</h1>
<form action="bookAction.action?methodName=editBook" method="post">
<input type="hidden" value="${book.bid }" name="bid"/>
<label>书本名称:</label><input type="text" name="bname" value="${book.bname }"/><br/>
<label>书本价格:</label><input type="text" name="bprice" value="${book.bprice }"/><br/>
<label>书本类型:</label><input type="text" name="btype" value="${book.btype }"/><br/>
<input type="submit" value="编辑"/>
</form>
</body>
</html>
3.2.3 完成页面编写,我们在WEB-INF开始需要配置MVC以及自定义分页标签的编写
web.xml ——系统文件,主要用于配置servlet、filter、listenner
<?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>mvcPlus</display-name>
<!-- 配置中文乱码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>com.zking.mvcplus.util.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置中央控制器ActionServlet -->
<servlet>
<servlet-name>actionServlet</servlet-name>
<servlet-class>com.zking.mvc.framework.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>actionServlet</servlet-name>
<url-pattern>*.action</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.zking.mvcplus.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>
以上就是本章所有内容,感谢观看!