网页商城

一、准备数据库

需要创建三个表
用户表(uid,username,password,birthday,state,code)
分类表(cid,cname)
商品表 (pid,pname,pdesc,market_price,shop_price,…cid)
单独看分类表和用户表没有任何关系
分类表和商品表有一个对应关系:在商品表上的cid列上设置了一个外键,参照了分类表上的cid
创建表直接套用了SQL文件,代码如下

-- 创建数据库
drop database if exists `store_40`;
create database `store_40`;
-- 使用数据库
use store_40;

-- 1.1 创建用户表
CREATE TABLE `user` (
  `uid` varchar(32) NOT NULL,  #用户编号
  `username` varchar(20) DEFAULT NULL,		#用户名
  `password` varchar(20) DEFAULT NULL,		#密码
  `name` varchar(20) DEFAULT NULL,			#昵称
  `email` varchar(30) DEFAULT NULL,			#电子邮箱
  `telephone` varchar(20) DEFAULT NULL,		#电话
  `birthday` date DEFAULT NULL,				#生日
  `sex` varchar(10) DEFAULT NULL,			#性别
  `state` int(11) DEFAULT 0,				#状态:0=未激活,1=已激活
  `code` varchar(64) DEFAULT NULL,			#激活码
  PRIMARY KEY (`uid`)
) ;
-- 1.2 初始化用户默认数据
INSERT INTO `user` VALUES ('373eb242933b4f5ca3bd43503c34668b','ccc','ccc','aaa','[email protected]','15723689921','2015-11-04','男',0,'9782f3e837ff422b9aee8b6381ccf927bdd9d2ced10d48f4ba4b9f187edf7738'),('3ca76a75e4f64db2bacd0974acc7c897','bb','bb','张三','[email protected]','15723689921','1990-02-01','男',0,'1258e96181a9457987928954825189000bae305094a042d6bd9d2d35674684e6'),('62145f6e66ea4f5cbe7b6f6b954917d3','cc','cc','张三','[email protected]','15723689921','2015-11-03','男',0,'19f100aa81184c03951c4b840a725b6a98097aa1106a4a38ba1c29f1a496c231'),('c95b15a864334adab3d5bb6604c6e1fc','bbb','bbb','老王','[email protected]','15712344823','2000-02-01','男',0,'71a3a933353347a4bcacff699e6baa9c950a02f6b84e4f6fb8404ca06febfd6f'),('f55b7d3a352a4f0782c910b2c70f1ea4','aaa','aaa','小王','[email protected]','15712344823','2000-02-01','男',1,NULL);

-- 2.1 创建分类表
CREATE TABLE `category` (
  `cid` varchar(32) NOT NULL,
  `cname` varchar(20) DEFAULT NULL,	#分类名称
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 2.2 初始化分类默认数据
INSERT INTO `category` VALUES ('1','手机数码'),('172934bd636d485c98fd2d3d9cccd409','运动户外'),('2','电脑办公'),('3','家具家居'),('4','鞋靴箱包'),('5','图书音像'),('59f56ba6ccb84cb591c66298766b83b5','aaaa'),('6','母婴孕婴'),('afdba41a139b4320a74904485bdb7719','汽车用品');

-- 3.1 创建商品表
CREATE TABLE `product` (
  `pid` varchar(32) NOT NULL,
  `pname` varchar(50) DEFAULT NULL,		#商品名称
  `market_price` double DEFAULT NULL,	#市场价
  `shop_price` double DEFAULT NULL,		#商城价
  `pimage` varchar(200) DEFAULT NULL,	#商品图片路径
  `pdate` date DEFAULT NULL,			#上架时间
  `is_hot` int(11) DEFAULT NULL,		#是否热门:0=不热门,1=热门
  `pdesc` varchar(255) DEFAULT NULL,	#商品描述
  `pflag` int(11) DEFAULT 0,			#商品标记:0=未下架(默认值),1=已经下架
  `cid` varchar(32) DEFAULT NULL,		#分类id
  PRIMARY KEY (`pid`),
  KEY `product_fk_0001` (`cid`),
  CONSTRAINT `product_fk_0001` FOREIGN KEY (`cid`) REFERENCES `category` (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 3.2 初始化商品默认数据
INSERT INTO `product` VALUES ('1','适用小米note m4小米4c小米3手机屏幕总成寄修维修单独换外屏触摸',1399,1299,'products/1/c_0001.jpg','2015-11-02',1,'小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待',0,'1'),('10','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02',1,'华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!',0,'1'),('11','vivo X5Pro',2399,2298,'products/1/c_0014.jpg','2015-11-02',1,'移动联通双4G手机 3G运存版 极光白【购机送蓝牙耳机+蓝牙自拍杆】新升级3G运行内存·双2.5D弧面玻璃·眼球识别技术',0,'1'),('12','努比亚(nubia)My 布拉格',1899,1799,'products/1/c_0013.jpg','2015-11-02',0,'努比亚(nubia)My 布拉格 银白 移动联通4G手机 双卡双待【嗨11,下单立减100】金属机身,快速充电!布拉格相机全新体验!',0,'1'),('13','华为 麦芒4',2599,2499,'products/1/c_0012.jpg','2015-11-02',1,'华为 麦芒4 晨曦金 全网通版4G手机 双卡双待金属机身 2.5D弧面屏 指纹解锁 光学防抖',0,'1'),('14','vivo X5M',1899,1799,'products/1/c_0011.jpg','2015-11-02',0,'vivo X5M 移动4G手机 双卡双待 香槟金【购机送蓝牙耳机+蓝牙自拍杆】5.0英寸大屏显示·八核双卡双待·Hi-Fi移动KTV',0,'1'),('15','Apple iPhone 6 (A1586)',4399,4288,'products/1/c_0015.jpg','2015-11-02',1,'Apple iPhone 6 (A1586) 16GB 金色 移动联通电信4G手机长期省才是真的省!点击购机送费版,月月送话费,月月享优惠,畅享4G网络,就在联通4G!',0,'1'),('16','华为 HUAWEI Mate S 臻享版',4200,4087,'products/1/c_0016.jpg','2015-11-03',0,'华为 HUAWEI Mate S 臻享版 手机 极昼金 移动联通双4G(高配)满星评价即返30元话费啦;买就送电源+清水套+创意手机支架;优雅弧屏,mate7升级版',0,'1'),('17','索尼(SONY) E6533 Z3+',4099,3999,'products/1/c_0017.jpg','2015-11-02',0,'索尼(SONY) E6533 Z3+ 双卡双4G手机 防水防尘 涧湖绿索尼z3专业防水 2070万像素 移动联通双4G',0,'1'),('18','HTC One M9+',3599,3499,'products/1/c_0018.jpg','2015-11-02',0,'HTC One M9+(M9pw) 金银汇 移动联通双4G手机5.2英寸,8核CPU,指纹识别,UltraPixel超像素前置相机+2000万/200万后置双镜头相机!降价特卖,惊喜不断!',0,'1'),('19','HTC Desire 826d 32G 臻珠白',1599,1469,'products/1/c_0020.jpg','2015-11-02',1,'后置1300万+UltraPixel超像素前置摄像头+【双】前置扬声器+5.5英寸【1080p】大屏!',0,'1'),('2','中兴 AXON',2899,2699,'products/1/c_0002.jpg','2015-11-05',1,'中兴 AXON 天机 mini 压力屏版 B2015 华尔金 移动联通电信4G 双卡双待',0,'1'),('20','小米 红米2A 增强版 白色',649,549,'products/1/c_0019.jpg','2015-11-02',0,'新增至2GB 内存+16GB容量!4G双卡双待,联芯 4 核 1.5GHz 处理器!',0,'1'),('21','魅族 魅蓝note2 16GB 白色',1099,999,'products/1/c_0021.jpg','2015-11-02',0,'现货速抢,抢完即止!5.5英寸1080P分辨率屏幕,64位八核1.3GHz处理器,1300万像素摄像头,双色温双闪光灯!',0,'1'),('22','三星 Galaxy S5 (G9008W) 闪耀白',2099,1999,'products/1/c_0022.jpg','2015-11-02',1,'5.1英寸全高清炫丽屏,2.5GHz四核处理器,1600万像素',0,'1'),('23','sonim XP7700 4G手机',1799,1699,'products/1/c_0023.jpg','2015-11-09',1,'三防智能手机 移动/联通双4G 安全 黑黄色 双4G美国军工IP69 30天长待机 3米防水防摔 北斗',0,'1'),('24','努比亚(nubia)Z9精英版 金色',3988,3888,'products/1/c_0024.jpg','2015-11-02',1,'移动联通电信4G手机 双卡双待真正的无边框!金色尊贵版!4GB+64GB大内存!',0,'1'),('25','Apple iPhone 6 Plus (A1524) 16GB 金色',5188,4988,'products/1/c_0025.jpg','2015-11-02',0,'Apple iPhone 6 Plus (A1524) 16GB 金色 移动联通电信4G手机 硬货 硬实力',0,'1'),('26','Apple iPhone 6s (A1700) 64G 玫瑰金色',6388,6088,'products/1/c_0026.jpg','2015-11-02',0,'Apple iPhone 6 Plus (A1524) 16GB 金色 移动联通电信4G手机 硬货 硬实力',0,'1'),('27','三星 Galaxy Note5(N9200)32G版',5588,5388,'products/1/c_0027.jpg','2015-11-02',0,'旗舰机型!5.7英寸大屏,4+32G内存!不一样的SPen更优化的浮窗指令!赠无线充电板!',0,'1'),('28','三星 Galaxy S6 Edge+(G9280)32G版 铂光金',5999,5888,'products/1/c_0028.jpg','2015-11-02',0,'赠移动电源+自拍杆+三星OTG金属U盘+无线充电器+透明保护壳',0,'1'),('29','LG G4(H818)陶瓷白 国际版',3018,2978,'products/1/c_0029.jpg','2015-11-02',0,'李敏镐代言,F1.8大光圈1600万后置摄像头,5.5英寸2K屏,3G+32G内存,LG年度旗舰机!',0,'1'),('3','华为荣耀6',1599,1499,'products/1/c_0003.jpg','2015-11-02',0,'荣耀 6 (H60-L01) 3GB内存标准版 黑色 移动4G手机',0,'1'),('30','微软(Microsoft) Lumia 640 LTE DS (RM-1113)',1099,999,'products/1/c_0030.jpg','2015-11-02',0,'微软首款双网双卡双4G手机,5.0英寸高清大屏,双网双卡双4G!',0,'1'),('31','宏碁(acer)ATC705-N50 台式电脑',2399,2299,'products/1/c_0031.jpg','2015-11-02',0,'爆款直降,满千减百,品质宏碁,特惠来袭,何必苦等11.11,早买早便宜!',0,'2'),('32','Apple MacBook Air MJVE2CH/A 13.3英寸',6788,6688,'products/1/c_0032.jpg','2015-11-02',0,'宽屏笔记本电脑 128GB 闪存',0,'2'),('33','联想(ThinkPad) 轻薄系列E450C(20EH0001CD)',4399,4199,'products/1/c_0033.jpg','2015-11-02',0,'联想(ThinkPad) 轻薄系列E450C(20EH0001CD)14英寸笔记本电脑(i5-4210U 4G 500G 2G独显 Win8.1)',0,'2'),('34','联想(Lenovo)小新V3000经典版',4599,4499,'products/1/c_0034.jpg','2015-11-02',0,'14英寸超薄笔记本电脑(i7-5500U 4G 500G+8G SSHD 2G独显 全高清屏)黑色满1000減100,狂减!火力全开,横扫3天!',0,'2'),('35','华硕(ASUS)经典系列R557LI',3799,3699,'products/1/c_0035.jpg','2015-11-02',0,'15.6英寸笔记本电脑(i5-5200U 4G 7200转500G 2G独显 D刻 蓝牙 Win8.1 黑色)',0,'2'),('36','华硕(ASUS)X450J',4599,4399,'products/1/c_0036.jpg','2015-11-02',0,'14英寸笔记本电脑 (i5-4200H 4G 1TB GT940M 2G独显 蓝牙4.0 D刻 Win8.1 黑色)',0,'2'),('37','戴尔(DELL)灵越 飞匣3000系列',3399,3299,'products/1/c_0037.jpg','2015-11-03',0,' Ins14C-4528B 14英寸笔记本(i5-5200U 4G 500G GT820M 2G独显 Win8)黑',0,'2'),('38','惠普(HP)WASD 暗影精灵',5699,5499,'products/1/c_0038.jpg','2015-11-02',0,'15.6英寸游戏笔记本电脑(i5-6300HQ 4G 1TB+128G SSD GTX950M 4G独显 Win10)',0,'2'),('39','Apple 配备 Retina 显示屏的 MacBook',11299,10288,'products/1/c_0039.jpg','2015-11-02',0,'Pro MF840CH/A 13.3英寸宽屏笔记本电脑 256GB 闪存',0,'2'),('4','联想 P1',2199,1999,'products/1/c_0004.jpg','2015-11-02',0,'联想 P1 16G 伯爵金 移动联通4G手机充电5分钟,通话3小时!科技源于超越!品质源于沉淀!5000mAh大电池!高端商务佳配!',0,'1'),('40','机械革命(MECHREVO)MR X6S-M',6799,6599,'products/1/c_0040.jpg','2015-11-02',0,'15.6英寸游戏本(I7-4710MQ 8G 64GSSD+1T GTX960M 2G独显 IPS屏 WIN7)黑色',0,'2'),('41','神舟(HASEE) 战神K660D-i7D2',5699,5499,'products/1/c_0041.jpg','2015-11-02',0,'15.6英寸游戏本(i7-4710MQ 8G 1TB GTX960M 2G独显 1080P)黑色',0,'2'),('42','微星(MSI)GE62 2QC-264XCN',6199,5999,'products/1/c_0042.jpg','2015-11-02',0,'15.6英寸游戏笔记本电脑(i5-4210H 8G 1T GTX960MG DDR5 2G 背光键盘)黑色',0,'2'),('43','雷神(ThundeRobot)G150S',5699,5499,'products/1/c_0043.jpg','2015-11-02',0,'15.6英寸游戏本 ( i7-4710MQ 4G 500G GTX950M 2G独显 包无亮点全高清屏) 金',0,'2'),('44','惠普(HP)轻薄系列 HP',3199,3099,'products/1/c_0044.jpg','2015-11-02',0,'15-r239TX 15.6英寸笔记本电脑(i5-5200U 4G 500G GT820M 2G独显 win8.1)金属灰',0,'2'),('45','未来人类(Terrans Force)T5',10999,9899,'products/1/c_0045.jpg','2015-11-02',0,'15.6英寸游戏本(i7-5700HQ 16G 120G固态+1TB GTX970M 3G GDDR5独显)黑',0,'2'),('46','戴尔(DELL)Vostro 3800-R6308 台式电脑',3299,3199,'products/1/c_0046.jpg','2015-11-02',0,'(i3-4170 4G 500G DVD 三年上门服务 Win7)黑',0,'2'),('47','联想(Lenovo)H3050 台式电脑',5099,4899,'products/1/c_0047.jpg','2015-11-11',0,'(i5-4460 4G 500G GT720 1G独显 DVD 千兆网卡 Win10)23英寸',0,'2'),('48','Apple iPad mini 2 ME279CH/A',2088,1888,'products/1/c_0048.jpg','2015-11-02',0,'(配备 Retina 显示屏 7.9英寸 16G WLAN 机型 银色)',0,'2'),('49','小米(MI)7.9英寸平板',1399,1299,'products/1/c_0049.jpg','2015-11-02',0,'WIFI 64GB(NVIDIA Tegra K1 2.2GHz 2G 64G 2048*1536视网膜屏 800W)白色',0,'2'),('5','摩托罗拉 moto x(x+1)',1799,1699,'products/1/c_0005.jpg','2015-11-01',0,'摩托罗拉 moto x(x+1)(XT1085) 32GB 天然竹 全网通4G手机11月11天!MOTO X震撼特惠来袭!1699元!带你玩转黑科技!天然材质,原生流畅系统!',0,'1'),('50','Apple iPad Air 2 MGLW2CH/A',2399,2299,'products/1/c_0050.jpg','2015-11-12',0,'(9.7英寸 16G WLAN 机型 银色)',0,'2'),('6','魅族 MX5 16GB 银黑色',1899,1799,'products/1/c_0006.jpg','2015-11-02',0,'魅族 MX5 16GB 银黑色 移动联通双4G手机 双卡双待送原厂钢化膜+保护壳+耳机!5.5英寸大屏幕,3G运行内存,2070万+500万像素摄像头!长期省才是真的省!',0,'1'),('7','三星 Galaxy On7',1499,1398,'products/1/c_0007.jpg','2015-11-14',0,'三星 Galaxy On7(G6000)昂小七 金色 全网通4G手机 双卡双待新品火爆抢购中!京东尊享千元良机!5.5英寸高清大屏!1300+500W像素!评价赢30元话费券!',0,'1'),('8','NUU NU5',1288,1190,'products/1/c_0008.jpg','2015-11-02',0,'NUU NU5 16GB 移动联通双4G智能手机 双卡双待 晒单有礼 晨光金香港品牌 2.5D弧度前后钢化玻璃 随机附赠手机套+钢化贴膜 晒单送移动电源+蓝牙耳机',0,'1'),('9','乐视(Letv)乐1pro(X800)',2399,2299,'products/1/c_0009.jpg','2015-11-02',0,'乐视(Letv)乐1pro(X800)64GB 金色 移动联通4G手机 双卡双待乐视生态UI+5.5英寸2K屏+高通8核处理器+4GB运行内存+64GB存储+1300万摄像头!',0,'1');

-- 4 创建订单表
CREATE TABLE `orders` (
  `oid` varchar(32) NOT NULL,
  `ordertime` datetime DEFAULT NULL,		#下单时间
  `total` double DEFAULT NULL,				#总价
  `state` int(11) DEFAULT NULL,				#订单状态:1=未付款;2=已付款,未发货;3=已发货,没收货;4=收货,订单结束
  `address` varchar(30) DEFAULT NULL,		#收获地址
  `name` varchar(20) DEFAULT NULL,			#收获人
  `telephone` varchar(20) DEFAULT NULL,		#收货人电话
  `uid` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`oid`),
  KEY `order_fk_0001` (`uid`),
  CONSTRAINT `order_fk_0001` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`)
) ;

-- 5 创建订单项表
CREATE TABLE `orderitem` (
  `itemid` varchar(32) NOT NULL,
  `quantity` int(11) DEFAULT NULL,			#购买数量
  `total` double DEFAULT NULL,			#小计
  `pid` varchar(32) DEFAULT NULL,		#购买商品的id
  `oid` varchar(32) DEFAULT NULL,		#订单项所在订单id
  PRIMARY KEY (`itemid`),
  KEY `order_item_fk_0001` (`pid`),
  KEY `order_item_fk_0002` (`oid`),
  CONSTRAINT `order_item_fk_0001` FOREIGN KEY (`pid`) REFERENCES `product` (`pid`),
  CONSTRAINT `order_item_fk_0002` FOREIGN KEY (`oid`) REFERENCES `orders` (`oid`)
) ;

二、通用Servlet的改写

在原来的数据增删改查中,需要五个servlet来编写,现在需要减少servlet的数量。

原理:从客户端向服务端发起请求,每次都要传递额外的键值对的数据“method=”,服务端获取到method对应的内容之后,通过判断不同的内容调用不同的功能。

从客户端向服务端发起请求,调用功能方式:
1_通过表单向服务端发起请求

用户

2_通过链接向服务端发起请求

删除学生

3_Ajax向服务端发起请求



以上三种方式的共同点就是在访问servlet的时候,后面缀了一个method

建立servletDemo,来使用一个servlet根据method的不同实现不同的功能

@WebServlet(name = "ServletDemo01")
public class ServletDemo01 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取客户端提交到服务器端的method
        String md = request.getParameter("method");
        System.out.println(md);
        //定义变量,存放功能执行完毕之后要转发的路径
        String path = null;

        //通过判断md中不同的内容来决定本次功能
        if("addStu".equals(md)){
            path = addStu(request,response);
        }else if ("delStu".equals(md)){
            path = delStu(request,response);
        }else if ("checkStu".equals(md)){
            path = checkStu(request,response);
        }else if ("".equals(md)){

        }
        if (null != path){
            //服务器端的转发
            request.getRequestDispatcher(path).forward(request,response);
        }
    }

    protected String addStu(HttpServletRequest request,HttpServletResponse response) {
        System.out.println("添加学生");
        return "/test.jsp";
    }
    protected String delStu(HttpServletRequest request,HttpServletResponse response) {
        System.out.println("删除学生");
        return "/test.jsp";
    }
    protected String checkStu(HttpServletRequest request,HttpServletResponse response) throws IOException {
        System.out.println("检查学生");
        response.setContentType("text/html; charset=utf-8");
        response.getWriter().write("憨憨");
        return null;
    }
}

但是这个版本中的if else语句太多,我们使用反射来简化一下,所以建立servletDemo02,

@WebServlet(name = "ServletDemo02")
public class ServletDemo02 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
//        使用反射调用类中的方法的时候,方法必须是public,受保护的不行
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        获取客户端提交到服务器的method对应的值
        String md = request.getParameter("method");
//        定义变量,存放功能执行完毕之后要转发的路径
        String path = null;
//        获取到当前字节码对象(ServletDemo02.class在内存中的对象)
        Class clazz = this.getClass();

        try {
//            获取clazz上名称为md的方法
            Method method = clazz.getMethod(md,HttpServletRequest.class,HttpServletResponse.class);
            if (null != method){
//                调用找到的方法
                path = (String)method.invoke(this,request,response);
            }
            if (null != path){
//                服务端的转发
                request.getRequestDispatcher(path).forward(request,response);
            }

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

    public String addStu(HttpServletRequest request,HttpServletResponse response) {
        System.out.println("添加学生");
        return "/test.jsp";
    }
    public String delStu(HttpServletRequest request,HttpServletResponse response) {
        System.out.println("删除学生");
        return "/test.jsp";
    }
    public String checkStu(HttpServletRequest request,HttpServletResponse response) throws IOException {
        System.out.println("检查学生");
        response.setContentType("text/html; charset=utf-8");
        response.getWriter().write("憨憨");
        return null;
    }
}
对于反射,需要插一句, Class clazz = this.getClass();和   path = (String)method.invoke(this,request,response);这两句话中this的含义,就像下图中的例子,this指的是当前类(AA),和当前类的对象(new AA())。

网页商城_第1张图片如果想再简化一下,就开始打doPost和doGet的注意了,能不能把这两个函数去掉,要知道,一个servlet文件执行的时候,是先创建该servlet的一个对象A,然后用该对象A调用servlet类的父类中的init()函数,之后再调用service()函数,在service()函数中,再调用doPost和doGet,不信你看下图,这个service函数是在HttpServlet类中的
网页商城_第2张图片在这里插入图片描述所以,如果重写一个service函数,就不用在使用doGet和doPost函数了。先创建一个重写service函数的BaseServlet

@WebServlet(name = "BaseServlet")
public class BaseServlet extends HttpServlet {
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
//        这个utf-8只能放到service种来用,不能放到具体的函数中去,获取反射中method.invoke不调用编码设置语句
        req.setCharacterEncoding("utf-8");
//        获取客户端提交到服务器端的method对应的值
        String md = req.getParameter("method");
//        定义变量,存放功能执行完毕之后要转发的路径
        String path = null;
//        获取到当前字节码对象(BaseServlet.class在内存中的对象)
        Class clazz = this.getClass();
        try {
//            获取clazz上名称为md方法
            Method method = clazz.getMethod(md,HttpServletRequest.class,HttpServletResponse.class);
            if (null != method){
//                调用找到的方法
//                此处的this是获取的字节码对象类的对象,就是谁的字节码对象,谁的对象
                path = (String)method.invoke(this,req,res);
            }
            System.out.println("-----------------");
            if (null != path){
//                服务器的转发
                req.getRequestDispatcher(path).forward(req,res);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这个servlet就是用于接受各种method,但是接收到method关键字后具体的函数体在哪呢,在建立一个ServletDemo03来继承BaseServlet,

@WebServlet(name = "ServletDemo03")
public class ServletDemo03 extends BaseServlet {
    public ServletDemo03(){
        System.out.println("没有参数构造函数 ");
//        根据运行结果来看,Servlet是先创建了一个当前类(ServletDemo03)的对象,然后使用该对象调用父类的init方法,之后再调用service方法,
//        之前使用的doGet和doPost方法是在service方法中调用的,现在改变了service方法,就不需要doGet和doPost方法了
    }

    public String addStu(HttpServletRequest request,HttpServletResponse response) {
        System.out.println("添加学生");
        return "/test.jsp";
    }
    public String delStu(HttpServletRequest request,HttpServletResponse response) {
        System.out.println("删除学生");
        return "/test.jsp";
    }
    public String checkStu(HttpServletRequest request,HttpServletResponse response) throws IOException {
        System.out.println("检查学生");
        response.setContentType("text/html; charset=utf-8");
        response.getWriter().write("憨憨");
        return null;
    }
}

这说明什么,有了这个BaseServlet之后,我们只要再用一个Servlet来写函数体,就可以直接把多个功能写在一个servlet中了,极大地减少了Servlet的数量。

三、搭建项目环境

1_创建工程InterStore
2_创建各个包结构
cn.zjw.store.web.servlet
cn.zjw.store.web.fitler
cn.zjw.store.web.base
cn.zjw.store.service
cn.zjw.store.service.serviceImpl
cn.zjw.store.dao
cn.zjw.store.dao.daoImpl
cn.zjw.store.domain
cn.zjw.store.utils
3_导入jar包
网页商城_第3张图片
从上到下的jar包依次是
C3P0连接池
beanutils工具
dbutils
fileupload(不是太清楚是搞什么的)
fileupload
beanutils工具
jstl标准标签库
邮件
C3P0连接池
mysql驱动
jstl标准标签库

3_导入工具类
CookUtils.java:在Cookie数组中,获取指定名称的cookie
JDBCUtils.java:这个是让数据库工具类。获取dataSourse。
MailUtils.java:
MD5Utils.java:
MyBeanUtils.java:
UploadUtils.java:
UUIDUtils.java:这个是获取一个 32位的十六进制的数字,用于ID和激活码。
5_导入配置文件
C3P0需要导入配置文件,c3p0-config.xml
6_导入编码过滤器
EncodingFilter.java:对过滤器中的request上的三个方法进行增强, req.getParameterValues(); req.getParameterMap(); req.getParameter();
需要手动在web.xml文件中对该过滤器进行配置。
7_导入BaseServlet
BaseServlet.java:上面说过了,用于减少servlet的数量
8_导入jsp页面
这个jsp页面我是直接套用了学习视频中的jsp文件。主要做的是后端的一些编写。
网页商城_第4张图片网页商城_第5张图片
9_创建用户模块相关程序
得先创建一个User类,用于将注册用户的各种信息封装进一个对象中。
接着还需要创建UserServlet、UserService、UserServiceImpl、UserDao、UserDaoImpl。

四、实现用户注册功能

开发约定
为了项目管理方便,不会从客户端直接发送请求到JSP页面,先请求到Servlet,再由Servlet转发到JSP页面。
4.1页面路径跳转
1_修改链接,旨在让用户点击注册按钮后先经过servlet再跳转到注册测页面。
index.jsp先跳转到UserServlet中,再由函数registUI跳转到regist.jsp
UserServlet4.2注册功能与案例分析

网页商城_第6张图片4.3 开发步骤(普通MVC功能)
1_准备工作(表单属性设置)准备工作实现完毕后,可以从客户端向服务端发起请求,需要注意的是套用的代码中各个文本框中是没有name属性的而且form标签中没有action属性,所以要描述准确,regist.jsp中的注册表单代码如下

2_UserServlet明确要实现的功能,中文注释,代码,在这其中,是使用map统一接受了regist.jsp中的表单数据,而且刚开始,是没有使用工具类的遍历,将map存放在一个set集合中,使用迭代器遍历map中的数据,以下中有其对应代码(已被注释),之后使用了BeanUtils工具类中的 populate(object,map)函数,该函数旨在查找map集合中是否有object的属性,有的话利用反射将属性值通过object类的set方法赋给当前object对象,这样就将表单中的数据全部封装到了一个object对象中了,但是此次的map集合中有date类型的数据,所以需要转化,为了简化代码,将转化代码写在了MyBeanUtils中,然后在该类中重写populate方法。
在userRegist方法的最后,添加了注册成功或失败的信息,并跳转到info.jsp那。

@WebServlet(name = "UserServlet")
public class UserServlet extends BaseServlet {
    public String registUI (HttpServletRequest request,HttpServletResponse response){
        return "/jsp/register.jsp";
    }

    public String userRegist(HttpServletRequest request,HttpServletResponse response) throws Exception{


        //接受表单数据
        Map map = request.getParameterMap();
//        新建一个User对象,存放注册信息
        User user = new User();


/*          以下的内容可以写在MyBeanUtils工具类中
//        BeanUtils找到User.class文件上有setBirthday这个方法,要执行,将
//        “1992-3-3”转换为时间日期类型,BeanUtils不知道这个字符的时间格式是什么,
//        以下三行代码设置时间转换格式
//        1、创建时间类型的转换器
        DateConverter dt = new DateConverter();
//        2、设置转换的格式
        dt.setPattern("yyyy-MM-dd");
//        3、注册转换器
        ConvertUtils.register(dt,java.util.Date.class);
        BeanUtils.populate(user,map);*/

        MyBeanUtils.populate(user,map);

        //为用户的其他属性赋值
        user.setUid(UUIDUtils.getId());
        user.setState(0);
        user.setCode(UUIDUtils.getCode());

        System.out.println(user);

        /*
        //不用工具类的遍历方法
        //遍历map中的数据
        Set keySet = map.keySet();
        Iterator iterator = keySet.iterator();
        while(iterator.hasNext()){
            String str = iterator.next();
            System.out.println(str);
            String[] strs = map.get(str);
            for (String string : strs){
                System.out.println(string);
            }
            System.out.println();
        }*/

//        调用业务层注册功能
        UserService userService = new UserServiceImpl();
        try{
            userService.userRegist(user);
//            注册成功,向用户邮箱发送信息,跳转提示页面
            request.setAttribute("msg","憨憨注册成功,请激活!");
        }catch(Exception e){
//            注册失败,跳转到提示页面
            request.setAttribute("msg","憨憨注册失败,请重新注册!");
        }
        return "/jsp/info.jsp";

    }

}

3_service和dao的代码。主要是UseDaoImpl中的代码。

public class UserDaoImpl implements UserDao {
    @Override
    public void userRegist(User user) throws SQLException {
        String sql = "INSERT INTO USER VALUES(?,?,?,?,?,?,?,?,?,?)";
        QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
        Object[] params = {user.getUid(),user.getUsername(),user.getPassword(),user.getName(),user.getEmail(),user.getTelephone(),user.getBirthday(),user.getSex(),user.getState(),user.getCode()};
        queryRunner.update(sql,params);
    }
}

4_jsp页面
要写一下info.jsp,接受从UserServlet返回过来的注册提示信息。
网页商城_第7张图片

五、电子邮箱

按照学习视频中的步骤来说,在用户注册的时候,会生成一个code激活码,服务器将该激活码发送至用户的有相中,然后用户可以激活账号,但是在配置本地邮箱服务器和客户端的时候出现了问题,这个邮箱激活码目前暂时实现不了。
问题描述:
按照视频中的步骤来说,邮箱服务器的配置应该是没有问题的。(易邮邮箱服务器),服务器设置单域名,store.com。
网页商城_第8张图片网页商城_第9张图片但是到配置到配置邮箱客户端的时候(Foxmail邮箱客户端),先是建立邮箱服务器中的账户[email protected],密码是aaa,
网页商城_第10张图片然后下一步,将接收和发送服务器全部设置为localhost,
网页商城_第11张图片之后测试用户账户设置的时候就会出现问题,当前还未解决,百度无果。网上其他人按照这种方法都顺利配置成功了,不知道问题出在哪。
网页商城_第12张图片网页商城_第13张图片网页商城_第14张图片

你可能感兴趣的:(网页商城)