一、后台
1、前台和后台的关系:
后台是由工作人员操作的,通过后台系统对数据库实行增删改查等操作,通过前台系统访问数据库,将数据库中的信息通过前台显示。
2、功能实现:
(1)显示全部商品信息:
home.jsp由其他jsp组成,其中的left.jsp能够访问Servlet,并从Servlet获取数据,而在其访问Servlet时,Servlet需要调用Service层的方法,Service层的方法调用dao层的方法,dao层则可以直接通过sql语句访问数据库。并将查询到的数据返回到Service层,Service层的数据又返回给web层,web层的数据被封装到request域中,通过request请求转发,request域中的数据通过jsp中的EL技术将数据取出,由jsp页面显示出来。
(2)读取分类信息的实现:
在进入list.jsp提供的页面后,点击“添加”按钮,会访问到web层的AdminAddCommodityServlet,向AdminAddCommodityServlet请求数据,最终,在AdminAddCommodityServlet中将数据封装到Request域,并通过请求转发访问add.jsp,将request域中的数据通过EL取出来,通过JSP页面进行显示。
(3)增加商品信息:
在点击List.jsp的添加按钮后,jsp访问AddProduceServlet,AddProduceServlet通过Service层和dao层将数据写入到数据库,然后从AddProduceServlet重定向到AdminCommodityServlet,获数据库中的信息,并将信息通过list.jsp显示出来。
4、删除功能:
List.jsp可以根据点击的删除标记的位置确定要删除的商品的pid,AdminDelCommodityServlet获取到jsp中的此pid,作为参数依次传递给Service层,dao层,最终将数据库中有此pid的商品删除。
5、商品信息的回显(商品信息修改的一部分)
要想修改某一商品的信息,必须先要获取到该商品未修改时的信息。为了实现修改商品所属分类的功能,必须先要从数据库中获取商品所有的分类,并从edit页面中显示出来。为了实现修改其他信息的功能,需要查询商品所有的属性,并通过edit.jsp显示出来。web层的AdminEditServlet里面需要从Service层中获取调用两个方法,分别获取到商品的属性信息和商品的所有类别信息,并封装到request域,通过请求转发将request域中的数据流向edit.jsp,通过EL技术将request域中的数据显示出来。
6、修改商品信息:
通过List.jsp访问AdminEditServlet查询商品的相关信息,并重定向到edit.jsp,在此jsp中,取出request域中的数据进行显示,在edit.jsp中可以对商品的信息进行修改,通过Service层和dao层将数据写到数据库,再重UpdateServlet重定向到AdminCommodityServlet,此Servlet通过Service层和dao层取出数据库中的全部商品信息,封装到request域中,并通过List.jsp显示所有的商品信息。
7、条件查询
表单中填写要查询的商品信息后(有些选项可以为空),将其提交给Servlet,在Servlet内部首先将其封装到VO中,然后封装到map集合中,依次提交到Service层和Dao层,最终从数据库中查询数据。
将查询到的数据封装到商品的javaBean中,通过request对象请求转发到 list.jsp。当然,在servlet中还要调用到查询商品分类的方法,该方法实现表单中分类从数据库的动态获取。
8、商品的分页
在访问Servlet时,获取到以上数据后将这些数据封装到request域中,其中Dao层的作用主要是用上述的两个数作为参数,求出每一页的商品的信息。
二、前台(包括部分后台:admin/home.jsp)
1、注册、表单校验
(1)注册&邮件激活:
注册的实质是封装表单数据,将数据作为参数传递到dao层后,借助于sql语句将数据写入数据库,并根据dao层的方法返回的数据判断是否成功向数据库写入数据,如果成功,借助于MailUtils向用户注册的时候填写的邮箱发送激活邮件。
点击激活邮件实际上是跳转到一个servlet,dao层执行的是update语句,将用户的状态进行更改。
(2)注册表单校验:
为了保证用户名的唯一性,需要先对用户的用户名进行校验,如果此用户名已存在则给出提示信息,如果还没有被使用则当前用户可以正常使用该用户名。当然,表单校验还包括对用户名密码是否为空,是否符合规则等进行校验。这些都属于前台校验,可以减少用户提交数据的次数,减小服务器的压力。
(3)登录
从页面获取用户的用户名和密码,然后根据用户名和密码,从数据库查询是否存在此用户,存在的话,返回用户的信息并封装到session内部,在首页可以从session中获取用户名进行登录用户的显示
(4)自动登录
判断是否选择了自动登录,选择的话就将该用户的用户名和密码存储到cookie中,在cookie过期之前可以自动登录(遍历cookie获取用户名和密码),是通过过滤器来实现的。
2、最新和热门商品的展示
最新和热门商品的区别仅仅在于查询的商品的字段不同,一个根据时间字段,一个根据商品是否热门的字段。为了能够直接翻个我拿到index.jsp,需要先定义一个default.jsp,然后重定向到servlet,如果直接访问index.jsp的话是不经过servlet的,页面也不能从数据库中动态获取到数据。
3、获取商品分类信息
通过三层架构获取到商品的分类信息后返回到servlet中,servlet将数据封装为json格式,以便jsp在发起ajax请求后能够获取到格式为json的数据。在jsp中书写函数只要jsp加载完毕就会发起ajax请求获取商品的分类数据,这样的话不管head.jsp在哪一个页面中,都能够通过函数发起请求后获取到数据,否则,在页面跳转后每次都要书写专门的servlet获取数据。
4、存储商品分类信息
(1)导包
(2)先从缓存中查询,如果缓存中有相应的数据,就不再从数据库中查询,因为从缓存中获取数据速度更快,但是如果缓存中没有,就需要从数据库中获取,然后将查询的数据放入缓存
5、商品分页
(1)第1次在头部点击商品分类的时候,需要将商品的ID传递到web层,当前页并没有传递到web层,当前页为空的话,在web层默认为1,也就是说第1次点击商品分类的时候,进入相应的商品分类页面后,是从第1页开始显示的
web层的处理:
从前端页面获取到商品分类的ID,当前页默认为1,每一页显示的数量为定值,将这三个参数传递到service层
service层:
从dao层获取商品的总数量,通过总数量和每一页能够显示的商品数量,计算出商品展示的总页数
通过商品ID、每一个页面的起始索引、每一个页面显示的数量,获取这一个页面显示的商品的信息,也需要dao层的一个方法来实现
将当前页面、每一个页面显示的数量,总条数,总页数和当前页面显示的商品信息,进行封装,返回给web层
(2)当点击分页条的时候,如果是第1页、当前页或者是最后一页,则保持不变,不会向服务器发起新的请求
当点击前一页的时候,当前页减一;同理,点击下一页的时候,当前页加一,需要向服务器发起新的请求
6、显示商品详细信息
在商品页面,点击商品图片或商品名称之后,就请求服务器查询该商品的详细信息,要向web层传递商品ID,通过ID查询到商品的详细信息后,在web层将商品的数据封装到request域,然后请求转发到页面,将商品的信息展示在商品的详情页面。
7、浏览记录
在点击商品的图片或者名称的时候,需要访问servlet,在里面创建cookie,并将商品的ID存放到cookie里面。如果cookie中已经存在了该商品的ID,那么就将该商品从集合中移除,并将该商品添加至集合的头部。如果cookie中不存在商品的iD,直接将该商品的ID放到集合的首部。
在商品的详情页面,点击返回首页的时候,会访问相应的servlet,会携带参数pid和商品所在的页面,保证返回的页面和初始的页面是同一个。在该servlet内部,将cookie转化为数组之后,对数组进行遍历,通过商品的ID,获取每一个商品的详细信息,将查询到的商品信息存放到list集合中,最后,请求转发到商品展示页面
8、servlet的抽取
将servlet按照模块分类,一个模块(servlet)中有多个功能(方法),这里和springmvc的控制器有相似的功能
抽取之后同一个servlet内部有多个方法,在调用的时候根据方法的名字来区别同一个servlet中的不同功能
9、购物车
(1)对象之间的关系:
购物车的一条信息称为cartitem,在这一条信息里面封装的有product对象,多个cartitem对象构成了cart对象
定义一个HashMap存储购物项,哈希表的键为商品的ID,值是该商品的购买信息
(2)向购物车添加商品
从表单获取购买的该商品的ID(通过ID获取该商品的全部信息)和该商品购买的数量,并根据单价和购买商品的数量计算出此次购买的商品小计,将以上信息封装为CartItem对象
从session中获取购物车,如果没有获取到就新建一个Cart对象,否则,从购物车中获取商品的购物项并判断新的提交的商品的ID是否在session中已经存在,如果已经存在,就都商品的购买数量和小计重新计算以后封装为Cartitem对象。如果购物车不为空,但是不存在该商品,就将其放入到HashMap集合中,并对小计进行修改
计算购物车的总金额,封装到cart里面,存储在session中
(3)移除一种商品
根据session的键获取购物车的session,并从购物车中获取相应ID的商品,修改总价后从集合中删除该商品的信息
(4)清空购物车
移除键为cart的session
(5)总结
虽然重定向能够携带数据,但是并不是携带不携带数据都能够使用它,因为,请求转发后地址栏的信息没有改变,如果重复提交会造成数据的错误,因此,此时可以采用重定向的方式
10、订单
(1)提交订单
订单、订单项、商品之间的关系:
商品添加订单项的ID、商品的数量、小计、订单项属于哪一个订单后就成为了订单项,多个(也可以是一个)订单项添加用户信息、地址等信息后就成为了一个订单。
web层:
订单提交后数据库就会存在订单的信息,需要在web层对订单进行封装,如果没有登录的话是不能提交订单的,会重定向到登录界面提示用户进行登录
订单项的信息可以从购物车项中获取,最终,将订单项添加到订单的订单项集合中即可
service层:
因为订单项和订单是两个不同的表,因此,需要分开来讲数据写入到不同的表中(需要两个方法处理),传递的参数都可以是order,因为,从order中可以获得orderItem。在service要进行事务处理,保证两个操作的一致性
dao层:
通过sql语句将订单信息写入到数据库
(2)网上支付
在这里主要是要学会调用第三方的支付接口,并在支付成功的时候更改订单的状态
(3)我的订单
先查询该用户的所有订单的集合(根据用户的uid查询该用户的所有订单信息),再对每一个订单下的订单项进行遍历(根据订单号查询)
因为查询的数据涉及到多张表,需要采用 MapListHandler()对查询到的数据进行封装(本质是将map封装到list集合中),接收的时候可以用List<Map<String, Object>>,然后遍历数据,将数据再次封装到orderitem中
对订单进行展示的时候,要用到foreach的嵌套,外层展示的是每一个订单,内层负责展示每一个订单的订单项。
11、权限控制
用户在没有登录的情况下是无法查看订单的,因为没有用户的信息是无法获取到该用户的订单的,因此,需要用到权限控制。这里是通过虚拟路径对访问的页面进行权限的控制。需要配置过滤器,在过滤器内部判断session中是否有用户的信息,有的话已经登录就放行,没有的话就重定向到登录界面。
12、注销
注销的实质是清除自动登录的时候创建的cookie和登录成功后存储用户信息的session
13、文件上传
需要导入两个与文件上传相关的包。
遍历request的每一个文件项,并对每一个文件项对是否是一个普通的表单项进行判断。
14、ajax获取商品分类
在add页面加载完毕的时候获取到商品的分类数据,通过service层和dao层获取到商品的分类数据,在web层将商品的分类数据转换为json格式,前端通过ajax获取到json字符串,并获取到商品的分类数据。最后通过拼接html文件将商品的分类信息显示在前端页面。
15、添加商品
商品的信息既包括文字信息又包括图片信息,获取表单提交的文字信息的同时又要获取图片,将图片的路径和商品的其他信息封装成为一个商品对象,同时,要通过文件的上传功能将图片上传到服务器,而其他商品的数据是存储在数据库中的。
16、订单详情
点击查看想请的按钮后,会掉用函数,在该函数内部发起ajax请求,web层返回订单详情的json字符串,jsp页面遍历json格式的字符串,取出里面的数据并进行html代码的拼接,最后进行页面的显示。