javaWeb学习笔记-smbms项目

目录

一、项目搭建

二、登录流程实现

三、注销及权限过滤

四、修改密码实现

五、Ajax验证旧密码

六、用户管理分页实现

七、角色管理分页实现

八、文件上传原理及实现

九、发送邮件原理及实现


Gitee仓库:狂神-smbms: 学习狂神的课程,练习项目 - Gitee.com

一、项目搭建

 数据库建表脚本

DROP TABLE IF EXISTS `smbms_address`;
CREATE TABLE `smbms_address`  (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `contact` VARCHAR(15) NULL DEFAULT NULL COMMENT '联系人姓名',
  `addressDesc` VARCHAR(50) NULL DEFAULT NULL COMMENT '收货地址明细',
  `postCode` VARCHAR(15) NULL DEFAULT NULL COMMENT '邮编',
  `tel` VARCHAR(20) NULL DEFAULT NULL COMMENT '联系人电话',
  `createdBy` BIGINT(20) NULL DEFAULT NULL COMMENT '创建者',
  `creationDate` DATETIME NULL DEFAULT NULL COMMENT '创建时间',
  `modifyBy` BIGINT(20) NULL DEFAULT NULL COMMENT '修改者',
  `modifyDate` DATETIME NULL DEFAULT NULL COMMENT '修改时间',
  `userId` BIGINT(20) NULL DEFAULT NULL COMMENT '用户ID',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `smbms_address` VALUES (1, '王丽', '北京市东城区东交民巷44号', '100010', '13678789999', 1, '2016-04-13 00:00:00', NULL, NULL, 1);
INSERT INTO `smbms_address` VALUES (2, '张红丽', '北京市海淀区丹棱街3号', '100000', '18567672312', 1, '2016-04-13 00:00:00', NULL, NULL, 1);
INSERT INTO `smbms_address` VALUES (3, '任志强', '北京市东城区美术馆后街23号', '100021', '13387906742', 1, '2016-04-13 00:00:00', NULL, NULL, 1);
INSERT INTO `smbms_address` VALUES (4, '曹颖', '北京市朝阳区朝阳门南大街14号', '100053', '13568902323', 1, '2016-04-13 00:00:00', NULL, NULL, 2);
INSERT INTO `smbms_address` VALUES (5, '李慧', '北京市西城区三里河路南三巷3号', '100032', '18032356666', 1, '2016-04-13 00:00:00', NULL, NULL, 3);
INSERT INTO `smbms_address` VALUES (6, '王国强', '北京市顺义区高丽营镇金马工业区18号', '100061', '13787882222', 1, '2016-04-13 00:00:00', NULL, NULL, 3);

DROP TABLE IF EXISTS `smbms_bill`;
CREATE TABLE `smbms_bill`  (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `billCode` VARCHAR(20) NULL DEFAULT NULL COMMENT '账单编码',
  `productName` VARCHAR(20) NULL DEFAULT NULL COMMENT '商品名称',
  `productDesc` VARCHAR(50) NULL DEFAULT NULL COMMENT '商品描述',
  `productUnit` VARCHAR(10) NULL DEFAULT NULL COMMENT '商品单位',
  `productCount` DECIMAL(20, 2) NULL DEFAULT NULL COMMENT '商品数量',
  `totalPrice` DECIMAL(20, 2) NULL DEFAULT NULL COMMENT '商品总额',
  `isPayment` INT(10) NULL DEFAULT NULL COMMENT '是否支付(1:未支付 2:已支付)',
  `createdBy` BIGINT(20) NULL DEFAULT NULL COMMENT '创建者(userId)',
  `creationDate` DATETIME NULL DEFAULT NULL COMMENT '创建时间',
  `modifyBy` BIGINT(20) NULL DEFAULT NULL COMMENT '更新者(userId)',
  `modifyDate` DATETIME NULL DEFAULT NULL COMMENT '更新时间',
  `providerId` BIGINT(20) NULL DEFAULT NULL COMMENT '供应商ID',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `smbms_bill` VALUES (2, 'BILL2016_002', '香皂、肥皂、药皂', '日用品-皂类', '块', 1000.00, 10000.00, 2, 1, '2016-03-23 04:20:40', NULL, NULL, 13);
INSERT INTO `smbms_bill` VALUES (3, 'BILL2016_003', '大豆油', '食品-食用油', '斤', 300.00, 5890.00, 2, 1, '2014-12-14 13:02:03', NULL, NULL, 6);
INSERT INTO `smbms_bill` VALUES (4, 'BILL2016_004', '橄榄油', '食品-进口食用油', '斤', 200.00, 9800.00, 2, 1, '2013-10-10 03:12:13', NULL, NULL, 7);
INSERT INTO `smbms_bill` VALUES (5, 'BILL2016_005', '洗洁精', '日用品-厨房清洁', '瓶', 500.00, 7000.00, 2, 1, '2014-12-14 13:02:03', NULL, NULL, 9);
INSERT INTO `smbms_bill` VALUES (6, 'BILL2016_006', '美国大杏仁', '食品-坚果', '袋', 300.00, 5000.00, 2, 1, '2016-04-14 06:08:09', NULL, NULL, 4);
INSERT INTO `smbms_bill` VALUES (7, 'BILL2016_007', '沐浴液、精油', '日用品-沐浴类', '瓶', 500.00, 23000.00, 1, 1, '2016-07-22 10:10:22', NULL, NULL, 14);
INSERT INTO `smbms_bill` VALUES (8, 'BILL2016_008', '不锈钢盘碗', '日用品-厨房用具', '个', 600.00, 6000.00, 2, 1, '2016-04-14 05:12:13', NULL, NULL, 14);
INSERT INTO `smbms_bill` VALUES (9, 'BILL2016_009', '塑料杯', '日用品-杯子', '个', 350.00, 1750.00, 2, 1, '2016-02-04 11:40:20', NULL, NULL, 14);
INSERT INTO `smbms_bill` VALUES (10, 'BILL2016_010', '豆瓣酱', '食品-调料', '瓶', 200.00, 2000.00, 2, 1, '2013-10-29 05:07:03', NULL, NULL, 8);
INSERT INTO `smbms_bill` VALUES (11, 'BILL2016_011', '海之蓝', '饮料-国酒', '瓶', 50.00, 10000.00, 1, 1, '2016-04-14 16:16:00', NULL, NULL, 1);
INSERT INTO `smbms_bill` VALUES (12, 'BILL2016_012', '芝华士', '饮料-洋酒', '瓶', 20.00, 6000.00, 1, 1, '2016-09-09 17:00:00', NULL, NULL, 1);
INSERT INTO `smbms_bill` VALUES (13, 'BILL2016_013', '长城红葡萄酒', '饮料-红酒', '瓶', 60.00, 800.00, 2, 1, '2016-11-14 15:23:00', NULL, NULL, 1);
INSERT INTO `smbms_bill` VALUES (14, 'BILL2016_014', '泰国香米', '食品-大米', '斤', 400.00, 5000.00, 2, 1, '2016-10-09 15:20:00', NULL, NULL, 3);
INSERT INTO `smbms_bill` VALUES (15, 'BILL2016_015', '东北大米', '食品-大米', '斤', 600.00, 4000.00, 2, 1, '2016-11-14 14:00:00', NULL, NULL, 3);
INSERT INTO `smbms_bill` VALUES (16, 'BILL2016_016', '可口可乐', '饮料', '瓶', 2000.00, 6000.00, 2, 1, '2012-03-27 13:03:01', NULL, NULL, 2);
INSERT INTO `smbms_bill` VALUES (17, 'BILL2016_017', '脉动', '饮料', '瓶', 1500.00, 4500.00, 2, 1, '2016-05-10 12:00:00', NULL, NULL, 2);
INSERT INTO `smbms_bill` VALUES (18, 'BILL2016_018', '哇哈哈', '饮料', '瓶', 2000.00, 4000.00, 2, 1, '2015-11-24 15:12:03', NULL, NULL, 2);

DROP TABLE IF EXISTS `smbms_provider`;
CREATE TABLE `smbms_provider`  (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `proCode` VARCHAR(20) NULL DEFAULT NULL COMMENT '供应商编码',
  `proName` VARCHAR(20) NULL DEFAULT NULL COMMENT '供应商名称',
  `proDesc` VARCHAR(50) NULL DEFAULT NULL COMMENT '供应商详细描述',
  `proContact` VARCHAR(20) NULL DEFAULT NULL COMMENT '供应商联系人',
  `proPhone` VARCHAR(20) NULL DEFAULT NULL COMMENT '联系电话',
  `proAddress` VARCHAR(50) NULL DEFAULT NULL COMMENT '地址',
  `proFax` VARCHAR(20) NULL DEFAULT NULL COMMENT '传真',
  `createdBy` BIGINT(20) NULL DEFAULT NULL COMMENT '创建者(userId)',
  `creationDate` DATETIME NULL DEFAULT NULL COMMENT '创建时间',
  `modifyDate` DATETIME NULL DEFAULT NULL COMMENT '更新时间',
  `modifyBy` BIGINT(20) NULL DEFAULT NULL COMMENT '更新者(userId)',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `smbms_provider` VALUES (1, 'BJ_GYS001', '北京三木堂商贸有限公司', '长期合作伙伴,主营产品:茅台、五粮液、郎酒、酒鬼酒、泸州老窖、赖茅酒、法国红酒等', '张国强', '13566667777', '北京市丰台区育芳园北路', '010-58858787', 1, '2013-03-21 16:52:07', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (2, 'HB_GYS001', '石家庄帅益食品贸易有限公司', '长期合作伙伴,主营产品:饮料、水饮料、植物蛋白饮料、休闲食品、果汁饮料、功能饮料等', '王军', '13309094212', '河北省石家庄新华区', '0311-67738876', 1, '2016-04-13 04:20:40', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (3, 'GZ_GYS001', '深圳市泰香米业有限公司', '初次合作伙伴,主营产品:良记金轮米,龙轮香米等', '郑程瀚', '13402013312', '广东省深圳市福田区深南大道6006华丰大厦', '0755-67776212', 1, '2014-03-21 16:56:07', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (4, 'GZ_GYS002', '深圳市喜来客商贸有限公司', '长期合作伙伴,主营产品:坚果炒货.果脯蜜饯.天然花茶.营养豆豆.特色美食.进口食品.海味零食.肉脯肉', '林妮', '18599897645', '广东省深圳市福龙工业区B2栋3楼西', '0755-67772341', 1, '2013-03-22 16:52:07', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (5, 'JS_GYS001', '兴化佳美调味品厂', '长期合作伙伴,主营产品:天然香辛料、鸡精、复合调味料', '徐国洋', '13754444221', '江苏省兴化市林湖工业区', '0523-21299098', 1, '2015-11-22 16:52:07', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (6, 'BJ_GYS002', '北京纳福尔食用油有限公司', '长期合作伙伴,主营产品:山茶油、大豆油、花生油、橄榄油等', '马莺', '13422235678', '北京市朝阳区珠江帝景1号楼', '010-588634233', 1, '2012-03-21 17:52:07', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (7, 'BJ_GYS003', '北京国粮食用油有限公司', '初次合作伙伴,主营产品:花生油、大豆油、小磨油等', '王驰', '13344441135', '北京大兴青云店开发区', '010-588134111', 1, '2016-04-13 00:00:00', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (8, 'ZJ_GYS001', '慈溪市广和绿色食品厂', '长期合作伙伴,主营产品:豆瓣酱、黄豆酱、甜面酱,辣椒,大蒜等农产品', '薛圣丹', '18099953223', '浙江省宁波市慈溪周巷小安村', '0574-34449090', 1, '2013-11-21 06:02:07', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (9, 'GX_GYS001', '优百商贸有限公司', '长期合作伙伴,主营产品:日化产品', '李立国', '13323566543', '广西南宁市秀厢大道42-1号', '0771-98861134', 1, '2013-03-21 19:52:07', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (10, 'JS_GYS002', '南京火头军信息技术有限公司', '长期合作伙伴,主营产品:不锈钢厨具等', '陈女士', '13098992113', '江苏省南京市浦口区浦口大道1号新城总部大厦A座903室', '025-86223345', 1, '2013-03-25 16:52:07', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (11, 'GZ_GYS003', '广州市白云区美星五金制品厂', '长期合作伙伴,主营产品:海绵床垫、坐垫、靠垫、海绵枕头、头枕等', '梁天', '13562276775', '广州市白云区钟落潭镇福龙路20号', '020-85542231', 1, '2016-12-21 06:12:17', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (12, 'BJ_GYS004', '北京隆盛日化科技', '长期合作伙伴,主营产品:日化环保清洗剂,家居洗涤专卖、洗涤用品网、墙体除霉剂、墙面霉菌清除剂等', '孙欣', '13689865678', '北京市大兴区旧宫', '010-35576786', 1, '2014-11-21 12:51:11', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (13, 'SD_GYS001', '山东豪克华光联合发展有限公司', '长期合作伙伴,主营产品:洗衣皂、洗衣粉、洗衣液、洗洁精、消杀类、香皂等', '吴洪转', '13245468787', '山东济阳济北工业区仁和街21号', '0531-53362445', 1, '2015-01-28 10:52:07', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (14, 'JS_GYS003', '无锡喜源坤商行', '长期合作伙伴,主营产品:日化品批销', '周一清', '18567674532', '江苏无锡盛岸西路', '0510-32274422', 1, '2016-04-23 11:11:11', NULL, NULL);
INSERT INTO `smbms_provider` VALUES (15, 'ZJ_GYS002', '乐摆日用品厂', '长期合作伙伴,主营产品:各种中、高档塑料杯,塑料乐扣水杯(密封杯)、保鲜杯(保鲜盒)、广告杯、礼品杯', '王世杰', '13212331567', '浙江省金华市义乌市义东路', '0579-34452321', 1, '2016-08-22 10:01:30', NULL, NULL);


DROP TABLE IF EXISTS `smbms_role`;
CREATE TABLE `smbms_role`  (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `roleCode` VARCHAR(15) NULL DEFAULT NULL COMMENT '角色编码',
  `roleName` VARCHAR(15) NULL DEFAULT NULL COMMENT '角色名称',
  `createdBy` BIGINT(20) NULL DEFAULT NULL COMMENT '创建者',
  `creationDate` DATETIME NULL DEFAULT NULL COMMENT '创建时间',
  `modifyBy` BIGINT(20) NULL DEFAULT NULL COMMENT '修改者',
  `modifyDate` DATETIME NULL DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8;


INSERT INTO `smbms_role` VALUES (1, 'SMBMS_ADMIN', '系统管理员', 1, '2016-04-13 00:00:00', NULL, NULL);
INSERT INTO `smbms_role` VALUES (2, 'SMBMS_MANAGER', '经理', 1, '2016-04-13 00:00:00', NULL, NULL);
INSERT INTO `smbms_role` VALUES (3, 'SMBMS_EMPLOYEE', '普通员工', 1, '2016-04-13 00:00:00', NULL, NULL);


DROP TABLE IF EXISTS `smbms_user`;
CREATE TABLE `smbms_user`  (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `userCode` VARCHAR(15) NULL DEFAULT NULL COMMENT '用户编码',
  `userName` VARCHAR(15) NULL DEFAULT NULL COMMENT '用户名称',
  `userPassword` VARCHAR(15) NULL DEFAULT NULL COMMENT '用户密码',
  `gender` INT(10) NULL DEFAULT NULL COMMENT '性别(1:女、 2:男)',
  `birthday` DATE NULL DEFAULT NULL COMMENT '出生日期',
  `phone` VARCHAR(15) NULL DEFAULT NULL COMMENT '手机',
  `address` VARCHAR(30) NULL DEFAULT NULL COMMENT '地址',
  `userRole` BIGINT(20) NULL DEFAULT NULL COMMENT '用户角色(取自角色表-角色id)',
  `createdBy` BIGINT(20) NULL DEFAULT NULL COMMENT '创建者(userId)',
  `creationDate` DATETIME NULL DEFAULT NULL COMMENT '创建时间',
  `modifyBy` BIGINT(20) NULL DEFAULT NULL COMMENT '更新者(userId)',
  `modifyDate` DATETIME NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `smbms_user` VALUES (1, 'admin', '111', '111111', 1, '2021-04-22', '13688889999', '北京市海淀区成府路207号', 3, 1, '2013-03-21 16:52:07', 1, '2021-04-22 17:43:02');
INSERT INTO `smbms_user` VALUES (2, 'liming', '李明', '0000000', 2, '1983-12-10', '13688884457', '北京市东城区前门东大街9号', 2, 1, '2014-12-31 19:52:09', NULL, NULL);
INSERT INTO `smbms_user` VALUES (5, 'hanlubiao', '韩路彪', '0000000', 2, '1984-06-05', '18567542321', '北京市朝阳区北辰中心12号', 2, 1, '2014-12-31 19:52:09', NULL, NULL);
INSERT INTO `smbms_user` VALUES (6, 'zhanghua', '张华', '0000000', 1, '1983-06-15', '13544561111', '北京市海淀区学院路61号', 3, 1, '2013-02-11 10:51:17', NULL, NULL);
INSERT INTO `smbms_user` VALUES (7, 'wangyang', '王洋', '0000000', 2, '1982-12-31', '13444561124', '北京市海淀区西二旗辉煌国际16层', 3, 1, '2014-06-11 19:09:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (8, 'zhaoyan', '赵燕', '0000000', 2, '2021-04-22', '18098764545', '北京市海淀区回龙观小区10号楼', 2, 1, '2016-04-21 13:54:07', 1, '2021-04-22 17:56:11');
INSERT INTO `smbms_user` VALUES (10, 'sunlei', '孙磊', '0000000', 2, '1981-01-04', '13387676765', '北京市朝阳区管庄新月小区12楼', 3, 1, '2015-05-06 10:52:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (11, 'sunxing', '孙兴', '0000000', 2, '1978-03-12', '13367890900', '北京市朝阳区建国门南大街10号', 3, 1, '2016-11-09 16:51:17', NULL, NULL);
INSERT INTO `smbms_user` VALUES (12, 'zhangchen', '张晨', '0000000', 1, '1986-03-28', '18098765434', '朝阳区管庄路口北柏林爱乐三期13号楼', 3, 1, '2016-08-09 05:52:37', 1, '2016-04-14 14:15:36');
INSERT INTO `smbms_user` VALUES (13, 'dengchao', '邓超', '0000000', 2, '1981-11-04', '13689674534', '北京市海淀区北航家属院10号楼', 3, 1, '2016-07-11 08:02:47', NULL, NULL);
INSERT INTO `smbms_user` VALUES (15, 'zhaomin', '赵敏', '0000000', 1, '1987-12-04', '18099897657', '北京市昌平区天通苑3区12号楼', 2, 1, '2015-09-12 12:02:12', NULL, NULL);
INSERT INTO `smbms_user` VALUES (18, '111', '111', '111111', 1, '2021-04-22', '15072151323', '111', 3, 1, '2021-04-22 18:13:07', NULL, NULL);


架构设计图

 项目搭建准备工作

  1. 搭建一个maven web项目

  2. 配置tomcat

  3. 测试项目是否可以跑起来

  4. 导入项目中所需jar包

  5. 创建项目包结构

  6. 编写实体类

    ORM映射:表-类映射

  7. 编写基础公共类

    1. 数据库配置文件
    2. 编写数据库的公共类
    3. 编写字符编码过滤器
  8. 导入静态资源

1

2

3

4

        <!--   jdbc依赖     -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <!--   单元测试,打印日志     -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>

        <!--   servlet依赖     -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>

        <!--   jsp依赖     -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
        </dependency>

        <!--   jstl依赖    -->
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>

        <!--   standard标签库  -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

        <!--   一键生成插件  -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

        <!--   JSON工具类  -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.79</version>
        </dependency>

5

 6

 7

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/smbms?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8
username=root
password=

数据库连接工具类


public class BaseDao {

    private static String driver;
    private static String url;
    private static String userName;
    private static String password;

    static {
        // 加载数据库的配置文件
        Properties properties = new Properties();
        InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        driver = properties.getProperty("driver");
        url = properties.getProperty("url");
        userName = properties.getProperty("username");
        password = properties.getProperty("password");
    }

    // 获取数据库的连接
    public static Connection getConnection() {
        Connection con = null;
        try {
            Class.forName(driver);
            con = DriverManager.getConnection(url, userName, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return con;
    }

    // 编写查询方法
    public static ResultSet execute(Connection con, PreparedStatement ps, ResultSet rs, String sql, Object[] params) throws SQLException {
        ps = con.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            // setObject 占位符下标从1开始,我们数组是从0开始
            ps.setObject(i + 1, params[i]);
        }
        rs = ps.executeQuery();
        return rs;
    }

    // 编写增、删、改方法
    public static int executeUpdate(Connection con, PreparedStatement ps, String sql, Object[] params) throws SQLException {
        ps = con.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            // setObject 占位符下标从1开始,我们数组是从0开始
            ps.setObject(i + 1, params[i]);
        }
        return ps.executeUpdate();
    }

    public static boolean closeResource(Connection con, PreparedStatement ps, ResultSet rs) {
        boolean closeFlag = true;
        if (rs != null) {
            try {
                rs.close();
                rs = null;
            } catch (SQLException e) {
                e.printStackTrace();
                closeFlag = false;
            }
        }
        if (ps != null) {
            try {
                ps.close();
                ps = null;
            } catch (SQLException e) {
                e.printStackTrace();
                closeFlag = false;
            }
        }
        if (con != null) {
            try {
                con.close();
                con = null;
            } catch (SQLException e) {
                e.printStackTrace();
                closeFlag = false;
            }
        }
        return closeFlag;
    }

    public static boolean closeResource(Connection con) {
        boolean closeFlag = true;
        if (con != null) {
            try {
                con.close();
                con = null;
            } catch (SQLException e) {
                e.printStackTrace();
                closeFlag = false;
            }
        }
        return closeFlag;
    }

    public static boolean closeResource(PreparedStatement ps, ResultSet rs) {
        boolean closeFlag = true;
        if (rs != null) {
            try {
                rs.close();
                rs = null;
            } catch (SQLException e) {
                e.printStackTrace();
                closeFlag = false;
            }
        }
        if (ps != null) {
            try {
                ps.close();
                ps = null;
            } catch (SQLException e) {
                e.printStackTrace();
                closeFlag = false;
            }
        }
        return closeFlag;
    }
}

字符编码过滤器

public class CharacterEncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//        System.out.println("CharacterEncodingFilter过滤了");
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}

配置web.xml

    <filter>
        <filter-name>characterEncoding</filter-name>
        <filter-class>com.kuang.filter.CharacterEncodingFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>characterEncoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

8

提示,后续页面都将以前端页面为起始来引导后续代码编写

二、登录流程实现

1、编写前端页面login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h3>我是登录页面</h3>

<form action="${pageContext.request.contextPath}/LoginServlet" method="get">
    用户名:<input type="text" name="username"/><br/>
    密码:<input type="password" name="password"/><br/>
    <input type="submit"/>
</form>

<br/>
提示信息:
<%
    String msg = (String) request.getSession().getAttribute("message");
    out.println(msg);
%>

</body>
</html>

2、在web.xml将其设置为首页

    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>

3、编写dao层登录用户的接口

public interface UserDao {
    User getLoginUser(Connection con, String userCode) throws SQLException;
}

4、编写dao接口的实现类


public class UserDaoImpl implements UserDao {

    // 查询登录用户
    public User getLoginUser(Connection con, String userCode) throws SQLException {
        System.out.println("UserDaoImpl的getLoginUser方法");
        PreparedStatement ps = null;
        ResultSet rs = null;
        User user = null;
        if (con != null) {
            String sql = "select id, userCode, userName, userPassword, gender, birthday, phone, address, " +
                    "userRole, createdBy, creationDate, modifyBy, modifyDate " +
                    "from smbms_user where userCode=?";
            // 生成入参
            String[] params = {userCode};
            rs = BaseDao.execute(con, ps, rs, sql, params);
            // 解析结果集
            if (rs.next()) {
                user = new User();
                user.setId(rs.getInt("id"));
                user.setUserCode(rs.getString("userCode"));
                user.setUserName(rs.getString("userName"));
                user.setUserPassword(rs.getString("userPassword"));
                user.setGender(rs.getInt("gender"));
                user.setBirthday(rs.getDate("birthday"));
                user.setPhone(rs.getString("phone"));
                user.setAddress(rs.getString("address"));
                user.setUserRole(rs.getInt("userRole"));
                user.setCreatedBy(rs.getInt("createdBy"));
                user.setCreationDate(rs.getTimestamp("creationDate"));
                user.setModifyBy(rs.getInt("modifyBy"));
                user.setModifyDate(rs.getTimestamp("modifyDate"));
            }
            // 关闭
            BaseDao.closeResource(ps, rs);
        }
        return user;
    }

}

5、编写service业务层接口

public interface UserService {
    User login(String userCode, String password);
}

6、编写service业务层实现类

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    // 无参构造,创建dao对象
    public UserServiceImpl() {
        userDao = new UserDaoImpl();
    }

    @Override
    public User login(String userCode, String password) {
        System.out.println("UserServiceImpl的login方法");
        Connection con = null;
        User user = null;
        try {
            // 获取连接
            con = BaseDao.getConnection();
            // 执行查询
            user = userDao.getLoginUser(con, userCode);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            BaseDao.closeResource(con);
        }
        return user;
    }
}

7、编写loginServlet


public class LoginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("LoginServlet开始");

        // 获取入参
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        // 执行登陆查询操作
        UserService userService = new UserServiceImpl();
        User user = userService.login(username, password);
        if (user != null) {
            req.getSession().setAttribute(Constants.USER_SESSION, user);
            // 重定向到首页
            resp.sendRedirect("/sys/frame.jsp");
        } else {
            // 附带错误信息
            req.setAttribute("message", "登录失败,用户名或者密码错误");
            // 转发到登录页面,并提示错误信息
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

8、在web.xml注册servlet

    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.kuang.servlet.LoginServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/LoginServlet</url-pattern>
    </servlet-mapping>

9、编写登录后的跳转页面

<%@ page import="com.kuang.pojo.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@include file="/common/head.jsp" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1>我是首页</h1>

<%
    User user = (User) request.getSession().getAttribute("userSession");
    out.println(user.getUserName() + ":您好!");
%>
<br/>
${userSession.userName}:您好!
<br/>

<form action="${pageContext.request.contextPath}/UserServlet" method="get">
    <input type="hidden" name="method" value="queryUserList">
    <input type="submit" name="获取用户列表" value="获取用户列表">
</form>

<a href="/sys/pwdModify.jsp">修改密码</a>
<br/>
<a href="/sys/addUser.jsp">新增用户</a>
<br/>
<a href="/LogoutServlet">登出</a>
<br/>

</body>
</html>
<%@include file="/common/foot.jsp" %>

10、测试访问

三、注销及权限过滤

注销思路:移除session,返回登录页面

1、在首页frame.jsp添加注销按钮

<a href="/LogoutServlet">登出</a>

2、编写logoutServlet


public class LogoutServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("LogoutServlet开始");
        //移除session
        req.getSession().removeAttribute(Constants.USER_SESSION);
        //跳转登录页面
        resp.sendRedirect("/login.jsp");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

登录拦截优化

配置登陆失败页面error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

登录失败

<p><a href="/login.jsp">返回登录页面</a></p>

</body>
</html>

sysFilter.java


public class SysFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        System.out.println("SysFilter过滤了");
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        User user = (User) req.getSession().getAttribute(Constants.USER_SESSION);
        // 已经被移除或者注销了,或者没有登录
        if (user == null) {
            resp.sendRedirect("/error.jsp");
            return;
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}

没有登录直接请求http://localhost:8080/sys/frame.jsp

四、修改密码实现

1、pwdModify.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@include file="/common/head.jsp" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

修改密码页面
<br/>

<form action="${pageContext.request.contextPath}/UserServlet" method="get">
    <input type="hidden" name="method" value="updatePwd">
    原密码:<input type="password" name="password"/><br/>
    新密码:<input type="password" name="newPassword"/><br/>
    <input type="submit"/>
</form>

</body>
</html>
<%@include file="/common/foot.jsp" %>

2、编写dao层的接口

public interface UserDao {
    User getLoginUser(Connection con, String userCode) throws SQLException;

    int updatePwd(Connection con, int id, String userPassword) throws SQLException;
}

3、编写dao接口的实现类


public class UserDaoImpl implements UserDao {

    // 查询登录用户
    public User getLoginUser(Connection con, String userCode) throws SQLException {
        System.out.println("UserDaoImpl的getLoginUser方法");
        PreparedStatement ps = null;
        ResultSet rs = null;
        User user = null;
        if (con != null) {
            String sql = "select id, userCode, userName, userPassword, gender, birthday, phone, address, " +
                    "userRole, createdBy, creationDate, modifyBy, modifyDate " +
                    "from smbms_user where userCode=?";
            // 生成入参
            String[] params = {userCode};
            rs = BaseDao.execute(con, ps, rs, sql, params);
            // 解析结果集
            if (rs.next()) {
                user = new User();
                user.setId(rs.getInt("id"));
                user.setUserCode(rs.getString("userCode"));
                user.setUserName(rs.getString("userName"));
                user.setUserPassword(rs.getString("userPassword"));
                user.setGender(rs.getInt("gender"));
                user.setBirthday(rs.getDate("birthday"));
                user.setPhone(rs.getString("phone"));
                user.setAddress(rs.getString("address"));
                user.setUserRole(rs.getInt("userRole"));
                user.setCreatedBy(rs.getInt("createdBy"));
                user.setCreationDate(rs.getTimestamp("creationDate"));
                user.setModifyBy(rs.getInt("modifyBy"));
                user.setModifyDate(rs.getTimestamp("modifyDate"));
            }
            // 关闭
            BaseDao.closeResource(ps, rs);
        }
        return user;
    }

    // 修改密码
    public int updatePwd(Connection con, int id, String userPassword) throws SQLException {
        System.out.println("UserDaoImpl的updatePwd方法");
        int updateCount = 0;
        if (con != null) {
            PreparedStatement ps = null;
            String sql = "update smbms_user set userPassword = ? where id = ?";
            // 生成入参
            Object[] params = {userPassword, id};
            updateCount = BaseDao.executeUpdate(con, ps, sql, params);
            BaseDao.closeResource(ps, null);
        }
        return updateCount;
    }
}

4、编写service业务层接口

public interface UserService {
    User login(String userCode, String password);

    boolean updatePwd(int id, String password);
}

5、编写service业务层实现类

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    // 无参构造,创建dao对象
    public UserServiceImpl() {
        userDao = new UserDaoImpl();
    }

    @Override
    public User login(String userCode, String password) {
        System.out.println("UserServiceImpl的login方法");
        Connection con = null;
        User user = null;
        try {
            // 获取连接
            con = BaseDao.getConnection();
            // 执行查询
            user = userDao.getLoginUser(con, userCode);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            BaseDao.closeResource(con);
        }
        return user;
    }

    @Override
    public boolean updatePwd(int id, String password) {
        System.out.println("UserServiceImpl的updatePwd方法");
        Connection con = null;
        int update = 0;
        try {
            // 获取连接
            con = BaseDao.getConnection();
            // 执行更新
            update = userDao.updatePwd(con, id, password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            BaseDao.closeResource(con);
        }
        return update > 0;
    }
}

6、编写loginServlet

public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 两种方法获取入参
        String method = (String) req.getSession().getAttribute("method");
        String method2 = req.getParameter("method");
        // 判断要执行什么方法
        if ("updatePwd".equals(method) || "updatePwd".equals(method2)) {
            updatePwd(req, resp);
        } else if ("checkOldPwd".equals(method) || "checkOldPwd".equals(method2)) {
            checkOldPwd(req, resp);
        } else if ("queryUserList".equals(method) || "queryUserList".equals(method2)) {
            queryUserList(req, resp);
        }

    }

    protected void updatePwd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("UserServlet的updatePwd方法");
        // 获取入参
        User user = (User) req.getSession().getAttribute(Constants.USER_SESSION);
        String newPassword = req.getParameter("newPassword");

        // 执行修改密码操作
        if (newPassword != null && user != null) {
            UserService userService = new UserServiceImpl();
            boolean b = userService.updatePwd(user.getId(), newPassword);
            if (b) {
                // 修改成功,移除session
                req.getSession().removeAttribute(Constants.USER_SESSION);
                req.setAttribute("message", "密码修改成功,请退出,使用新密码登录~");
            } else {
                req.setAttribute("message", "密码修改失败~");
            }
        } else {
            req.setAttribute("message", "新密码不可为空~");
        }

        req.getRequestDispatcher("/login.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

7、在web.xml注册Servlet

    <servlet>
        <servlet-name>UserServlet</servlet-name>
        <servlet-class>com.kuang.servlet.UserServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>UserServlet</servlet-name>
        <url-pattern>/UserServlet</url-pattern>
    </servlet-mapping>

8、启动项目测试

 

五、Ajax验证旧密码

导入依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.68</version>
</dependency>

修改UserServlet,添加密码校验方法


    protected void checkOldPwd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("UserServlet的checkOldPwd方法");
        // 获取入参
        User user = (User) req.getSession().getAttribute(Constants.USER_SESSION);
        String oldPassword = req.getParameter("oldPassword");
        Map<String, Object> resultMap = new HashMap<String, Object>(16);

        // 执行修改密码操作
        if (user == null) {
            resultMap.put("message", "登录已失效");
        } else if (oldPassword != null && !"".equals(oldPassword)) {
            if (user.getUserPassword().equals(oldPassword)) {
                // 旧密码输入正确
                resultMap.put("message", "true");
            } else {
                resultMap.put("message", "false");
            }
        } else {
            resultMap.put("message", "旧密码不可为空~");
        }

        // 返回json格式的数据给前端
        resp.setContentType("application/json");
        PrintWriter writer = resp.getWriter();
        writer.write(JSON.toJSONString(resultMap));
        writer.flush();
        writer.close();
    }

六、用户管理分页实现

1、userList.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@include file="/common/head.jsp" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h2>用户管理页面</h2>

<div class="search">
    <form action="${pageContext.request.contextPath}/UserServlet" method="get">
        <input type="hidden" name="method" value="queryUserList">
        用户名:<input type="text" name="queryUserName" value="${queryUserName}"/><br/>

        用户角色:
        <select name="queryUserRole">
            <c:if test="${roleList != null}">
                <option value="0">--请选择--</option>
                <c:forEach var="role" items="${roleList}">
                    <option
                            <c:if test="${role.id == queryUserRole}">
                                selected="selected"
                            </c:if> value="${role.id}">
                            ${role.roleName}
                    </option>
                </c:forEach>
            </c:if>
        </select>
        <input type="hidden" name="pageIndex" value="1">
        <input id="searchRole" type="submit" value="查询用户"/>
    </form>
</div>


<table class="userList">
    <thead>
    <tr>
        <th>用户名</th>
        <th>性别</th>
        <th>电话号码</th>
        <th>地址</th>
        <th>操作</th>
    </tr>
    </thead>

    <tbody>
    <c:forEach var="user" items="${userList}"><%--方式二写法:requsestScope.get('books')--%>
        <tr>
            <td>${user.userName}</td>
            <td>${user.gender}</td>
            <td>${user.phone}</td>
            <td>${user.address}</td>
            <td>
                <a href="${pageContext.request.contextPath}/books/toUpdatePage?bookID=${user.id}">更改</a>
                <a href="${pageContext.request.contextPath}/books/deleteBooks?bookID=${user.id}">删除</a>
            </td>
        </tr>
    </c:forEach>
    </tbody>
</table>

</body>
</html>
<%@include file="/common/foot.jsp" %>

2、编写dao层的接口

public interface UserDao {

    User getLoginUser(Connection con, String userCode) throws SQLException;

    int updatePwd(Connection con, int id, String userPassword) throws SQLException;

    int addUser(Connection con, String userName, String userPassword) throws SQLException;

    int getUserCount(Connection con, String userName, int userRole) throws SQLException;

    List<User> getUserList(Connection con, String userName, int userRole, int currentPageNo, int pageSize) throws SQLException;

}

3、编写dao接口的实现类


public class UserDaoImpl implements UserDao {

    // 新增用户
    public int addUser(Connection con, String userName, String userPassword) throws SQLException {
        System.out.println("UserDaoImpl的addUser方法");
        int insertCount = 0;
        if (con != null) {
            PreparedStatement ps = null;
            String sql = "unsert into smbms_user(userName,userPassword) values(?,?)";
            // 生成入参
            Object[] params = {userName, userPassword};
            insertCount = BaseDao.executeUpdate(con, ps, sql, params);
            BaseDao.closeResource(ps, null);
        }
        return insertCount;
    }

    public int getUserCount(Connection con, String userName, int userRole) throws SQLException {
        System.out.println("UserDaoImpl的getUserCount方法");
        PreparedStatement ps = null;
        ResultSet rs = null;
        int count = 0;
        if (con != null) {
            StringBuffer sql = new StringBuffer("select count(1) as 'count' from smbms_user u," +
                    "smbms_role r where u.userRole = r.id");
            List<Object> list = new ArrayList<Object>();
            if (!StringUtils.isNullOrEmpty(userName)) {
                sql.append(" and u.userName like ?");
                list.add("%" + userName + "%");
            }
            if (userRole > 0) {
                sql.append(" and r.id = ?");
                list.add(userRole);
            }
            // 生成入参
            Object[] params = list.toArray();
            rs = BaseDao.execute(con, ps, rs, sql.toString(), params);
            // 解析结果集
            if (rs.next()) {
                count = rs.getInt("count");
            }
            BaseDao.closeResource(ps, rs);
        }
        return count;
    }

    public List<User> getUserList(Connection con, String userName, int userRole, int currentPageNo, int pageSize) throws SQLException {

        System.out.println("UserDaoImpl的getUserList方法");
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<User> userList = new ArrayList<>();
        if (con != null) {
            StringBuffer sql = new StringBuffer("select u.*, r.roleName as `userRoleName` " +
                    "from smbms_user u, smbms_role r where u.userRole = r.id");
            List<Object> list = new ArrayList<>();
            if (!StringUtils.isNullOrEmpty(userName)) {
                sql.append(" and u.userName like ?");
                list.add("%" + userName + "%");
            }
            if (userRole > 0) {
                sql.append(" and r.id = ?");
                list.add(userRole);
            }
            //mysql 分页使用limit startIndex, pageSize
            //比如现在一共13条数据,每页最大容量是5
            //0,5 01234 第一页
            //5,5 56789 第二页
            //10,3 10,11,12 第三页
            sql.append(" order by u.creationDate desc limit ?,?");
            // 分页入参
            currentPageNo = (currentPageNo - 1) * pageSize;
            list.add(currentPageNo);
            list.add(pageSize);
            // 生成入参
            Object[] params = list.toArray();
            rs = BaseDao.execute(con, ps, rs, sql.toString(), params);
            // 解析结果集
            while (rs.next()) {
                User user = new User();
                user.setId(rs.getInt("id"));
                user.setUserCode(rs.getString("userCode"));
                user.setUserName(rs.getString("userName"));
                user.setGender(rs.getInt("gender"));
                user.setBirthday(rs.getDate("birthday"));
                user.setPhone(rs.getString("phone"));
                user.setUserRole(rs.getInt("userRole"));
                user.setUserRoleName(rs.getString("userRoleName"));
                userList.add(user);
            }
            BaseDao.closeResource(ps, rs);
        }
        return userList;
    }
}

4、编写service业务层接口

public interface UserService {
    User login(String userCode, String password);

    boolean updatePwd(int id, String password);

    int getUserCount(String userName, int userRole);

    List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize);
}

5、编写service业务层实现类

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    // 无参构造,创建dao对象
    public UserServiceImpl() {
        userDao = new UserDaoImpl();
    }

    @Override
    public User login(String userCode, String password) {
        System.out.println("UserServiceImpl的login方法");
        Connection con = null;
        User user = null;
        try {
            // 获取连接
            con = BaseDao.getConnection();
            // 执行查询
            user = userDao.getLoginUser(con, userCode);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            BaseDao.closeResource(con);
        }
        return user;
    }

    @Override
    public boolean updatePwd(int id, String password) {
        System.out.println("UserServiceImpl的updatePwd方法");
        Connection con = null;
        int update = 0;
        try {
            // 获取连接
            con = BaseDao.getConnection();
            // 执行更新
            update = userDao.updatePwd(con, id, password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            BaseDao.closeResource(con);
        }
        return update > 0;
    }

    @Override
    public int getUserCount(String userName, int userRole) {
        System.out.println("UserServiceImpl的getUserCount方法");
        Connection con = null;
        int userCount = 0;
        try {
            // 获取连接
            con = BaseDao.getConnection();
            // 执行查询
            userCount = userDao.getUserCount(con, userName, userRole);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            BaseDao.closeResource(con);
        }
        return userCount;
    }

    @Override
    public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize) {
        System.out.println("UserServiceImpl的getUserList方法");
        Connection con = null;
        List<User> userList = new ArrayList<>();
        try {
            // 获取连接
            con = BaseDao.getConnection();
            // 执行查询
            userList = userDao.getUserList(con, queryUserName, queryUserRole, currentPageNo, pageSize);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            BaseDao.closeResource(con);
        }
        return userList;
    }

}

6、启动项目测试

条件查询

 

七、角色管理分页实现

同上,暂时不写

八、文件上传原理及实现

1、导入依赖

        <!--   文件上传下载  -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

2、fileUpload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<form action="${pageContext.request.contextPath}/FileServlet" enctype="multipart/form-data" method="post">
    上传用户:<input type="text" name="username"><br/>
    <p><input type="file" name="file1"></p>
    <p><input type="file" name="file2"></p>
    <p><input type="submit"> | <input type="reset"></p>
</form>

</body>
</html>

3、FileServlet.java

public class FileServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("FileServlet开始");
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("FileServlet开始");
        //判断上传的表单是普通表单还是文件表单
        if (!ServletFileUpload.isMultipartContent(request)) {
            //终止方法运行,说明这是一个普通的表单,直接返回
            return;
        }

        //创建上传文件的保存路径,建议在web-inf路径下,安全,用户无法直接访问上传的文件
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists()) {
            uploadFile.mkdir();
        }

        //临时文件
        //临时路径,假如文件超过了预期的大小,我们就把他放到一个临时文件中,过几天自助删除,或者提醒用户转存为永久
        String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
        File tempFile = new File(tempPath);
        if (!tempFile.exists()) {
            tempFile.mkdir();
        }

        //处理上传的文件,一般都需要通过流来获取,我们可以使用request.getInputStream(),原生态的文件上传流获取,十分麻烦
        //但是我们都是建议使用Apache的文件上传组件来实现,common-fileupload,它需要依赖于commons-io组件

        //1.创建DiskFileItemFactory对象,处理文件路径上传或者大小限制的
        DiskFileItemFactory factory = createDiskFileItemFactory(tempFile);
        //2.获取ServletFileUpload
        ServletFileUpload upload = creatServletFileUpload(factory);
        //3.处理上传的文件
        String msg = uploadFile(request, uploadPath, upload);

        //转发
        request.setAttribute("msg", msg);
        request.getRequestDispatcher("/fileUpload.jsp").forward(request, response);
    }

    private DiskFileItemFactory createDiskFileItemFactory(File tempFile) {
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件中
        //缓冲区大小为1M
        factory.setSizeThreshold(1024 * 1024);
        //临时目录的保存目录
        factory.setRepository(tempFile);
        return factory;
    }

    private ServletFileUpload creatServletFileUpload(DiskFileItemFactory factory) {
        ServletFileUpload upload = new ServletFileUpload(factory);
        final long[] bilv = {0L};
        //监听文件上传进度
        upload.setProgressListener(new ProgressListener() {
            /**
             *
             * @param pBytesRead 已经读取到的文件大小
             * @param pContentLength 文件总大小
             * @param pItems
             */
            @Override
            public void update(long pBytesRead, long pContentLength, int pItems) {
                while ((int) (pBytesRead * 100 / pContentLength - bilv[0]) >= 10) {
                    System.out.println("总大小:" + pContentLength + ",已经上传:" + pBytesRead + ",百分比:" + pBytesRead * 100 / pContentLength + "%");
                    bilv[0] = pBytesRead * 100 / pContentLength;
                }
            }
        });
        //处理乱码问题
        upload.setHeaderEncoding("UTF-8");
        //设置单个文件的最大值
        upload.setFileSizeMax(1020 * 1024 * 10);
        //设置总共能够上传文件的大小
        //1020 = 1kb * 1024 = 1M * 10 = 10M
        upload.setSizeMax(1020 * 1024 * 10);
        return upload;
    }

    private String uploadFile(HttpServletRequest request, String uploadPath, ServletFileUpload upload) throws IOException {
        String msg = "";
        //把前端请求解析,封装成一个FileItem对象,需要从ServletFileUpload对象中获取
        try {
            List<FileItem> fileItems = upload.parseRequest(request);
            for (FileItem fileItem : fileItems) {
                if (fileItem.isFormField()) {
                    String fieldName = fileItem.getFieldName();
                    //处理乱码
                    String value = fileItem.getString("UTF-8");
                    System.out.println(fieldName + ":" + value);
                } else {
                    //文件
                    //===========处理文件============
                    String uploadFileName = fileItem.getName();
                    System.out.println("uploadFileName:" + uploadFileName);
                    //可能存在文件名不合法的情况
                    if (uploadFileName == null || "".equals(uploadFileName.trim())) {
                        continue;
                    }
                    //获取上传的文件名
                    String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
                    //获取文件的后缀名
                    String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
                    //如果文件后缀名fileExtName不是我们所需要的,就直接return,不处理,告诉用户文件类型不对

                    //可以使用UUID(统一识别的通用码),保证文件名唯一
                    //UUID.randomUUID() 随机生一个唯一识别的通用码
                    //网络从传输中的东西,都需要序列化
                    //implements java.io.Serializable 标记接口  本地方法栈--》C++
                    String uuidPath = UUID.randomUUID().toString();

                    //===========存放地址============
                    String realPath = uploadPath + "/" + uuidPath;
                    File realPathFile = new File(realPath);
                    if (!realPathFile.exists()) {
                        realPathFile.mkdir();
                    }
                    //===========文件传输============
                    InputStream inputStream = fileItem.getInputStream();
                    FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
                    byte[] buffer = new byte[1024 * 1024];
                    int len;
                    while ((len = inputStream.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                    fos.close();
                    inputStream.close();
                    msg = "上传成功~";
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
            msg = "上传失败~";
        }
        return msg;
    }

}

4、启动项目并测试

可以实时查看进度

九、发送邮件原理及实现

 0、在QQ邮箱注册邮件客户端,获取16位密钥

 

1、导入依赖

        <!--   发送邮件  -->
        <dependency>
            <groupId>jakarta.activation</groupId>
            <artifactId>jakarta.activation-api</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>

2、register.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册页面</title>
</head>
<body>

<form action="${pageContext.request.contextPath}/EmailServlet" method="post">
    <p>用户名:<input type="text" name="username" required></p>
    <p>密码:<input type="password" name="password" required></p>
    <p>邮箱:<input type="email" name="email" required></p>
    <p><input type="submit" value="提交"></p>
</form>

</body>
</html>

3、FileServlet.java

public class EmailServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("EmailServlet开始");
        //处理前端请求
        String name = req.getParameter("username");
        String password = req.getParameter("password");
        String email = req.getParameter("email");

        //将信息封装进User2对象
        User2 User2 = new User2(name, password, email);

        SendMail sendMail = new SendMail(User2);
        //开启线程
        sendMail.start();
        // 返回结果给页面
        req.setAttribute("msg", "发送成功");
        req.getRequestDispatcher("msg.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

4、sendEmail.java


public class SendMail extends Thread {
    //发件人信息
    private final String From = "1487884767@qq.com";
    //发件人邮箱
    private final String recipient = "1487884767@qq.com";
    //邮箱密码
    private final String password = "bvgmpiohyarwhbig";
    //邮件发送的服务器
    private final String host = "smtp.qq.com";

    //收件人信息
    private User2 User2;

    public SendMail(User2 User2) {
        this.User2 = User2;
    }

    @Override
    public void run() {
        try {
            Properties properties = new Properties();
            properties.setProperty("mail.host", "smtp.qq.com");
            properties.setProperty("mail.transport.protocol", "smtp");
            properties.setProperty("mail.smtp.auth", "true");

            //QQ存在一个特性设置SSL加密
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            try {
                sf = new MailSSLSocketFactory();
            } catch (GeneralSecurityException e) {
                e.printStackTrace();
            }
            sf.setTrustAllHosts(true);
            properties.put("mail.smtp.ssl.enable", "true");
            properties.put("mail.smtp.ssl.socketFactory", sf);

            //创建一个session对象
            Session session = Session.getDefaultInstance(properties, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(recipient, password);
                }
            });
            //开启debug模式
            session.setDebug(true);

            //获取连接对象
            Transport transport = null;
            try {
                transport = session.getTransport();
            } catch (NoSuchProviderException e) {
                e.printStackTrace();
            }
            //连接服务器
            transport.connect(host, From, password);

            //创建一个邮件发送对象
            MimeMessage mimeMessage = new MimeMessage(session);
            //邮件发送人
            mimeMessage.setFrom(new InternetAddress(recipient));
            //邮件接收人
            mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(User2.getMail()));
            //邮件标题
            mimeMessage.setSubject("网站注册成功");
            //邮件内容
            mimeMessage.setContent("网站注册成功,密码为" + User2.getPassword() + ",请妥善保管密码", "text/html;charset=UTF-8");
            //发送邮件
            transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());

            transport.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

5、这里是开头老师写的demo,我放在最后了

public class demo2 {
    public static void main(String[] args) throws Exception {

        Properties properties = new Properties();
        //设置QQ邮件服务器
        properties.setProperty("mail.host", "smtp.qq.com");
        //邮件发送协议
        properties.setProperty("mail.transport.protocol", "smtp");
        //需要验证用户名密码
        properties.setProperty("mail.smtp.auth", "true");

        //关于QQ邮箱,还需要设置SSL加密,加上以下以下代码即可
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        properties.put("mail.smtp.ssl.enable", "true");
        properties.put("mail.smtp.ssl.socketFactory", sf);

        //使用javaMail发送邮件的5个步骤
        //1.创建定义整个应用程序所需的环境信息的Session对象
        Session session = Session.getDefaultInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                //发件人邮件用户名、授权码
                return new PasswordAuthentication("1487884767@qq.com", "bvgmpiohyarwhbig");
            }
        });
        //--开启debug模式,这样就可以查看到程序发送email的运行状态
        session.setDebug(true);
        //2.通过session得到transport对象
        Transport ts = session.getTransport();
        //3.使用邮箱的用户名和授权码连上邮件服务器
        ts.connect("smtp.qq.com", "1487884767@qq.com", "bvgmpiohyarwhbig");
        //4.创建邮件
        MimeMessage message = new MimeMessage(session);
        //--邮件的发件人
        message.setFrom(new InternetAddress("1487884767@qq.com"));
        //--邮件的收件人
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("1487884767@qq.com"));
        //--邮件的标题
        message.setSubject("hello");

        //》》》》》》》》》》《《《《《《《《《
        //图片
        MimeBodyPart image = new MimeBodyPart();
        //图片需要数据处理  DataHandler
        DataHandler dh = new DataHandler(new FileDataSource("src/resources/bz.jpg"));
        image.setDataHandler(dh);
        //给图片设置一个id
        image.setContentID("bz.jpg");

        //文本
        MimeBodyPart text = new MimeBodyPart();
        text.setContent("这是一封邮件带图片<img src='cid:bz.jpg'/>的邮件", "text/html;charset=UTF-8");
        //整合
        MimeMultipart mm = new MimeMultipart();
        mm.addBodyPart(text);
        mm.addBodyPart(image);
        mm.setSubType("related");

        //放到消息中,保存修改
        message.setContent(mm);
        message.saveChanges();

        //》》》》》》》》》》《《《《《《《《《
        //5.发送邮件
        ts.sendMessage(message, message.getAllRecipients());
        //6.关闭连接
        ts.close();
    }
}

6、启动项目并测试

 

7、查看收到的邮件

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值