什么是Session:
使用Cookie和附加URL参数都可以将上一次请求的状态信息传递到下一次请求中,但是如果传递的状态信息较多,将极大降低网络传输效率和增大服务器端程序处理的难度。
Session技术是一种将会话状态保存在服务器端的技术 ,它可以比喻成是医院发放给病人的病历卡和医院为每个病人保留的病历档案的结合方式 。
客户端需要接收、记忆和回送 Session的会话标识号,Session可以且通常是借助Cookie来传递会话标识号。
如果以前没有接触过的话可以看下面这篇博客:
这里我用了一些网上流传比较广的工具类,如果有兴趣可以看一下,就是源码中的utils包下的那些类,熟练使用这些类可以方便你更快地完成更完善的功能。
当我们想让一本书籍加入购物车时将会调用Controller层中的这个方法,传入的参数是书籍的id。
@RequestMapping("/add/{itemId}")
public String addCartItem(@PathVariable Long itemId, HttpServletRequest request, HttpServletResponse response) {
cartService.addCartItem(itemId, request, response);
return "cart/success";
}
接着到了Service层,我们得先在Service层写一个获取购物车中商品列表的类,这样商品才有地方可以放置:
private List getCartItemList(HttpServletRequest request) {
//从cookie中取商品列表
String cartJson = CookieUtil.getCookieValue(request, "ZouCart", true);
if (cartJson == null) {
return new ArrayList<>();
}
//把json转换成商品列表
try {
List list = JsonUtils.jsonToList(cartJson, CartItem.class);
if(list==null){
list = new ArrayList<>();
}
return list;
} catch (Exception e) {
e.printStackTrace();
}
return new ArrayList<>();
}
}
public List getCartItemList(HttpServletRequest request, HttpServletResponse response) {
//从cookies中取得商品列表
String cartJson = CookieUtil.getCookieValue(request, "ZouCart", true);
if (cartJson == null) {
return new ArrayList<>();
}
//把json转换成商品列表
try {
List list = JsonUtils.jsonToList(cartJson, CartItem.class);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return new ArrayList<>();
}
当我们试图加入一个商品进入购物车时会调用这个方法
@Override
public Msg addCartItem(long itemId, HttpServletRequest request, HttpServletResponse response) {
//取商品信息
CartItem cartItem = null;
//收取购物车商品列表
List itemList = getCartItemList(request);
//判断购物车商品列表是否存在此商品
for (CartItem item : itemList) {
//如果存在此商品
if (item.getId() == itemId) {
//增加商品数量
item.setQuantity(item.getQuantity() + 1);
cartItem = item;
break;
}
}
if (cartItem == null) {
cartItem = new CartItem();
Msg msg = bookService.getBookByPrimary(itemId);
if (msg.getCode() == 100) {
Book book = (Book) msg.getExtend().get("book");
cartItem.setQuantity(1);
cartItem.setB_id(book.getbId());
cartItem.setId(book.getbId());
cartItem.setAuthor(book.getAuthor());
cartItem.setBook_image(book.getBookImage());
cartItem.setBook_name(book.getBookName());
cartItem.setPrice(book.getPrice());
cartItem.setPubilshing(book.getPubilshing());
}
//添加到购物车列表
itemList.add(cartItem);
}
CookieUtil.setCookie(request, response, "ZouCart", JsonUtils.objectToJson(itemList), true);
return Msg.success();
}
因为这里我们是用Session实现购物车功能,不涉及数据库的使用,所以我们不需要dao层
如果我们要删除一个商品又怎样呢:
public Msg deleteCartItem(long itemId, HttpServletRequest request, HttpServletResponse response) {
//从cookies中获取购物车列表
List itemList = getCartItemList(request);
//从列表中找到此商品
for (CartItem cartItem : itemList) {
if (cartItem.getId() == itemId) {
itemList.remove(cartItem);
break;
}
}
//把购物车列表重新写入cookies
CookieUtil.setCookie(request, response, "ZouCart", JsonUtils.objectToJson(itemList), true);
return Msg.success();
}
当我们进入购物车界面时是可以更改我们所拥有书籍的数量的,那么就需要一个更新书籍的方法
public Msg updateItem(long itemId, int quantity, HttpServletRequest request, HttpServletResponse response) {
List itemList = getCartItemList(request);
for (CartItem cartItem : itemList) {
if (cartItem.getId() == itemId) {
cartItem.setQuantity(quantity);
break;
}
}
CookieUtil.setCookie(request, response, "ZouCart", JsonUtils.objectToJson(itemList), true);
return Msg.success();
}
购物车功能大概介绍完了,接下来就是提交订单功能了,我们知道,只要是涉及到金钱的我们都需要小心,一个设计上的失误就可能会导致大量的损失。
事务(Transaction)是并发控制的单位,是用户定义的一个操作序列。
这些操作要么都做,要么都不做,是一个不可分割的工作单位。
通过事务,SQL Server能将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性。
主要用于一些对操作过程的完整性比较高的程序。
比如银行系统,用户在转账的过程中程序出现错误,但是这个转账操作没有完成。那么这个操作就被退回。
不了解事务的可以看下面两个链接,都很详细。
数据库事务详解
Spring事务管理(详解+实例)
Spring的注解式事务十分简单,只需要在Service层对应的需要使用注解的地方加上@Transactional注解即可,注意readOnly一定要是false,代表这不是一个只读操作,而只读操作是不需要使用事务的。
@Transactional(rollbackFor = {Exception.class},propagation = Propagation.REQUIRED,readOnly = false)
public String create(Allint allint, Order order, List<Detail> details) throws Exception {
//调用创建订单服务前补全用户信息
//从cookie中取得购物车的内容,然后获取用户信息
String orderId = new Date().getTime() + UUID.randomUUID().toString().substring(0, 5);
order.setoId(orderId);
orderMapper.insert(order);
int i = 0;
for (Detail detail : details) {
long bId = allint.getInts().get(i);
long stock = bookMapper.checkBookStock(bId);
long bookNum = detail.getBookNum();
if (stock < bookNum) {
throw new Exception();
}
//补全订单明细信息并存储
detail.setoId(orderId);
orderMapper.insertDetail(detail);
//减少书本库存,增加书本销量
HashMap<String, Long> map = new HashMap<>();
map.put("stock", (long) detail.getBookNum());
map.put("bId", allint.getInts().get(i));
bookMapper.reduceBook(map);
i = i + 1;
}
return orderId;
}