教学网站建设论文,wordpress python导入,官方网站建设方案图,系统那个网站好#x1f44f;作者简介#xff1a;大家好#xff0c;我是小童#xff0c;Java开发工程师#xff0c;CSDN博客博主#xff0c;Java领域新星创作者 #x1f4d5;系列专栏#xff1a;前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 #x1f4… 作者简介大家好我是小童Java开发工程师CSDN博客博主Java领域新星创作者 系列专栏前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 如果文章知识点有错误的地方请指正和大家一起学习一起进步 如果感觉博主的文章还不错的话请三连支持一下博主哦 博主正在努力完成2023计划中以梦为马扬帆起航2023追梦人 专栏:高并发项目 编写购物车服务接口
用户购买商品的流程为 搜索商品 查看商品详情 添加到购物车 生成商品订单 支 付 搜索商品和查看商品详情功能已经完成接下来我们编写购物 车服务。购物车数据属于临时数据为了节约数据库开销我们会 将其存放到redis中。
在通用模块编写购物车服务接口
// 购物车服务
public interface CartService {// 新增商品到购物车void addCart(Long userId, CartGoods cartGoods);// 修改购物车商品数量void handleCart(Long userId, Long goodId, Integer num);// 删除购物车商品void deleteCartOption(Long userId, Long goodId);// 获取用户购物车ListCartGoods findCartList(Long userId);// 更新redis中的商品数据在管理员更新商品后执行void refreshCartGoods(CartGoods cartGoods);// 删除redis中的商品数据在管理员下架商品后执行void deleteCartGoods(CartGoods cartGoods);
}
创建购物车服务模块
1、创建名为 shopping_cart_service 的SpringBoot工程添加相关依赖。
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactId/dependencydependencygroupIdcom.itbaizhan/groupIdartifactIdshopping_common/artifactIdversion0.0.1-SNAPSHOT/version/dependency!-- dubbo --dependencygroupIdorg.apache.dubbo/groupIdartifactIddubbo-spring-boot-starter/artifactIdversion2.7.8/version/dependency!-- 操作zookeeper --dependencygroupIdorg.apache.curator/groupIdartifactIdcurator-recipes/artifactIdversion4.2.0/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency!-- redis --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependency
/dependencies2、设置该工程的父工程为 shopping 。
parentgroupIdcom.ittxc/groupIdartifactIdshopping/artifactIdversion1.0-SNAPSHOT/version
/parent
3、给 shopping 工程设置子模块
!-- 子模块 --
modules!-- 购物车服务 --moduleshopping_cart_service/module
/modules
4、编写配置文件 application.yml
# 端口号
server:port: 9009
# 日志格式
logging:pattern:console: %d{HH:mm:ss.SSS} %clr(%-5level) --- [%-15thread] %cyan(%-50logger{50}):%msg%n
spring:# redisredis:host: 192.168.0.159port: 6379timeout: 30000jedis:pool:max-active: 8max-wait: -1max-idle: 8min-idle: 0
dubbo:application:name: shopping_cart_service # 项目名registry:address: zookeeper://192.168.0.159 #注册中心地址port: 2181 # 注册中心的端口timeout: 10000 # 注册到zk上超时时间msprotocol:name: dubbo # dubbo使用的协议port: -1 # dubbo自动分配端口scan:base-packages: com.itbaizhan.shopping_cart_service.service # 包扫描
5、启动类忽略数据源自动配置
SpringBootApplication(exclude {DataSourceAutoConfiguration.class})
public class ShoppingCartServiceApplication {public static void main(String[] args)
{SpringApplication.run(ShoppingCartServiceApplication.class, args);}
}
创建购物车Api模块
1、创建名为 shopping_cart_customer_api 的SpringBoot工程添加相关依赖。
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- dubbo --dependencygroupIdorg.apache.dubbo/groupIdartifactIddubbo-spring-boot-starter/artifactIdversion2.7.8/version/dependency!-- 操作zookeeper --dependencygroupIdorg.apache.curator/groupIdartifactIdcurator-recipes/artifactIdversion4.2.0/version/dependencydependencygroupIdcom.itbaizhan/groupIdartifactIdshopping_common/artifactIdversion0.0.1-SNAPSHOT/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-startertest/artifactIdscopetest/scope/dependency
/dependencies 2、设置该工程的父工程为 shopping 。
parentgroupIdcom.ittxc/groupIdartifactIdshopping/artifactIdversion1.0-SNAPSHOT/version
/parent
3、给 shopping 工程设置子模块
!-- 子模块 --
modules!-- 购物车api --moduleshopping_cart_customer_api/module
/modules
4、编写配置文件 application.yml
# 端口号
server:port: 8005
# 日志格式
logging:pattern:console: %d{HH:mm:ss.SSS} %clr(%-5level) --- [%-15thread] %cyan(%-50logger{50}):%msg%n
dubbo:application:name: shopping_cart_customer_api # 项目名registry:address: zookeeper://192.168.0.159 #注册中心地址port: 2181 # 注册中心的端口timeout: 10000 # 注册到zk上超时时间msprotocol:name: dubbo # dubbo使用的协议port: -1 # dubbo自动分配端口
5、启动类忽略数据源自动配置
SpringBootApplication(exclude {DataSourceAutoConfiguration.class})
public class ShoppingUserCustomerApiApplication {public static void main(String[] args)
{SpringApplication.run(ShoppingUserCustomerApiApplication.class, args);}
}
编写查询用户购物车功能
我们将用户的购物车信息保存到redis当中所有用户的购物车作为 一个hash类型的数据保存hash的键是用户idhash的值是购物车商品列表。 在购物车服务模块创建购物车服务接口的实现类重写查询用户购物车功能
DubboService
public class CartServiceImpl implements CartService {Autowiredprivate RedisTemplate redisTemplate;Overridepublic ListCartGoods findCartList(Long userId) {Object cartList redisTemplate.boundHashOps(cartList).get(userId);if (cartList null) {return new ArrayListCartGoods();} else {return (ListCartGoods)cartList;}}
} 编写添加商品到购物车方法
Override
public void addCart(Long userId, CartGoods cartGoods) {// 1.根据用户id获取用户购物车列表ListCartGoods cartList findCartList(userId);// 2.查询购物车是否有该商品如果有商品添加商品数量for (CartGoods cartGoods1 : cartList) {if(cartGoods.getGoodId().equals(cartGoods1.getGoodId())){int newNum cartGoods1.getNum() cartGoods.getNum();cartGoods1.setNum(newNum);redisTemplate.boundHashOps(cartList).put(userId,cartList);return;}}// 3.如果购物车没有该商品将商品添加到购物车列表cartList.add(cartGoods);redisTemplate.boundHashOps(cartList).put(userId,cartList);
}
编写修改购物车商品数量方法
Override
public void handleCart(Long userId, Long goodId, Integer num) {// 获取用户购物车列表ListCartGoods cartList findCartList(userId);// 遍历列表找到对应商品for (CartGoods cartGoods : cartList) {if(goodId.equals(cartGoods.getGoodId())) {// 改变商品数量cartGoods.setNum(num);break;}}// 将新的购物车列表保存到redis中redisTemplate.boundHashOps(cartList).put(userId, cartList);
}
编写删除购物车商品方法
Override
public void deleteCartOption(Long userId,Long goodId) {// 获取用户购物车列表ListCartGoods cartList findCartList(userId);// 将商品移出列表for (CartGoods cartGoods : cartList) {if (goodId.equals(cartGoods.getGoodId())) {cartList.remove(cartGoods);break;}}// 将新的购物车列表保存到redis中redisTemplate.boundHashOps(cartList).put(userId, cartList);
}
编写购物车控制器
在进行购物车操作之前要先获取用户的Id而用户的令牌中只保存了用户名所以我们要修改JWT工具类让令牌中也保存用户的 Id
1、修改JWT工具类
public class JWTUtil {//token过期时间一天private static final Long EXPIRE_DATE 1000*60*60*24L;// 秘钥private static final String SECRET xiaotong;// 签发者private static final String ISSUER XIAOTONG;/*** 签名生成* param shoppingUser* return*/public static String sign(ShoppingUser shoppingUser){String token JWT.create().withIssuer(ISSUER) // 签发者.withIssuedAt(new Date())// 签发时间.withExpiresAt(new Date(new Date().getTime() EXPIRE_DATE))// 过期时间.withSubject(shoppingUser.getUsername())// 保存用户名.withClaim(userId,shoppingUser.getId())// 保存用户id.sign(Algorithm.HMAC256(SECRET)); // 秘钥return token;}/*** 签名解析* param token 签名字符串* return 解析得出的用户名*/public static String verify(String token){try {String username JWT.require(Algorithm.HMAC256(SECRET)).withIssuer(ISSUER).build().verify(token).getSubject();return username;} catch (Exception e){throw new BusException(CodeEnum.VERIFY_TOKEN_ERROR);}}/*** 签名解析获取用户id* param token 签名字符串* return 用户id*/public static Long getId(String token){try {Long userId JWT.require(Algorithm.HMAC256(SECRET)).withIssuer(ISSUER).build().verify(token).getClaim(userId).asLong();return userId;} catch (Exception e){throw new BusException(CodeEnum.VERIFY_TOKEN_ERROR);}}
}
2、在购物车Api模块编写购物车控制器
/**
* 购物车
*/
RestController
RequestMapping(/user/cart)
public class CartController {DubboReferenceprivate CartService cartService;/*** 查询用户购物车* param token 用户令牌* return 用户购物车列表*/GetMapping(/findCartList)public BaseResultListCartGoods findCartList(RequestHeader String token){Long userId JWTUtil.getId(token); // 获取用户idListCartGoods cartList cartService.findCartList(userId);return BaseResult.ok(cartList);}/*** 新增商品到购物车* param cartGoods 购物车商品* param token 用户令牌* return 操作结果*/PostMapping(/addCart)public BaseResult addCart(RequestBody CartGoods cartGoods,RequestHeader String token){Long userId JWTUtil.getId(token); // 获取用户idcartService.addCart(userId,cartGoods);return BaseResult.ok();}/*** 修改购物车商品数量* param token 用户令牌* param goodId 商品id* param num 修改后的数量* return 操作结果*/GetMapping(/handleCart)public BaseResult addCart(RequestHeader String token,Long goodId,Integer num){Long userId JWTUtil.getId(token); // 获取用户idcartService.handleCart(userId,goodId,num);return BaseResult.ok();}/*** 删除购物车商品* param token 用户令牌* param goodId 商品id* return 操作结果*/DeleteMapping(/deleteCart)public BaseResult addCart(RequestHeader String token,Long goodId){Long userId JWTUtil.getId(token); // 获取用户idcartService.deleteCartOption(userId,goodId);return BaseResult.ok();}
}
编写修改所有用户购物车商品方法
当管理员修改了商品的价格等数据后需要将数据同步到用户购物车中所以我们要编写给所有用户的购物车中修改某件商品的方法。
Override
public void refreshCartGoods(CartGoods
cartGoods) {// 获取所有用户购物车商品BoundHashOperations cartList redisTemplate.boundHashOps(cartList);MapLong,ListCartGoods allCartGoods cartList.entries();SetMap.EntryLong, ListCartGoods entries allCartGoods.entrySet();// 遍历所有用户的购物车for (Map.EntryLong, ListCartGoods entry : entries) {ListCartGoods goodsList entry.getValue();// 遍历一个用户购物车的所有商品for (CartGoods goods : goodsList) {// 如果该商品是被更新的商品修改商品数据if(cartGoods.getGoodId().equals(goods.getGoodId())){goods.setGoodsName(cartGoods.getGoodsName());goods.setHeaderPic(cartGoods.getHeaderPic());goods.setPrice(cartGoods.getPrice());}}}// 将改变后所有用户购物车重新放入redisredisTemplate.delete(cartList);redisTemplate.boundHashOps(cartList).putAll(allCartGoods);
}
编写删除所有用户购物车商品方法
当管理员下架某件商品后所有用户的购物车中该商品也应该被删除所以我们要编写给所有用户的购物车中删除某件商品的方法。
Override
public void deleteCartGoods(CartGoods cartGoods) {BoundHashOperations cartList redisTemplate.boundHashOps(cartList);// 所有用户的购物车MapString,ListCartGoods allCartGoods cartList.entries();SetMap.EntryString, ListCartGoods entries allCartGoods.entrySet();// 遍历所有用户的购物车for (Map.EntryString, ListCartGoods entry : entries) {ListCartGoods goodsList entry.getValue();// 遍历一个用户购物车的所有商品for (CartGoods goods : goodsList) {// 如果该商品是被删除的商品if (cartGoods.getGoodId().equals(goods.getGoodId())){goodsList.remove(goods);break;}}}// 将改变后的map重新放入redisredisTemplate.delete(cartList);redisTemplate.boundHashOps(cartList).putAll(allCartGoods);
}优化修改商品、下架商品方法
接下来我们修改商品服务模块代码在修改商品后发送消息同步修 改购物车数据在下架商品后发送消息同步删除购物车数据
1、在MQ配置文件创建队列绑定队列到交换机
Configuration
public class RabbitConfig {// 交换机private final String GOODS_EXCHANGE goods_exchange;// 同步商品数据队列private final String SYNC_GOODS_QUEUE sync_goods_queue;// 删除商品数据队列private final String DEL_GOODS_QUEUE del_goods_queue;// 向购物车同步商品队列private final String SYNC_CART_QUEUE sync_cart_queue;// 向购物车删除商品队列private final String DEL_CART_QUEUE del_cart_queue;// 创建交换机Bean(GOODS_EXCHANGE)public Exchange getExchange() {return ExchangeBuilder.topicExchange(GOODS_EXCHANGE) // 交换机类型.durable(true) // 是否持久化.build();}// 创建队列Bean(SYNC_GOODS_QUEUE)public Queue getQueue1() {return new Queue(SYNC_GOODS_QUEUE); // 队列名}Bean(DEL_GOODS_QUEUE)public Queue getQueue2() {return new Queue(DEL_GOODS_QUEUE);// 队列名}Bean(SYNC_CART_QUEUE)public Queue getQueue3() {return new Queue(SYNC_CART_QUEUE);// 队列名}Bean(DEL_CART_QUEUE)public Queue getQueue4() {return new Queue(DEL_CART_QUEUE);
// 队列名}// 交换机绑定队列Beanpublic Binding bindQueue1(Qualifier(GOODS_EXCHANGE) Exchange exchange,Qualifier(SYNC_GOODS_QUEUE) Queue queue){return BindingBuilder.bind(queue).to(exchange).with(#.sync_goods.#).noargs();}Beanpublic Binding bindQueue2(Qualifier(GOODS_EXCHANGE) Exchange exchange,Qualifier(DEL_GOODS_QUEUE) Queue queue) {return BindingBuilder.bind(queue).to(exchange).with(#.del_goods.#).noargs();}Beanpublic Binding
bindQueue3(Qualifier(GOODS_EXCHANGE)
Exchange exchange,Qualifier(SYNC_CART_QUEUE) Queue queue)
{return BindingBuilder.bind(queue).to(exchange).with(#.sync_cart.#).noargs();}Beanpublic Binding bindQueue4(Qualifier(GOODS_EXCHANGE) Exchange exchange,Qualifier(DEL_CART_QUEUE) Queue queue) {return BindingBuilder.bind(queue).to(exchange).with(#.del_cart.#).noargs();}
}
DubboService
public class GoodsServiceImpl implements
GoodsService {Autowiredprivate GoodsMapper goodsMapper;Autowiredprivate GoodsImageMapper goodsImageMapper;Autowiredprivate RabbitTemplate rabbitTemplate;Overridepublic void update(Goods goods) {// 删除旧图片数据Long goodsId goods.getId(); //商品idQueryWrapperGoodsImage queryWrapper new QueryWrapper();queryWrapper.eq(goodsId,goodsId);goodsImageMapper.delete(queryWrapper);// 删除旧规格项数据goodsMapper.deleteGoodsSpecificationOption(goodsId);// 插入商品数据goodsMapper.updateById(goods);// 插入图片数据ListGoodsImage images goods.getImages(); // 商品图片for (GoodsImage image : images) {image.setGoodsId(goodsId); // 给图片设置商品idgoodsImageMapper.insert(image); // 插入图片}// 插入商品_规格项数据ListSpecification specifications goods.getSpecifications(); // 获取规格ListSpecificationOption options new ArrayList(); // 规格项集合// 遍历规格获取规格中的所有规格项for (Specification specification : specifications) {options.addAll(specification.getSpecificationOptions());}// 遍历规格项插入商品_规格项数据for (SpecificationOption option : options) {goodsMapper.addGoodsSpecificationOption(goodsId,option.getId());}rabbitTemplate.convertAndSend(goods_exchange,sync_goods,findById(goodsId));// 将商品修改数据同步到用户购物车CartGoods cartGoods new CartGoods();cartGoods.setGoodId(goods.getId());cartGoods.setGoodsName(goods.getGoodsName());cartGoods.setHeaderPic(goods.getHeaderPic());cartGoods.setPrice(goods.getPrice());rabbitTemplate.convertAndSend(goods_exchange,sync_cart,cartGoods);}Overridepublic void putAway(Long id, Boolean isMarketable) {goodsMapper.putAway(id,isMarketable);if (isMarketable){// 上架时同步到ESrabbitTemplate.convertAndSend(goods_exchange,sync_goods,findById(id));}else{// 下架删除ES数据rabbitTemplate.convertAndSend(goods_exchange,del_goods,id);// 商品下架删除用户购物车CartGoods cartGoods new CartGoods();cartGoods.setGoodId(id);rabbitTemplate.convertAndSend(goods_exchange,del_cart,cartGoods);}}
}
购物车模块监听修改商品、删除商品消息
1、在购物车服务模块添加RabbitMQ依赖
!-- RabbitMQ --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-amqp/artifactId
/dependency
2、添加RabbitMQ配置
spring:# redisredis:host: 192.168.0.159port: 6379timeout: 30000jedis:pool:max-active: 8max-wait: -1max-idle: 8min-idle: 0# rabbitmqrabbitmq:host: 192.168.0.159port: 5672username: guestpassword: guestvirtual-host: /
3、修改购物车服务接口实现类监听队列
DubboService
Service
public class CartServiceImpl implements CartService {Autowiredprivate RedisTemplate redisTemplate;// 监听修改购物车商品队列RabbitListener(queues sync_cart_queue)public void listenSyncQueue(CartGoods cartGoods){refreshCartGoods(cartGoods);}// 监听删除购物车商品队列RabbitListener(queues del_cart_queue)public void listenDelQueue(CartGoods cartGoods){deleteCartGoods(cartGoods);}
}
4、测试管理员修改商品、下架商品看用户购物车是否发生改变。