高并发解决方案,tomcat负载均衡,大型电商项目实战,数据库架构设计,Solr集群与应用,分布式实战


1.展示订单确认页面
1.1.1. 功能分析
1、在购物车页面点击“去结算”按钮跳转到订单确认页面。

2、请求的url:/order/order-cart

3、参数:没有参数。

4、购物车商品数据从cookie中取出来的。可以在订单系统中取到cookie中的购物车数据。

5、配送地址列表,需要用户登录。需要根据用户id查询收货地址列表。静态数据。

6、支付方式。静态数据。

6、返回值:逻辑视图String,展示订单确认页面。

1.1.2. Interface层
package cn.e3mall.order.service;

import cn.e3mall.common.utils.E3Result;
import cn.e3mall.order.pojo.OrderInfo;

public interface OrderService {
//创建订单
E3Result createOrder(OrderInfo orderInfo);
}
1.1.3. Service层
package cn.e3mall.order.service.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import cn.e3mall.common.jedis.JedisClient;
import cn.e3mall.common.utils.E3Result;
import cn.e3mall.mapper.TbOrderItemMapper;
import cn.e3mall.mapper.TbOrderMapper;
import cn.e3mall.mapper.TbOrderShippingMapper;
import cn.e3mall.order.pojo.OrderInfo;
import cn.e3mall.order.service.OrderService;
import cn.e3mall.pojo.TbOrderItem;
import cn.e3mall.pojo.TbOrderShipping;
/**
* 订单处理服务
* @author cxx
*
*/
@Service
public class OrderServiceImpl implements OrderService {

@Autowired
private TbOrderMapper orderMapper;
@Autowired
private TbOrderItemMapper orderItemMapper;
@Autowired
private TbOrderShippingMapper orderShippingMapper;
@Autowired
private JedisClient jedisClient;

@Value("${ORDER_ID_GEN_KEY}")
private String ORDER_ID_GEN_KEY;
@Value("${ORDER_ID_START}")
private String ORDER_ID_START;
@Value("${ORDER_DETAIL_ID_GEN_KEY}")
private String ORDER_DETAIL_ID_GEN_KEY;

@Override
public E3Result createOrder(OrderInfo orderInfo) {
//生成订单号。使用redis的incr生成。
if (!jedisClient.exists(ORDER_ID_GEN_KEY)) {
jedisClient.set(ORDER_ID_GEN_KEY, ORDER_ID_START);
}
String orderId = jedisClient.incr(ORDER_ID_GEN_KEY).toString();
//补全orderInfo的属性
orderInfo.setOrderId(orderId);
//1、未付款,2、已付款,3、未发货,4、已发货,5、交易成功,6、交易关闭
orderInfo.setStatus(1);
orderInfo.setCreateTime(new Date());
orderInfo.setUpdateTime(new Date());
//插入订单表
orderMapper.insert(orderInfo);
//向订单明细表插入数据。
List<TbOrderItem> orderItems = orderInfo.getOrderItems();
for (TbOrderItem tbOrderItem : orderItems) {
//生成明细id
String odId = jedisClient.incr(ORDER_DETAIL_ID_GEN_KEY).toString();
//补全pojo的属性
tbOrderItem.setId(odId);
tbOrderItem.setOrderId(orderId);
//向明细表插入数据
orderItemMapper.insert(tbOrderItem);
}
//向订单物流表插入数据
TbOrderShipping orderShipping = orderInfo.getOrderShipping();
orderShipping.setOrderId(orderId);
orderShipping.setCreated(new Date());
orderShipping.setUpdated(new Date());
orderShippingMapper.insert(orderShipping);
//返回E3Result,包含订单号
return E3Result.ok(orderId);
}

}
1.1.4.表现层
package cn.e3mall.order.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import cn.e3mall.cart.service.CartService;
import cn.e3mall.common.utils.E3Result;
import cn.e3mall.order.pojo.OrderInfo;
import cn.e3mall.order.service.OrderService;
import cn.e3mall.pojo.TbItem;
import cn.e3mall.pojo.TbUser;

/**
* 订单管理Controller
* <p>Title: OrderController</p>
* <p>Description: </p>
* <p>Company: www.itcast.cn</p>
* @version 1.0
*/
@Controller
public class OrderController {

@Autowired
private CartService cartService;
@Autowired
private OrderService orderService;

@RequestMapping("/order/order-cart")
public String showOrderCart(HttpServletRequest request) {
//取用户id
TbUser user= (TbUser) request.getAttribute("user");
//根据用户id取收货地址列表
//使用静态数据。。。
//取支付方式列表
//静态数据
//根据用户id取购物车列表
List<TbItem> cartList = cartService.getCartList(user.getId());
//把购物车列表传递给jsp
request.setAttribute("cartList", cartList);
//返回页面
return "order-cart";
}

@RequestMapping(value="/order/create", method=RequestMethod.POST)
public String createOrder(OrderInfo orderInfo, HttpServletRequest request) {
//取用户信息
TbUser user = (TbUser) request.getAttribute("user");
//把用户信息添加到orderInfo中。
orderInfo.setUserId(user.getId());
orderInfo.setBuyerNick(user.getUsername());
//调用服务生成订单
E3Result e3Result = orderService.createOrder(orderInfo);
//如果订单生成成功,需要删除购物车
if (e3Result.getStatus() == 200) {
//清空购物车
cartService.clearCartItem(user.getId());
}
//把订单号传递给页面
request.setAttribute("orderId", e3Result.getData());
request.setAttribute("payment", orderInfo.getPayment());
//返回逻辑视图
return "success";
}
}


2.用户身份认证
在展示订单确认页面之前,需要对用户身份进行认证,要求用户必须登录。

2.1.1. 功能分析
1、使用springmvc的拦截器实现。需要实现一个接口HandlerInterceptor接口。

2、业务逻辑

a) 从cookie中取token。

b) 没有token,需要跳转到登录页面。

c) 有token。调用sso系统的服务,根据token查询用户信息。

d) 如果查不到用户信息。用户登录已经过期。需要跳转到登录页面。

e) 查询到用户信息。放行。

3、在springmvc.xml中配置拦截器。

**在展示订单页面前,我们Redis有用户原理购物车数据,需要将Cookie数据与它进行合并

2.1.2. 拦截器实现
package cn.e3mall.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 cn.e3mall.cart.service.CartService;
import cn.e3mall.common.utils.CookieUtils;
import cn.e3mall.common.utils.E3Result;
import cn.e3mall.common.utils.JsonUtils;
import cn.e3mall.pojo.TbItem;
import cn.e3mall.pojo.TbUser;
import cn.e3mall.sso.service.TokenService;

/**
* 用户登录拦截器
* @author cxx
*
*/
public class LoginInterceptor implements HandlerInterceptor{

@Value("${SSO_URL}")
private String SSO_URL;
@Autowired
private TokenService tokenService;
@Autowired
private CartService cartService;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//从cookie中获取token
String token = CookieUtils.getCookieValue(request,"token");
//判断token是否存在
if(StringUtils.isBlank(token)) {
//跳到登录页面,登录成功后跳到该页面
response.sendRedirect(SSO_URL+"/page/login?redirect="+request.getRequestURI());
return false;
}
E3Result e3Result = tokenService.getUserByToken(token);
//判断用户是否身份过期
if(e3Result.getStatus() !=200) {
//如果token不存在,未登录状态,跳转到sso系统的登录页面。用户登录成功后,跳转到当前请求的url
response.sendRedirect(SSO_URL + "/page/login?redirect=" + request.getRequestURL());
//拦截
return false;
}
//把用户信息放入到request中
TbUser user = (TbUser)e3Result.getData();
request.setAttribute("user",user);
//判断cookie中是否有数据,合并到服务器
String jsonCartList = CookieUtils.getCookieValue(request, "cart",true);
if(StringUtils.isNoneBlank(jsonCartList)) {
//合并购物车
cartService.mergeCart(user.getId(), JsonUtils.jsonToList(jsonCartList, TbItem.class));
}
//放行
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub

}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub

}


}
2.1.3. 配置拦截器
springmvc.xml中配置拦截器。

<!-- 拦截器配置 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cn.e3mall.order.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>

2.1.4. 实现sso系统的回调
@RequestMapping("/page/login")
public String showLogin(String redirectUrl,Model model) {
model.addAttribute("redirect",redirectUrl);
return "login";
}


项目展示:

一个问题:订单编号怎么生成

Redis Incr 命令将 key 中储存的数字值增一。

#订单号生成key
ORDER_ID_GEN_KEY=ORDER_ID_GEN
#订单号初始值
ORDER_ID_START=100544
#订单明细id生成key
ORDER_DETAIL_ID_GEN_KEY=ORDER_DETAIL_ID_GEN

猜你喜欢

转载自www.cnblogs.com/java11889/p/10466942.html