淘淘商城第112讲——展示订单确认页面以及用户身份认证

我们上一讲一起搭建了订单系统的服务层工程和表现层工程。这一讲,我们就要实现订单确认页面展示这个功能了。

展示订单确认页面

在淘淘商城中,用户未登录即可添加商品到购物车,如下图所示。
在这里插入图片描述
这儿我们是参考的之前的京东,之前的京东在用户没有登录的情况下他就可以使用购物车了,但是当用户要真正去结算的时候,一定是要求他登录的,也就是说由购物车商品列表展示页面直接跳转到用户登录页面要求他去登录。

在淘淘商城中,我们也是这样做的,当用户点击购物车商品列表展示页面中的去结算之后,如果当前用户还没登录,那么必须要求他先登录。也就是说在展示订单确认页面之前,需要对用户身份进行认证,要求用户必须登录。

我们找到购物车商品列表展示页面(即cart.jsp),打开它之后找到去结算超链接,对其进行如下处理。
在这里插入图片描述
由于在购物车商品列表展示页面中点击去结算之后要跳转到订单确认页面,因此我们就要先把淘淘商城订单系统中所需的静态文件添加到taotao-order-web工程当中。你可能会问了,这些静态文件应该从哪儿获取到呢?大可以从我下面给出的百度网盘链接地址中进行下载。

链接:https://pan.baidu.com/s/1Mll2gCLhEvCh0GZ967L2Iw,提取码:ky43

下载下来之后解压即可,而且记得要将css、js、images等目录放到webapp目录下,将jsp目录放到WEB-INF目录下,如下图所示。
在这里插入图片描述
order-cart.jsp页面就是我们要访问的订单确认页面,这个页面中的cartList代表的就是Controller返回的购物车商品列表,而且一定要注意cart的属性要写正确哟😘
在这里插入图片描述
下面我们按照如下业务逻辑在taotao-order-web工程中编写一个Controller,例如OrderController。
在这里插入图片描述
该OrderController来响应购物车商品列表请求访问订单确认页面的请求,如下图所示。
在这里插入图片描述
为了方便大家复制,现将该OrderController类的代码给出,如下所示。

package com.taotao.order.controller;import java.util.ArrayList;
import java.util.List;import javax.servlet.http.HttpServletRequest;import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.CookieUtils;
import com.taotao.common.utils.JsonUtils;
import com.taotao.pojo.TbItem;
import com.taotao.pojo.TbUser;
import com.taotao.sso.service.UserLoginService;/*** 订单处理的Controller* @author liayun**/
@Controller
public class OrderController {@Value("${TT_TOKEN_KEY}")private String TT_TOKEN_KEY;@Value("${COOKIE_TT_CART}")private String COOKIE_TT_CART;@Autowiredprivate UserLoginService loginService;/*** url:/order/order-cart.html* 参数:没有参数,但是需要用户的id,用户的id是从Cookie中获取token并调用SSO的服务获取到的* 返回值:逻辑视图(订单的确认页面)*/@RequestMapping("/order/order-cart")public String showOrder(HttpServletRequest request) {// 1. 从Cookie中获取用户的tokenString token = CookieUtils.getCookieValue(request, TT_TOKEN_KEY);if (StringUtils.isNotBlank(token)) {// 2. 调用SSO的服务获取用户的信息TaotaoResult result = loginService.getUserByToken(token);if (result.getStatus() == 200) {// 3. 获取用户的信息之后,它有可能存在,也有可能不存在,但必须是用户登录了才展示我们的数据// 4. 展示用户的送货地址,它是根据用户的id查询该用户的配送地址,这里暂时使用静态数据// 5. 展示支付方式,从数据库中获取支付的方式,这里暂时使用静态数据// 6. 调用购物车服务从redis数据库中获取购物车中的商品列表TbUser user = (TbUser) result.getData();// 注意,我这儿是直接从Cookie中获取购物车中商品列表数据的List<TbItem> cartList = getCartList(request);// 7. 将购物车中的商品列表传递到页面中(通过Model来进行传递)request.setAttribute("cartList", cartList);}}return "order-cart";}// 从Cookie中取出购物车中的商品列表private List<TbItem> getCartList(HttpServletRequest request) {// 使用CookUtils工具类取购物车列表String json = CookieUtils.getCookieValue(request, COOKIE_TT_CART, true);// 判断Cookie中是否有值if (StringUtils.isBlank(json)) {// 如果没有值那么就返回一个空的Listreturn new ArrayList<TbItem>();}// 如果有值,那么把json转换成List对象List<TbItem> list = JsonUtils.jsonToList(json, TbItem.class);return list;}}

可以看到,我们在以上Controller类的代码中用到了两个常量,常量我们要定义在配置文件当中,如下图所示。
在这里插入图片描述
而且我们还可以看到该Controller类的showOrder方法中通过token获取了用户的信息,显然这是调用到了SSO系统的服务,因此我们还要在taotao-order-web工程中添加对taotao-sso-interface工程的依赖,如下图所示。
在这里插入图片描述
光依赖taotao-sso-interface工程还不行,我们还得在springmvc.xml配置文件中引用taotao-sso-service工程发布的Dubbo服务。
在这里插入图片描述
下面我们就要来进行测试了,先将taotao-order聚合工程安装到本地maven仓库中,然后启动taotao-order-web工程,启动成功后,我们登录到淘淘商城中,接着点击去购物车结算跳转到购物车商品列表展示页面,紧接着点击去结算,这时便能看到订单确认页面了,如下图所示。
在这里插入图片描述

用户身份认证

上面我也讲过,之前的京东在用户没有登录的情况下他就可以使用购物车了,但是当用户要真正去结算的时候,一定是要求他登录的,也就是说由购物车商品列表展示页面直接跳转到用户登录页面要求他去登录。这显然用到了拦截器的功能,本小节我们便一起来编写一个拦截器,实现这样一个效果,即在展示订单确认页面之前对用户身份进行认证,以要求用户必须登录。

我们在taotao-order-web工程的src/main/java目录下新建一个com.taotao.order.interceptor包并在该包下新建一个用户身份认证的拦截器,例如LoginInterceptor(拦截器是需要实现HandlerInterceptor接口的),要编写出这样一个拦截器并不难,你只须按照以下业务逻辑按部就班编写即可。
在这里插入图片描述
该拦截器的代码如下所示:

package com.taotao.order.interceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.CookieUtils;
import com.taotao.sso.service.UserLoginService;/*** 用户身份认证的拦截器* @author liayun**/
public class LoginInterceptor implements HandlerInterceptor {@Value("${TT_TOKEN_KEY}")private String TT_TOKEN_KEY;@Value("${SSO_URL}")private String SSO_URL;@Autowiredprivate UserLoginService loginService;/** 在DispatcherServlet拦截之后,在进入目标方法(其实就是Controller中的方法,例如showOrder)之前执行* * 应用场景:做预处理的相关工作,例如身份认证*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 用户的身份认证在此验证// 1. 取Cookie中的tokenString token = CookieUtils.getCookieValue(request, TT_TOKEN_KEY);// 2. 判断token是否存在if (StringUtils.isEmpty(token)) {// 3. 如果token不存在,那么说明没登录,需要重定向到用户登录页面response.sendRedirect(SSO_URL + "/page/login");return false;}// 4. 如果token存在,那么调用SSO的服务查询用户的信息,看是否用户已经过期TaotaoResult result = loginService.getUserByToken(token);if (result.getStatus() != 200) {// 5. 若用户已经过期,则重定向到用户登录页面response.sendRedirect(SSO_URL + "/page/login");return false;}// 6. 若用户没过期,说明用户已经登录了,则放行return true;}/** 在进入目标方法(其实就是Controller中的方法,例如showOrder)之后,在返回ModelAndView之前执行* * 应用场景:公用变量的一些设置*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception {// TODO Auto-generated method stub}/** 在返回ModelAndView之后,渲染到页面之前执行* * 应用场景:异常处理,清理工作(例如日志的清理)*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {// TODO Auto-generated method stub}}

可以看到,我们在以上拦截器中用到了一个常量,常量我们要定义在配置文件当中,如下图所示。
在这里插入图片描述
编写完以上拦截器之后,我们还得告诉Spring容器我们写了这个拦截器,于是需要在springmvc.xml文件中配置该拦截器,如下图所示。
在这里插入图片描述
下面我们就要来进行测试了,现在只须重启taotao-order-web工程即可,启动成功后,进入到淘淘商城首页,先不登录,直接点击去购物车结算跳转到购物车商品列表展示页面,然后再点击去结算,这时会看到页面已经跳转到了用户登录页面,这说明我们的拦截器起作用了。

此时,当我们登录之后,会发现直接跳转到了淘淘商城首页。哎呀!怎么不是跳转到订单确认页面中去呢?这是不是就有问题啊!而且这还只是其中的一个问题。那第二个问题是什么呢?调用SSO系统的服务时调用了两次,第一次是在拦截器中调用了一次,第二次是在Controller中获取用户信息时又调用了一次。

那么如何解决这两个问题呢?下面这一小节我就来告诉大伙。

实现拦截器后存在的问题

上面我就说了,使用拦截器进行用户身份认证时,出现了两个问题,它们分别是:

  • 第一个问题:调用SSO系统的服务时调用了两次,第一次是在拦截器中调用了一次,第二次是在Controller中获取用户信息时又调用了一次
  • 第二个问题:用户登录成功之后跳转到了淘淘商城首页,但是应当跳转到订单确认页面才对

接下来我就要一一解决这两个问题了。

解决调用SSO服务两次的问题

实际上,我们只须在拦截器中调用一次SSO系统的服务便可以了,调用之后,将用户信息数据存放在request域中,等进入到目标方法中之后,它就可以直接通过request域来获取用户信息了。

因此,咱们的拦截器的代码就要修改成下面这个样子了。
在这里插入图片描述
相应地,OrderController类中的showOrder方法就要修改成下面这个样子了。
在这里插入图片描述
如此一来,第一个问题便可解决掉。

解决登录之后跳转到首页的问题

用户未登录时,他是不能直接访问订单确认页面的,如果他偏要逆天而行,那么就得要求他去登录,只有他真正登录之后,才能跳转到订单确认页面,而且还要注意的是登录之后不应该再回到商城首页了!

用户访问订单确认页面的流程图如下所示。
在这里插入图片描述
知道了用户访问订单确认页面的流程之后,咱们就知道该如何解决登录之后跳转到首页这个问题了。

解决办法就是在拦截器中加上访问订单确认页面的URL,然后在SSO单点登录系统中进行获取,获取之后传递到用户登录页面,接着再在用户登录的页面中取得订单确认页面访问的URL。若一旦用户登录成功,则通过JS直接跳转到订单确认页面。
在这里插入图片描述
参照上图,我们即可快速解决登录之后跳转到首页这个问题。

首先,修改一下咱们的拦截器,即在拦截器中加上访问订单确认页面的URL。
在这里插入图片描述
然后,我们到taotao-sso-web工程的PageController类中简单做下修改,如下图所示,我们在showPage方法中添加了两个参数,一个是回调地址url,另一个是用来给jsp页面添加属性的Model,回调地址url也不是凭空来的,它是由拦截器重定向时就指定好的。
在这里插入图片描述
接着,在用户登录页面(即login.jsp页面)中判断用户登录是否成功,如下图所示,可以看到js代码首先会去尝试获取从Controller中传递过来的回调地址,如果取到了回调地址,那么登录成功后会跳转到回调地址,如果没有取到回调地址,那么登录成功后直接访问的便是淘淘商城首页。
在这里插入图片描述
如此一来,第二个问题又被解决掉了。

两个问题都被解决掉之后,接下来我们就要来进行测试了。首先重启taotao-sso-web和taotao-order-web这两工程,它俩都重启成功之后,我们就可以测试了。

如果你是刚登录的话,那么Cookie中已经有了你的登录信息而且token还没过期,要想达到用户未登录的效果,有两种方法,一种方法是删除Cookie中的TT_TOKEN,如下图所示,另一种方法就是等,等30分钟,30分钟后token就会过期。很显然,我们删除Cookie中的TT_TOKEN比较靠谱。
在这里插入图片描述
删除了Cookie中的token或token过期后,我们还是在购物车商品列表展示页面中去点击去结算,这时依然还是会让我们进行登录,登录成功后会提示登录成功的消息,接着点击确定按钮,这时我们看到的便是下图所示的订单确认页面,而不再是淘淘商城首页了。
在这里插入图片描述
但是当前这个页面头部还是显示的是未登录状态,我们参考单点登录系统中的代码,在taotao-order-web工程的js目录下找到base-v1.js这个文件,打开它并修改最上面的两个方法,修改后的代码如下所示,这样在订单确认页面中便可以点击登录注册超链接跳转到相应页面中了。
在这里插入图片描述
紧接着我们再修改下js目录中的taotao.js文件,其实这个文件我们只需要将端口修改为8088就可以了。
在这里插入图片描述
最后我们重启taotao-order-web工程,重启成功后,刷新订单确认页面,这时我们便可以看到头部有用户信息了。
在这里插入图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部