淘淘商城第十一天


1   课程计划

昨天:

单点登录系统

1、创建工程

2、可以被多种客户端调用,门户系统、手机app、微信商城。

3、实现接口

a)        数据校验接口

b)       注册接口

c)        登录接口

d)       根据token查询用户接口

e)        安全退出(作业)

 

今天的内容:

1、登录、注册功能的实现。

2、门户系统整合登录、注册功能

3、当用户下订单时需要用户登录,使用拦截器实现用户登录。登录成功后跳转到用户要访问的页面。

4、购物车的实现

a)        添加商品

b)       删除商品

c)        修改商品数量

 

2   注册功能的实现

登录和注册的功能都放到单点登录系统中完成,供其他系统调用。

 

2.1  向sso系统中添加页面

需要对静态资源做映射。需要修改springmvc.xml

 

 

2.2  注册功能实现

1、进行注册之前先进行数据的有效性验证。

a)        用户名不能重复

b)       确认密码和密码文本框的内容要一致。

c)        用户名、密码不能为空。

d)       手机不能为空 并且不能重复。

2、校验完成后注册。可以调用sso系统的注册接口完成注册。

 

2.2.1   打开注册页面

 

@Controller

@RequestMapping("/page")

public class PageController {

 

     @RequestMapping("/register")

     public String showRegister() {

          return"register";

     }

}

 

 

2.2.2   数据校验

 

2.2.3   提交注册

 

3   登录功能的实现

3.1.1   打开登录页面

使用一个Controller跳转到登录页面。

@RequestMapping("/login")

     public String showLogin() {

          return "login";

     }

 

3.1.2   数据校验

校验用户名密码必须输入。

3.1.3   用户登录

用户点击登录按钮把用户名和密码表单提交给登录接口,接收返回结果判断是否登录成功。

 

3.1.4   登录页面回调url

回调url应该是通过一个参数传递给显示登录页面的Controller。参数名为:redirect

需要把回调的url传递给jsp页面。当登录成功后,js的逻辑中判断是否有回调的rul,如果有就跳转到此url,如果没有就跳转到商城首页。

 

4   使用拦截器实现用户登录

4.1  门户系统整合sso

在门户系统点击登录连接跳转到登录页面。登录成功后,跳转到门户系统的首页,在门户系统中需要从cookie中 把token取出来。所以必须在登录成功后把token写入cookie。并且cookie的值必须在系统之间能共享。

 

4.1.1   Cookie共享:

1、Domain:必须是相同的。

例如有多个域名:

www.taotao.com

Sso.taotao.com

Search.taotao.com

需要设置domain为:.taotao.com

2、设置path:/

 

4.1.2   工具类

 

如果是localhost不要设置domain。直接设置path就可以了。

工具类可以放到taotao-common中。

 

4.1.3   在登录接口中添加写cookie的逻辑

4.1.4   首页取cookie信息

从cookie中取token,在页面中根据token取用户信息,调用sso系统的服务来完成。需要使用jsonp调用。

 

 

登录成功:

 

4.2  模拟拦截url

需求:当访问商品详情页面时强制用户登录。(当有订单系统后就改为订单系统的url。)

 

4.2.1   创建拦截器

1、需要实现HandlerInterceptor接口。

2、实现拦截逻辑

3、需要在springmvc.xml中配置。

 

4.2.2   用户登录Service

功能:根据token换取用户信息,需要调用sso系统的服务。返回TbUser对象。如果没有就返回null。

 

@Service

public class UserServiceImpl implements UserService {

    

     @Value("${SSO_BASE_URL}")

     private String SSO_BASE_URL;

     @Value("${SSO_USER_TOKEN}")

     private String SSO_USER_TOKEN;

    

     @Override

     public TbUser getUserByToken(String token) {

          try {

               //调用sso系统的服务,根据token取用户信息

               String json = HttpClientUtil.doGet(SSO_BASE_URL + SSO_USER_TOKEN + token);

               //json转换成TaotaoREsult

               TaotaoResult result = TaotaoResult.formatToPojo(json, TbUser.class);

               if (result.getStatus() == 200) {

                    TbUser user = (TbUser) result.getData();

                    return user;

               }

              

          } catch (Exception e) {

               e.printStackTrace();

          }

          return null;

     }

 

}

 

4.2.3   拦截器实现

public class LoginInterceptor implements HandlerInterceptor {

    

     @Autowired

     private UserServiceImpl userService;

 

     @Override

     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

               throws Exception {

          //在Handler执行之前处理

          //判断用户是否登录

          //从cookie中取token

          String token = CookieUtils.getCookieValue(request, "TT_TOKEN");

          //根据token换取用户信息,调用sso系统的接口。

          TbUser user = userService.getUserByToken(token);

          //取不到用户信息

          if (null == user) {

               //跳转到登录页面,把用户请求的url作为参数传递给登录页面。

               response.sendRedirect(userService.SSO_BASE_URL + userService.SSO_PAGE_LOGIN

                         + "?redirect=" + request.getRequestURL());

               //返回false

               return false;

          }

          //取到用户信息,放行

          //返回值决定handler是否执行。true:执行,false:不执行。

          return true;

     }

 

     @Override

     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

               ModelAndView modelAndView) throws Exception {

          // handler执行之后,返回ModelAndView之前

 

     }

 

     @Override

     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

               throws Exception {

          // 返回ModelAndView之后。

          //响应用户之后。

 

     }

 

}

 

4.2.4   Springmvc.xml

<!-- 拦截器配置 -->

     <mvc:interceptors>

          <mvc:interceptor>

               <!-- 拦截订单类请求 -->

               <mvc:mapping path="/item/**"/>

               <bean class="com.taotao.portal.interceptor.LoginInterceptor"/>

          </mvc:interceptor>

     </mvc:interceptors>

 

5   购物车的实现

5.1  分析


淘淘:购物车在用户不登陆的情况下也可以使用购物车。需要把购物车的商品信息写入cookie中。所有对购物车的操作都是操作cookie。有效 的降低数据库的压力。

缺点:换一台电脑后购物车的商品不能同步。

 

实现的工程:taotao-protal中实现购物车功能。只需要调用商品信息的服务,除此之外不需要和其他系统交互。

 

5.2  添加购物车商品

5.2.1   流程分析:

在商品详情页面点击“加入购物车”按钮提交一个请求吧商品id传递给Controller,Controller接收id,Controller调用Service根据商品id查询商品基本信息。把商品写入cookie中,加入cookie之前先从cookie中把购物车的商品取出来判断当前购物车商品列表中是否有此商品,如果有数量加一,如果没有添加一个商品,数量为1。展示给用户购物车列表。

 

 

5.2.2   Service层实现

功能:接收一个商品id,数量(默认为1),根据商品id查询商品信息。调用taotao-rest的服务。把商品添加到购物车,先把购物车商品列表取出来,判断列表中是否有此商品,如果有就增加数量就可以了。如果没有把此商品添加到商品列表。返回添加成功Taotaoresult。

 

 

创建购物车商品POJO:

public class CartItem {

 

     private long id;

     private String title;

     private Integer num;

     private long price;

     private String image;

}

 

 

@Service

public class CartServiceImpl implements CartService{

    

     @Value("${REST_BASE_URL}")

     private String REST_BASE_URL;

     @Value("${ITME_INFO_URL}")

     private String ITME_INFO_URL;

    

 

     /**

      * 添加购物车商品

      * <p>Title: addCartItem</p>

      * <p>Description: </p>

      * @param itemId

      * @param num

      * @return

      * @see com.taotao.portal.service.CartService#addCartItem(long, int)

      */

     @Override

     public TaotaoResult addCartItem(long itemId, int num,

               HttpServletRequest request, HttpServletResponse response) {

          //取商品信息

          CartItem cartItem = null;

          //取购物车商品列表

          List<CartItem> itemList = getCartItemList(request);

          //判断购物车商品列表中是否存在此商品

          for (CartItem cItem : itemList) {

               //如果存在此商品

               if (cItem.getId() == itemId) {

                    //增加商品数量

                    cItem.setNum(cItem.getNum() + num);

                    cartItem = cItem;

                    break;

               }

          }

          if (cartItem == null) {

               cartItem = new CartItem();

               //根据商品id查询商品基本信息。

               String json = HttpClientUtil.doGet(REST_BASE_URL + ITME_INFO_URL + itemId);

               //json转换成java对象

               TaotaoResult taotaoResult = TaotaoResult.formatToPojo(json, TbItem.class);

               if (taotaoResult.getStatus() == 200) {

                    TbItem item = (TbItem) taotaoResult.getData();

                    cartItem.setId(item.getId());

                    cartItem.setTitle(item.getTitle());

                    cartItem.setImage(item.getImage() == null ? "":item.getImage().split(",")[0]);

                    cartItem.setNum(num);

                    cartItem.setPrice(item.getPrice());

               }

               //添加到购物车列表

               itemList.add(cartItem);

          }

          //把购物车列表写入cookie

          CookieUtils.setCookie(request, response, "TT_CART", JsonUtils.objectToJson(itemList), true);

         

          return TaotaoResult.ok();

     }

     /**

      * 从cookie中取商品列表

      * <p>Title: getCartItemList</p>

      * <p>Description: </p>

      * @return

      */

     private List<CartItem> getCartItemList(HttpServletRequest request) {

          //从cookie中取商品列表

          String cartJson = CookieUtils.getCookieValue(request, "TT_CART", true);

          if (cartJson == null) {

               return new ArrayList<>();

          }

          //json转换成商品列表

          try {

               List<CartItem> list = JsonUtils.jsonToList(cartJson, CartItem.class);

               return list;

          } catch (Exception e) {

               e.printStackTrace();

          }

          return new ArrayList<>();

     }

 

}

 

5.2.3   Controller

接收商品的id和商品的数量,商品数量如果为空默认为1.调用Service向购物车添加商品。

展示添加成功页面。

请求的url:http://localhost:8082/cart/add/144141542125084.html

 

@Controller

@RequestMapping("/cart")

public class CartController {

 

     @Autowired

     private CartService cartService;

    

     @RequestMapping("/add/{itemId}")

     public String addCartItem(@PathVariable Long itemId,

               @RequestParam(defaultValue="1")Integer num,

               HttpServletRequest request, HttpServletResponse response) {

          TaotaoResult result = cartService.addCartItem(itemId, num, request, response);

          return "cartSuccess";

     }

    

}

 

5.3  展示购物车列表

需要展示购物车页面,没有参数,只需要从cookie中把商品列表取出来,展示到页面即可。

 

5.3.1   Service

从cookie中把购物车列表取出来,没有参数,返回购物车中的商品列表。

@Override

     public List<CartItem> getCartItemList(HttpServletRequest request, HttpServletResponse response) {

          List<CartItem> itemList = getCartItemList(request);

          return itemList;

     }

 

5.3.2   Controller

调用Service取购物车商品列表,把购物车商品传递给jsp。在购物车页面展示商品列表。

请求的url:http://localhost:8082/cart/cart.html

返回jsp页面:cart.jsp

@RequestMapping("/cart")

     public String showCart(HttpServletRequest request, HttpServletResponse response, Model model) {

          List<CartItem> list = cartService.getCartItemList(request, response);

          model.addAttribute("cartList", list);

          return "cart";

     }

 

5.4  购物车商品数量修改

作业:直接修改购物车数量。

响应修改商品数量的事件:

 

5.5  删除购物车商品

在购物车页面中点击删除连接,接收要删除的商品id,从cookie中把商品找到删除,重新写入cookie,重新展示购物车页面。

 

5.5.1   Service

/**

      * 删除购物车商品

      * <p>Title: deleteCartItem</p>

      * <p>Description: </p>

      * @param itemId

      * @return

      * @see com.taotao.portal.service.CartService#deleteCartItem(long)

      */

     @Override

     public TaotaoResult deleteCartItem(long itemId, HttpServletRequest request, HttpServletResponse response) {

          //从cookie中取购物车商品列表

          List<CartItem> itemList = getCartItemList(request);

          //从列表中找到此商品

          for (CartItem cartItem : itemList) {

               if (cartItem.getId() == itemId) {

                    itemList.remove(cartItem);

                    break;

               }

                     

          }

          //把购物车列表重新写入cookie

          CookieUtils.setCookie(request, response, "TT_CART", JsonUtils.objectToJson(itemList), true);

         

          return TaotaoResult.ok();

     }

 

5.5.2   Controller

接收商品id,调用Service删除购物车商品,返回购物车页面。

请求的url:/cart/delete/${cart.id}.html

@RequestMapping("/delete/{itemId}")

     public String deleteCartItem(@PathVariable Long itemId, HttpServletRequest request, HttpServletResponse response) {

          cartService.deleteCartItem(itemId, request, response);

          return"redirect:/cart/cart.html";

     }

 

6   购物车存在的问题

1、更换设备购物车商品不能同步

a)        不能把购物车商品保存到数据库

b)       要求用户登录才能同步信息

c)        可以把购物车信息保存到redis中,key就是用户,value就是购物车列表

d)       购物车商品合并的问题。

2、提交订单后购物车商品需要清空。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值