商城案例

        分模块:用户模块→ 分类模块 → 商品模块→购物车模块(最难)→  订单模块
后台模块(往前台的数据的增删改查) 今日任务: 1用户注册
a注册完成
b给注册人发邮件
2用户激活
a 去邮箱激活发送的邮件
3用户登录
a 登录失败:回首页显示
b 判断用户是否激活了邮件
c 如果没激活让用户去激活,如果激活了首页展示
4用户退出
Session相关 注意点:
1.数据库和表
create database store;
use store; 用户表:
CREATE TABLE `user` (
`uid` varchar(32) NOT NULL, //id号
`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 NULL, // 0 未激活 1 已激活
`code` varchar(64) DEFAULT NULL, // 激活码
PRIMARY KEY (`uid`) //主键
设置账号是否已经注销了,如果注销了,设置一个标记,标记已注销.
) ENGINE=InnoDB DEFAULT CHARSET=utf8; //设置编码格式 servlet工具类的抽取:
之前编写的servlet的问题:
1.doget每次请求都会执行
2.用了大量 if else if 判断执行的是那个方法让方法执行
Method method = this.getClass().getMethod(mt, HttpServletRequest.class,HttpServletResponse.class);
method.invoke(this, request,response);
3.每个方法执行的结果无非就是请求转发或者重定向或者打印数据
让所有的方法都返回一个字符串
若最后的结果需要请求转发,就把转发的路径给返回
若最后的结果不需要请求转发,就返回一个null String path=method.invoke(this, request,response);
if(path != null){
request.getx(path).forward(...)
}
4.所有servlet的service中的代码都一样
向上继续抽取
编写一个BaseServlet,将之前方法中的代码复制过来即可,
然所有的servlet都继承baseservlet即可 今日难点:servlet工具类的抽取(baseServlet) :真正的企业开发中一个模块一个servlet 1先搭建数据库
2建立项目并且将页面信息加载进去
3在外部建立一个index.jsp 跳转到servlet(list=封装热门商品--->请求转发到首页显示数据库面的信息)
<%request.getrequestDispacher(“”);%> 4找到登录页面中登录与注册入口 href=${}/jsp/jsp;
//如果一个页面放在了WEB-INF文件下:不能被浏览器直接访问,只能通过代码访问,(通过Servlet)
步骤: 在href= 标签里${pageContext....}/sd1
创建一个servlet 名字为sd1
doGet方法中使用请求转发 getRequestDispacher(需要访问的jsp);
注意:之前做需求的时候一个功能一个Servlet,发现这样做的效率不高
解决方案:一个模块一个servlet(UserServlet)
实现方案:传参
在href= 标签里${pageContext....}/sd1改成${pageContext....}/user?method=loginUI Servlet中的代码实现
doGet()}{
String method = request.getPatameter(“method”);
If(loginUI.equals(method){
//登录
LoginUI(request,response);
}else if(registUI.equals(method)){
//注册
RegistUI(request,response)
} 问:虽然传参方式满足了一个模块使用一个servlet但是if,else太多,不利于后期维护
是否有什么方法解决?
答:反射:传什么方法用什么方法 Class.forName(“cn.baidu.web.UserServlet”)
或者Class clazz =this.getClass();
String me = request.getParameter(“method”)) Method method = clazz.getMethod(me,HttpServletRequest.cass.....)
String value = (String)Method.invoke(clazz.newInstance(),request,response)
//做一个统一的请求转发
If(value!=null){
request.getRequestDispacher(Value).forward(request,response)
}
问:反射的方式解决了频繁编写 if else问题
//虽然好处很大,但是只限于用户模块的功能,以后能不能所有的模块全部不需要在写了
答:有:工具类的抽取(base extends HttpServlet)
} //登录
Public String LoginUI( HttpServletRequest request){
//到登录页面
//request.getRequest.Dispacher(/jsp/login.jsp)
Return “jsp/login.jsp”
}
//注册 重定向
Public String RegistUI( HttpServletRequest request){
//注册
//request.getRequest.Dispacher(/jsp/regist.jsp)
Return “/jsp/regist.jsp ” } //重定向()
Public String zhuce(request,response){
resonse.sendRedirect(“”) Return null;
} 5.创建一个servlet工具类base之后的servlet类只需要继承他并且去掉doGet与doPost,只需要写自己的方法就好,需要用doGet与doPost就找父类
doGet()}{
Try(){}
Class.forName(“cn.baidu.web.UserServlet”)
或者Class clazz =this.getClass();
String me = request.getParameter(“method”)) Method method = clazz.getMethod(me,HttpServletRequest.cass.....)
String value = (String)method.invoke(clazz.newInstance(),request,response)
//做一个统一的请求转发
If(value!=null){
request.getRequestDispacher(Value).forward(request,response)
}
问:反射的方式解决了频繁编写 if else问题
//虽然好处很大,但是只限于用户模块的功能,以后能不能所有的模块全部不需要在写了
答:有:工具类的抽取(base extends HttpServlet)
} 6.UerServlet(注册)
表单提交 action, method=”post”
隐藏域<input tyoe =hidden, name=”method” value =’regist’> //日期控件......有资料,只读属性
/把过滤器拿过来动态代理,编码
配置文件XML中药配置一个filter
Url->/*
创建一个JAVABean(不要用int用Integer,int的默认值是0,Integer默认值是null)
不和业务逻辑起冲突
uid用UUID保证它唯一,激活码 uuid+uuid Public String regist(reqest,response){
Try(){
//获取注册的所有页面信息
Map<String,String[]> map = request.getParameter();
//创建一个bean
User uer = new User();
//把map中的数据封装到User中
BeanUtils.populate(user,map);
//设置主键uid
user.setUid(UUID.randomUUID().toString().replace(“-”,””));
//设置激活状态,刚注册的时候是未激活状态
user.setState(0);
//设置激活码 uuid+uuid
user.setCode(...);
//调用service
//以后工作中的开发都是面向接口开发,好处是拓展性高
UserServic us = new UserServiceImpl();//多态
Us.regist(user);
Syso(数据注册成功,可以给该用户发邮件了) //注册只要成功就给该用户发邮件一个工具类mailUtils,一个jar包
//email就是收信人 emaliMsg是正文 String emaliMsg = “”+user.getName()+”<a href=’http://httplocalhost:8080/store/user?method=active&code=’’+user.getCode()> 点击激活</a>” mailUtils. request.setAttribute(“msg”,”邮件发送成功,去邮件激活再登录”)
}
}catch(Exeption e){
e.printStack...
//请求转发到另一个页面
request.setAttribute(“msg”,”注册失败,稍后继续..”);
Return “ /jsp/**.jsp”
}
Return “/jsp/**.jsp”;
} //激活
Public String active(Http..request,Http...response){
Try{
//先判断数据库中有没有该用户
String code = request.getParameter(“code”);
UserService us = new UserService();
User user = us.findByCode(code);
If(user==null){
//代表该用户已经从数据库中移除了
request.setAttibute(“msg”,”激活失效,重新注册”)
Return ”/jsp/**.jsp”
}
//有的话就把状态码改成1
user.setState(1);
//提示信息,激活成功,去登录吧
request.setAttrubute(“msg”,”激活成功去登录吧”)
}catch(Exception e){
request.setAttribute(“msg”,”查询用户失败,请稍后继续”)
} Return “/jsp/**.jsp”
} //登录的方法实现
//也需要核实jsp中是否有这些name属性
Public String login((Http..request,Http...response){
Try{
HttpSession session = request.getSession(); //获取用户名与密码
String username = request.getParameter(“username”);
String password = request.getParameter(“password”);
//根据用户名和密码查询该用户
UserService us = new UserServiceImpl();
User user =us.findUser(username,password);
If(user==null){
Request.setA...(“msg”,”用户名或者密码错误”)
Return “/jsp...”
}
//判断是否激活
If(user.getState()!=1){
Request.setA...(“msg”,”没有激活,先激活再登录”)
Return “/jsp...” } //既有该用户也做了激活
自动登录=Request--->javabean---->服务器关闭了-->request中数据没有了
Session--->javabean--->服务器关闭了---->session没有销毁 永远可以从session中拿到javabean(用户的信息永远在session中)
session.setA...(“user”,”user”);
//重定向
response.sendRedirect(request.getContextPath()+”/jsp/**.jsp”) //index.jsp中做el判断 登录注册购物车
<c: if test=”${empty user}”>
</c:if> <c: if test=”${ not empty user}”>
“欢迎***登录”
加一个购物车标签
</c:if> }catch(){
E.print.....
Request.set...(“msg”,”失败”)
Return “/jsp/**.jsp” } Return null;
} //用户退出
点击用户退出就干掉session,在index.jsp中用户退出标签中添加链接
Public String quit((Http..request,Http...response){
Try{
//获取session
HttpSeesion session = request.getSession():
Session.remove(“user”)
//重定向
response.sendRedirect.....
Return null; }
}
前台分类信息展示
从数据库获取导航条的信息展示 分类商品的分页展示 单个商品详情 最新商品和热门商品展示 特点: select 所需要的表: 分类表, 商品表 1.创建分类表
CREATE TABLE `category` (
`cid` varchar(32) NOT NULL,
`cname` varchar(20) DEFAULT NULL,
PRIMARY KEY (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `category` VALUES ('1','手机数码'),('172934bd636d485c98fd2d3d9cccd409','运动户外'),('2','电脑办公'),('3','家具家居'),('4','鞋靴箱包'),('5','图书音像'),('59f56ba6ccb84cb591c66298766b83b5','aaaa'),('6','母婴孕婴'),('afdba41a139b4320a74904485bdb7719','汽车用品'); 2 创建商品表
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 NULL, // 是否下架 0: 上架 1 下架 做逻辑删除的
`cid` varchar(32) DEFAULT NULL,
PRIMARY KEY (`pid`),
KEY `sfk_0001` (`cid`),
CONSTRAINT `sfk_0001` FOREIGN KEY (`cid`) REFERENCES `category` (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `product` VALUES ('1','小米 4c 标准版',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)灵越',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'); 案例1-前台分类信息展示
需求:
访问任意页面的时候,都需要将分类的信息展示出来 技术分析: 静态包含
ajax异步的数据交互 要从redis中获取数据
有数据
直接返回 无数据
从mysql中拿数据
放到redis中
然后返回 实现步骤:
1 抽取所有页面上 logo和菜单部分(head.jsp)
页面加载的时候
编写函数
发送ajax请求 $.post(url,params,fn,type);
url:/store/category
params: method=findAll
fn:将返回值遍历,每一个分类封装成li标签,插入到ul标签内部
type:json
编写categoryservlet,继承baseservlet,编写findAll方法
调用service,查询所有的分类,分类列表的json字符串(String)
写回页面
categoryservice中的操作
调用dao,获取所有的分类
将list转成json返回
2 在所有的页面里将 head.jsp 包含进去
获取返回值
遍历返回值
每一个分类封装成li标签,插入到ul标签内部 3 使用redis进行优化(理解)
修改service层的代码
获取的时候,去redis中获取,
若获取到了返回
若没有获取到,先去mysql数据库中查询出来,将list转成json放入redis中即可 -----------------------------------------------------------------------------------------------------
案例2-分类商品的分页展示
需求:
点击菜单栏上某一个分类的时候,将该分类下的商品,分页展示出来(默认第一页) 技术分析:
分页
起始数据
limit (当前页-1)*每页显示的条数,每页显示的条数 (重要)页面上需要的数据(list)
当前页(pageNumber)
每页显示的条数(pageSize) 总页数(totalPage)
总记录数(totalCount)
总记录数%每页显示的条数==0
总页数=总记录数/每页显示的条数 pageBean 步骤分析:
1.修改head.jsp上的每个分类的超链接
<a href="/store/product?method=findByPage&pageNumber=1&cid=xxx">
2.在cateservlet中编写findByPage方法
获取pagenumber
获取cid
设置pageSize 调用service获取分页的数据 返回值:PageBean 将pagebean放入request域中,请求转发 /jsp/product_list.jsp
3.编写service:
返回值:pagebean
创建一个pagebean 设置当前页需要的数据
调用dao 设置总记录数
调用dao
4.dao
5.在jsp/product_list.jsp上展示商品 ----------------------------------------------------------------------------------------------------- 案例3-单个商品详情 需求:
在首页上点击每个商品,将这个商品的详细信息展示在页面上(product_info.jsp) 步骤分析:
1.给每个商品添加超链接
<a href="/store/product?method=getById&pid=xxx">yy</a>
2
.编写productservlet,继承baseservlet,编写getById
获取商品的pid
调用service获取一个商品 返回值:product
请求转发到product_info.jsp 3.service ,dao 4.在product_info.jsp将商品展示 ------------------------------------------------------------------------------------------------ 案例4-最新商品和热门商品展示
需求:
访问首页的时候,需要将最新商品和热门商品展示出来. is_hot:是否热门
热门: 1
不热门:0 pflag: 是否下架 (逻辑删除)
没下架: 0
下架了: 1 查最新: list =select * from product where pflag=0 order by date desc limit 0,9
查热门: list=SELECT * FROM product WHERE pflag=0 AND is_hot=1 ORDER BY pdate DESC LIMIT 0,9; 步骤: 1.访问项目首页,请求转发productServlet
productServlet中处理
调用productservice查询热门商品和最新商品, 每一个都返回一个list
将两个list放入request域中,请求转发到 /jsp/index.jsp 2.在页面上将数据遍历出来 商城案例实现 今日内容 (购物车模块 订单模块) 购物车 生成订单 案例1-添加到购物车 需求:
在商品的详情页面,输入购买数量,点击加入购物车,将该商品添加到购物车了 技术分析: 一个用户只有一个购物车,购物车里面的商品都是用户临时选择的
所以购物车的商品,我们并不会存在数据库中 现实中:
购物车--->存放商品 在java代码中:
javabean---->商品数据 对等:
Cart---->商品数据 购物车 -------------------------------------> Cart
商品图片 {
商品名称 商品图片属性
商品价格 商品名称属性
商品数量 商品价格属性
商品小计 商品数量属性
商品的小计属性
总金额
商品总金额的属性
} 一个用户---存2个商品(大冬瓜,小冬瓜,黄瓜)-----> Cart
{
购物项对象的集合(3个购物项对象) 商品总金额的属性
} 购物项(多个) CartItem
{
商品图片属性
商品名称属性
商品价格属性
----替换成商品对象(好处:扩展性很强) 商品数量属性
商品的小计属性 } 购物车(1个) Cart
{
购物项集合(new CartItem)
商品总金额的属性
} jack用户---大冬瓜----CartItem(商品对象,商品数量,商品小计 )
jack用户---小冬瓜----CartItem(商品对象,商品数量,商品小计 ----Cart(购物项集合,总金额) 任务:封装这2个对象 CartItem
商品对象--->pid编号
商品数量--->购买数量
商品小计---商品对象.getshop_price*数量
Cart
购物项集合
总金额(待定) ////////////////////////////////
案例2-从购物车移除一个商品
需求:
在cart.jsp上,点击某一个商品的 删除 ,点击确定,从购物车中移除.
步骤分析:
1.给 删除 添加连接
/store/cart?method=remove&pid=xxx 2.在cartservlet中编写remove方法
获取pid
获取cart,执行removeFromCart()方法
重定向到cart.jsp 案例3-清空购物车
需求:
点击cart.jsp上的 清空购物车,需要将购物车中所有商品移除掉 步骤分析:
1.修改 清空购物车的连接
/store/cart?method=clear
2.编写clear方法
获取购物车,执行clearCart()
重定向到cart.jsp上
3.判断购物车中是否有商品,
有则展示
无则提示
///////////////////////// 案例2-生成订单
需求:
在cart.jsp上,点击 "提交订单",将购物车中的商品,最终保存到数据库中. 技术分析: 要把购物车的而所有数据在生成订单的时候,插入的数据库的2张表上 当用户开始点击生成订单的时候
会产生1个订单以及N个订单下的订单商品 1个订单详情 (订单编号,下单时间,订单总金额....) N个订单商品详情 (订单商品的数量 订单商品的时间,订单商品的id...) saveOrders(对象)
订单表(orders)
订单ID: UUID
订单时间: 点击生成订单的当前系统时间
总金额: cart购物车对象中的总金额
订单的状态: 0 未付款 1 已付款未发货 2 以发货未收货 3 以收货未评价 4 已结束 地址
姓名
电话
-------- 下订单的时候不写,在要付款的时候在填写 saveOrderitem(对象)
订单详情表(orderitem)
订单详情ID: uuid
订单ID: 订单表的主键
商品ID: 商品表的主键
数量: 购物项里的数量
小计: 购物项里的小计 需要的表 -- 订单表
javabean=orders(封装订单时间,订单编号,订单总金额,订单状态,订单收货人,订单收货人电话...)
dao:insert into orders values(orders.getoid,) CREATE TABLE `orders` (
`oid` varchar(32) NOT NULL,
`ordertime` date DEFAULT NULL,
`total` double DEFAULT NULL,
`state` int(11) DEFAULT NULL,
`address` varchar(30) DEFAULT NULL,
`name` varchar(20) DEFAULT NULL,
`telephone` varchar(20) DEFAULT NULL,
`uid` varchar(32) DEFAULT NULL,
PRIMARY KEY (`oid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; javabean==orderitem(封装所属订单,封装该订单项的数量,封装该订单项的小计..)
dao:insert into orders values(orderitem.getitemid....) -- 订单商品详情表
CREATE TABLE `orderitem` (
`itemid` varchar(32) NOT NULL,
`count` int(11) DEFAULT NULL,
`subtotal` double DEFAULT NULL,
`pid` varchar(32) DEFAULT NULL, // 订单项下的商品
`oid` varchar(32) DEFAULT NULL, // 订单项所属的订单
PRIMARY KEY (`itemid`),
KEY `fk_0001` (`pid`),
KEY `fk_0002` (`oid`),
CONSTRAINT `fk_0001` FOREIGN KEY (`pid`) REFERENCES `product` (`pid`),
CONSTRAINT `fk_0002` FOREIGN KEY (`oid`) REFERENCES `orders` (`oid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 商城案例实现 今日内容:
我的订单(难点)
单个订单详情
在线支付(第三方的支付平台--易宝(了解))
权限过滤器
//////////////////////////////////////////
案例1-我的订单
需求:
在任意页面上,点击 "我的订单" 将当前用户的订单(包含订单项列表)分页展示出来 技术分析: 分页
多表查询 步骤分析:
1.修改 head.jsp 上"我的订单"的连接
/store/order?method=MyOrder&pageNumber=1
2.在orderservlet中编写 MyOrder
获取pagenumber 设置pagesize 获取当前用户的id
调用service完成分页查询操作:返回pagebean
将pagebean放入request域中,请求转发 order_list.jsp
3.service中操作
创建pagebean
设置总条数
设置当前页数据
4.dao中操作:
获取当前页订单数据
sql:只能查询订单的基本信息,没有订单项
select * from orders where uid = ? order by ordertime desc limit ?,? 执行上面的sql,返回的 List<Order>
遍历orderlist集合,获取到每一个订单,关联查询订单项和商品表,将该订单下的所有信息查询出来,
封装成orderItem,将每一个orderitem放入当前order的订单项列表中
SELECT * FROM orderitem oi,product p WHERE oi.pid = p.pid AND oi.oid = '8727C1B22C214E6D865ECFB3B118E330' 上面的结果用什么封装???
使用maplisthandler封装, 将查询结果的每一条记录封装成map
(key:字段名(和bean属性名一样),value:具体指),将所有的map放入list中返回
遍历map的list,获取每一个订单的详情,使用beanutils进行封装即可 封装orderitem和product对象,最后将orderitem对象放入订单项列表中
[{itemid=xxxx,pname=华为,...},{itemid=uyyyyx,pname=中兴,...}] --------------------------------------------------------------------------------------------------- 案例2-订单详情
需求:
在订单列表页面上点击 "去付款",展示出当前的订单的详情.
步骤分析:
1.修改 "去付款" 连接
/store/order?method=payOrderPage&oid=xxxx
2.在orderservlet编写payOrderPage方法
获取oid
调用service查询单个订单 返回值:order
将order放入request域中,请求转发到order_info.jsp 3.service中操作 4.dao中操作
先查询订单信息
select * from orders where oid = ? 再查询当前订单的订单项
select * from orderitem oi,product p where oi.pid = p.pid and oi.oid=?
使用maplisthandler进行封装
获取每一个订单项详情,封装成orderitem,最后将orderitem添加到订单的订单项列表项即可 ---------------------------------------------------------------------------------------------------
案例3-在线支付
需求:
在详情页面上 输入收货人信息,选择支付的银行,点击确认订单,保存收获人信息,跳转到银行页面,输入用户名(卡号),点击支付,
最后跳转到商城,提示 订单支付成功,(修改订单的状态)
技术分析:
在线支付
/////////////////////
在线支付:
对银行
对第三方 /////////////////////////////////
支付步骤的分析:
1.在订单详情页面上 填写收货人信息, 选择支付银行,点击"确认订单",向商城发送请求
表单提交
收货人信息
支付银行
订单号
路径: /store/order?method=payorder 2.在orderservlet中 编写pay方法
接受收货人信息 订单号
调用service获取订单,
设置收货人信息
更新订单 拼接重定向的字符串 支付成功之后的步骤分析:
编写callback方法
获取第三方发送过来的数据(order_id) 通过id获取订单
修改订单的状态 =1
更新订单 --------------------------------------------------------------------------------------------- 案例4-权限过滤
需求:
访问购物车的时候,需要判断用户是否登录,若没有登录,则提示
技术分析:
过滤器
过滤器编写步骤:
1.编写一个类 PrivilegeFilter
实现filter接口
重写方法(主要doFilter)
2.编写配置文件
filter
filter-mapping
步骤分析:
doFilter方法中的逻辑
从session中获取用户,
判断用户是否为空
若为空:提示"请先登录",请求转发到 /jsp/msg.jsp return ///////////////////////////////////////////////// 商城案例的后台实现 回顾: jquery easyUi 作用:增强用户界面,完成了与服务器数据交互(异步方式)的功能 环境搭建:
3个css文件+2个js文件 easyui.css + images图片 themes/bootstrap/easyui.css + images图片 icon.css+icons图标图片 themes/incos(incos.css) demo.css demo/demo.css js库
jquery.easyui.min.js jquery-easyui-1.4.2/(jquery.easyui.min.js/jquery.min.js) 如果将一个普通的html标签渲染成easyui插件? 如果给这个插件设置属性,事件,方法? 例如:
ps : add('abc');
不加单引号仅限于数值类型
如果涉及到了字符串类型就必须得加单引号,如果不加,它会认为是一个变量 静态方式/css方式
特点: 都在标签体内设置 <div class="easyui-dialog" data-options="属性,事件,方法"></div>
就是在标签体内通过属性class的值 easyui-组件名来渲染 就是标签体内通过属性data-options来设置该插件的属性,事件和方法 动态方式/js方式
特点: 需要写js代码 <div id="d"></div> <script>
// 将html标签渲染成easy组件并设置属性
$("标签体").组件名(
{
属性名1:属性值1,
属性名2:属性值2,
属性名3:属性值3
}
) // 将html标签渲染成easy组件并设置事件
$("标签体").组件名(
{
事件名1:function(){},
事件名2:function(){},
事件名3:function(){},
}
) // 将html标签渲染成easy组件并设置方法
$("标签体").组件名("该组件提供的方法名","方法参数")
方法参数有2种:
1 一个值: 直接写
2 多个值:
{
值名1:值1,
值名2:值2,
值名2:值2
}
</script> datagrid-data1.json
{"total":28,"rows":[
{"productid":"FI-SW-01","productname":"Koi","unitcost":10.00,"status":"P","listprice":36.50,"attr1":"Large","itemid":"EST-1"},
{"productid":"K9-DL-01","productname":"Dalmation","unitcost":12.00,"status":"P","listprice":18.50,"attr1":"Spotted Adult Female","itemid":"EST-10"},
{"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":38.50,"attr1":"Venomless","itemid":"EST-11"},
{"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":26.50,"attr1":"Rattleless","itemid":"EST-12"},
{"productid":"RP-LI-02","productname":"Iguana","unitcost":12.00,"status":"P","listprice":35.50,"attr1":"Green Adult","itemid":"EST-13"},
{"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":158.50,"attr1":"Tailless","itemid":"EST-14"},
{"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":83.50,"attr1":"With tail","itemid":"EST-15"},
{"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":23.50,"attr1":"Adult Female","itemid":"EST-16"},
{"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":89.50,"attr1":"Adult Male","itemid":"EST-17"},
{"productid":"AV-CB-01","productname":"Amazon Parrot","unitcost":92.00,"status":"P","listprice":63.50,"attr1":"Adult Male","itemid":"EST-18"}
]} 这个文件表示要给esayui返回的分页数据 EasyUI底层是用ajax做的,所以给easyUI回传的时候,必须使用json回传,也只能用json回传数据,(ajax回传就是用json传输数据的.)
商城案例的实现 上传原理解释:
下面是请求体:
----------------------7e111423100812 ----->传统的方式
Content-Disposition:form-data:name="username" 整个请求体的内容="request.getInputStream()";
lisi
----------------------7e111423100812 实现步骤:
Content-Disposition:form-data:name="upload";filename="cs.txt" 1:根据分割线将整个请求体的内容分成多个.
Content-Type:text/plain 2:根据filename判断哪些是普通表单项,哪些是上传表单项
aaa 3.普通表单项:name和value
bbbb 4.上传表单项:表单项和表单内容
cccccc io -- >服务器
|
上传: |
浏览器端有3个要求 apache:上传工具包(企业开发) 1 form表单的提交方式必须得是post method=post 2 上传框必须得有name属性 <input type="file" name="upload" /> 3 表单的enctype属性必须得是 multpart/form-data 在form表单里面有一个默认属性enctype,这个默认属性的默认属性值: enctype="application/x-www-form-urlencoded"
url表单 只要玩上传,这个enctype属性值就必须修改了
enctype=multipart/form-data 多部分表单 ps:上传就必须得是多部分表单 什么是url表单?
就是之前一直玩的
所有的内容都在请求体里面,以url形式进行参数的拼接
username=zhangsan&upload=cs.txt&password=123 什么是多部分表单?
所有的内容也都在请求体里面,但是以一部分一部分进行拼接的 -----------------------
一部分
-------------------------
一部分
---------------------------
一部分
............. 服务器的要求:
如果表单是以多部分进行提交的,那么request的3中获取数据的方法全部失效 上传: 浏览器对于上传会要求3件事: 1 上传框要有name属性 name="upload" 2 表单的method必须是post method="post" 3 表单的enctype属性必须得是 multipart/form-data
在表单里面有个entype属性,这个属性有一个默认值: 你写或则不写都会有
enctype="application/x-www-form-urlencoded"(这个属性表示告诉服务器给你上传所有提交的内容都是字符串,没有二进制的形式) url表单 从要玩上传开始,这个属性就必须要做更改,要把这个属性改成:
enctype="multipart/form-data"(该属性以后文件是以二进制形式传输的) 多部分表单 什么是url(普通)表单? 什么是多部分表单? url(普通)表单: 就是之前一直玩的
username=zhangsan&password=123&hobby=eat&hobby=sleep.. 以url形式进行数据拼装传递的表单 多部分表单: ---------------------------------------
一部分 -----------------------------------------
一部分 -------------------------------------------
一部分 不论是url(普通)表单还是多部分表单,数据都在请求体 注意:如果是多部分的表单进行提交,之前使用的request获取数据的3种方式,全部失效 部署应用 需求:
将我们自己的项目部署到linux下 技术分析: 1 linux的环境
安装jdk
安装tomcat
安装mysql
安装redis 2 如何把已完成的项目给linux 项目打包: 后缀名: .war
通过ide工具: 在项目右键-->export-->搜索 war -->选择目的地
特点:在web服务器下的webapps目录下,随着服务器的启动而解压 3 如何把数据库表和数据给linux
数据备份还原:
数据备份 导出本地数据库中的表结构和数据
数据迁移 导入表结构和数据到linux下的数据库
注意:
中文乱码
在连接的url后面追加:
?useUnicode=true&characterEncoding=utf-8
重启tomcat

javaWeb综合案例的更多相关文章

  1. EL&Filter&Listener:EL表达式和JSTL,Servlet规范中的过滤器,Servlet规范中的监听器,观察着设计模式,监听器的使用,综合案例学生管理系统

    EL&Filter&Listener-授课 1 EL表达式和JSTL 1.1 EL表达式 1.1.1 EL表达式介绍 *** EL(Expression Language):表达式语言 ...

  2. JavaScript:综合案例-表单验证

    综合案例:表单验证 开发要求: 要求定义一个雇员信息的增加页面,例如页面名称为"emp_add.htmnl",而后在此页面中要提供有输入表单,此表单定义要求如下: .雇员编号:必须 ...

  3. DOM综合案例、SAX解析、StAX解析、DOM4J解析

    今日大纲 1.DOM技术对xml的增删操作 2.使用DOM技术完成联系人管理 3.SAX和StAX解析 4.DOM4J解析 5.XPATH介绍 1.DOM的增删操作 1.1.DOM的增加操作 /* * ...

  4. JavaEE Tutorials (30) - Duke综合案例研究示例

    30.1Duke综合应用的设计和架构456 30.1.1events工程458 30.1.2entities工程459 30.1.3dukes—payment工程461 30.1.4dukes—res ...

  5. jquery-easyUI第二篇【综合案例】

    基于easyUI开发的一个综合案例模版 <%@ page language="java" pageEncoding="UTF-8"%> <!D ...

  6. CSS3_综合案例

    综合案例 设置元素的 width,还可以利用 left 和 right 为了防止图片太小,background-size: 100% 100%; <!DOCTYPE html> <h ...

  7. Angular路由与多视图综合案例

    Ajax请求存在的几个问题 (1)Ajax请求不会留下History 记录,会导致浏览器后退按钮失效 (2)用户无法直接通过URL进入应用中的指定页面(保存书签.链接分享给朋友) (3)Ajax对SE ...

  8. Winform开发框架中的综合案例Demo

    在实际的系统开发中,我们往往需要一些简单的的案例代码,基于此目的我把Winform开发框架中各种闪光点和不错的功能,有些是我们对功能模块的简单封装,而有些则是引入了一些应用广泛的开源组件进行集成使用, ...

  9. 【原创 Hadoop&Spark 动手实践 13】Spark综合案例:简易电影推荐系统

    [原创 Hadoop&Spark 动手实践 13]Spark综合案例:简易电影推荐系统

随机推荐

  1. [FPGA] Verilog 燃气灶控制器的设计与实现

    燃气灶控制器的设计与实现 一.引述 本次实验所用可编程器件型号为MAXII EPM1270T144C5(其引脚表见本人另一博文:可编程实验板EPM1270T144C5使用说明),通过可编程实验板实现一 ...

  2. docker 常用命令 以及常见问题

    常见命令 windos 在搜索框 输入 windows powershell,打开.然后输入以下命令#查看镜像列表 docker images ls #删除单个镜像 docker rmi image- ...

  3. php yii 查看帮助时会调用具体脚本类的析构函数

    现象 执行 php yii 查看脚本有什么命令的时候,发现会调用我一个类中的析构函数的命令.并且不是一次调用,是3次,截图中有两次,还有一次输出完析构函数所在的类中的命令之后. 分析原因 在析构函数中 ...

  4. centos_mysql 安装脚本

    #!/bin/bash env echo "Download msyql5.7 rpm..." sudo yum install wget wget -i -c http://de ...

  5. 通过 loganalyzer 展示数据库中的系统日志

    目录 通过 loganalyzer 展示数据库中的日志 环境准备 准备服务器: 日志服务器: 数据库服务器: 测试日志服务器和数据库是否连接: websrv服务器端: 通过 loganalyzer 展 ...

  6. IM即时通信软件设计

    参考资料: 架构篇:https://yq.aliyun.com/articles/698301 模型篇:https://yq.aliyun.com/articles/701593 实现篇:https: ...

  7. 05-深入python的set和dict

    一.深入python的set和dict 1.1.dict的abc继承关系 from collections.abc import Mapping,MutableMapping #dict属于mappi ...

  8. Apply Grouping to List View Data 将分组应用于列表视图数据

    This lesson will teach you how to apply grouping to List View data. For this purpose, you will group ...

  9. 剑指offer笔记面试题8----二叉树的下一个节点

    题目:给定一棵二叉树和其中的一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左.右子节点的指针,还有一个指向父节点的指针. 测试用例: 普通二叉树(完全二叉树,不完全二叉树). ...

  10. 由“RangeError: Invalid status code: 0”错误所引发的思考

    最近发现一个基于Node.js平台上的Express框架运行的Web网站经常报这样一个错误: RangeError: Invalid status code: 网站的源码中有专门针对错误处理的中间件, ...