目录
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);
架构设计图
项目搭建准备工作
-
搭建一个maven web项目
-
配置tomcat
-
测试项目是否可以跑起来
-
导入项目中所需jar包
-
创建项目包结构
-
编写实体类
ORM映射:表-类映射
-
编写基础公共类
- 数据库配置文件
- 编写数据库的公共类
- 编写字符编码过滤器
-
导入静态资源
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&useUnicode=true&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、查看收到的邮件