最近在做一个类似京东的购物网站,做到购物车模块,购物车中的逻辑为:按照商家id分块,将每个属于同一个商家的商品放在同一个商家模块下,可以选中不同商家的不同商品进行订单提交(购物车中信息存在redis中),将选中的商品传给订单页页面,点击“提交订单”按钮将选中的商品信息传到后台进行订单表和订单详细信息表的生成与保存(此种数据库使用mysql),当传回的数据存入数据库成功后订单状态变为未付款,跳转至支付界面,此时若返回购物车页面则购物车中应将已经提交后台的订单商品剔除,只显示未提交的商品信息。
前台传给后台的数据结构为:前台涉及到需传输的数据为用户地址等信息及已经被选中的商品的信息,因此设置一个集合变量,将两者存入其中,当做同一个对象传给后台,结构为:
all = [
address:[address,mobile,contact]
message:[sellerId,sellerName,orderItemList:[]]
]
其中address为tborder对象,message为List
tborder order,
List cartList.
在后台add方法中,将所有信息设置完毕,并将两个对象存入数据库中后,需要对redis中的购物车信息进行更新,实现思路:设置方法:
private List deleteFromCart(List redisCartList , List submitCartList)
对前台传回的数据与redis中购物车现存信息进行处理,完整代码为:
/**
* 购物车信息剔除
* @param redisCartList
* @param submitCartList
* @return
*/
private List deleteFromCart(List redisCartList , List submitCartList){
System.out.println("进入deletefromcart方法");
System.out.println(submitCartList.get(0));
for(Cart submitCart: submitCartList) {
System.out.println("1");
for(Cart redisCart: redisCartList) {
System.out.println("2");
//如果两个cart中的sellerid相等,则进行tborderitemlist中各项的比对
if(redisCart.getSellerId().equals(submitCart.getSellerId())) {
for(TbOrderItem item:submitCart.getOrderItemList()) {
System.out.println("3");
for(TbOrderItem redis_item: redisCart.getOrderItemList()) {
System.out.println("4");
if(contrastObj(item,redis_item)) {
//Iterator iterator = (Iterator) redisCart.getOrderItemList();
System.out.println("5");
int indexOf = redisCart.getOrderItemList().indexOf(redis_item);
System.out.println("index:" + indexOf);
redisCart.getOrderItemList().remove(indexOf);
System.out.println("移除成功");
break;
//iterator.remove();
//System.out.println("被移除的元素:" + remove);
}
}
}
}
//判断如果所有orderitem都被移除,说明列表中不存在商品,则整个店铺都要移除
if(redisCart.getOrderItemList().size() == 0) {
System.out.println("6");
//Iterator iterator = (Iterator) redisCartList;
int indexOf = redisCartList.indexOf(redisCart);
System.out.println("整体index:"+indexOf);
redisCartList.remove(indexOf);
System.out.println("整体购物项移除成功");
break;
//iterator.remove();
//Cart remove =
//System.out.println("被移除的对象:" + remove);
}
}
}
if(redisCartList.isEmpty() || redisCartList.size() == 0 || redisCartList == null) {
return null;
}
return redisCartList;
}
其中难点为:如何判断两个同类型的对象中的属性值是否相等,经过查阅,选择使用反射的方法,也就是contrastObj()方法
代码为:(转自:https://www.jianshu.com/p/cc9f95792fd3)
//若使用请将Pojo更换成自己所对比对象的类型
public static boolean contrastObj(Object obj1, Object obj2) {
boolean isEquals = true;
if (obj1 instanceof Pojo && obj2 instanceof Pojo) {
Pojo pojo1 = (Pojo) obj1;
Pojo pojo2 = (Pojo) obj2;
List textList = new ArrayList();
try {
Class clazz = pojo1.getClass();
Field[] fields = pojo1.getClass().getDeclaredFields();
for (Field field : fields) {
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
Method getMethod = pd.getReadMethod();
Object o1 = getMethod.invoke(pojo1);
Object o2 = getMethod.invoke(pojo2);
if (!o1.toString().equals(o2.toString())) {
isEquals = false;
textList.add(getMethod.getName() + ":" + "false");
} else {
textList.add(getMethod.getName() + ":" + "true");
}
}
} catch (Exception e) {
}
for (Object object : textList) {
System.out.println(object);
}
}
return isEquals;
}
在完成代码后执行的过程中,出现了java.util.ConcurrentModificationException,经过研究,在deleteFromCart方法中存在嵌套循环,开始rediscart在外层,submitcart在内层,而对内层tborderitemlist的循环则是对调进行,导致ArrayList中modCount不等于expectedModCount,因此调整循环嵌套的变量后成功。
在此记录。20180721