TT_商品详情页实现

1. 需要做的事情

l 商品详情页实现

   1、商品查询服务事项

   2、商品详情展示

   3、添加缓存

2. 实现商品详情页功能

2.1. 功能分析

1Taotao-portal接收页面请求,接收到商品id

2、调用taotao-rest提供的商品详情的服务,把商品id作为参数传递给服务。接收到商品详细。

3、渲染结果,展示商品详细页面

4、为了提高响应速度,商品详情页的内容需要分步骤加载。

第一步:先展示商品基本信息,例如商品的名称、图片、价格。

第二步:展示商品的描述,此时商品页面已经展示完毕,需要ajax请求商品描述。展示的时机是页面加载完毕后一秒钟。

第三步:展示商品规格。当用户点击商品规格选项卡时展示。使用ajax请求商品规格。

5、在搜索页面点击商品的图片或者商品名称请求商品详情页面。

商品详情页请求的url/item/{itemId}.html

商品描述请求的url/item/desc/{itemId}.html

商品规格请求的url/item/param/{itemId}.html

2.2. 处理流程


2.3. Taotao-rest服务

需要实现三个服务:

1、根据商品id查询商品详细表。

2、根据商品id查询商品描述表

3、根据商品id查询商品规格参数表。

2.3.1. Mapper

因为都是单表查询所以使用逆向工程生成的mapper文件即可。

tb_item

tb_item_desc

tb_item_param_item

2.3.2. Service

[java]  view plain  copy
  1. @Service  
  2. public class ItemServiceImplimplements ItemService {  
  3.    
  4. @Autowired  
  5. private TbItemMapperitemMapper;  
  6. @Autowired  
  7. private TbItemDescMapperitemDescMapper;  
  8. @Autowired  
  9. private TbItemParamItemMapperitemParamItemMapper;  
  10. /** 
  11.  * 根据id取商品信息 
  12.  * <p>Title: getItemById</p> 
  13.  * <p>Description:</p> 
  14.  * @param id 
  15.  * @return 
  16.  * @throws Exception 
  17.  * @see com.taotao.rest.service.ItemService#getItemById(java.lang.Long) 
  18.  */  
  19. @Override  
  20. public TbItem getItemById(Longid) throws Exception {  
  21. TbItem tbItem = itemMapper.selectByPrimaryKey(id);  
  22. return tbItem;  
  23. }  
  24.    
  25. /** 
  26.  * 根据id取商品描述 
  27.  * <p>Title: getItemDescById</p> 
  28.  * <p>Description:</p> 
  29.  * @param id 
  30.  * @return 
  31.  * @throws Exception 
  32.  * @see com.taotao.rest.service.ItemService#getItemDescById(java.lang.Long) 
  33.  */  
  34. @Override  
  35. public TbItemDesc getItemDescById(Longid) throws Exception {  
  36. TbItemDesc itemDesc = itemDescMapper.selectByPrimaryKey(id);  
  37. return itemDesc;  
  38. }  
  39.    
  40. /** 
  41.  * 根据商品id取规格参数 
  42.  * <p>Title: getItemParamById</p> 
  43.  * <p>Description:</p> 
  44.  * @param id 
  45.  * @return 
  46.  * @throws Exception 
  47.  * @see com.taotao.rest.service.ItemService#getItemParamById(java.lang.Long) 
  48.  */  
  49. @Override  
  50. public TbItemParamItem getItemParamById(Longid) throws Exception {  
  51. TbItemParamItemExample example = new TbItemParamItemExample();  
  52. Criteria criteria =example.createCriteria();  
  53. criteria.andItemIdEqualTo(id);  
  54. List<TbItemParamItem> list = itemParamItemMapper.selectByExampleWithBLOBs(example);  
  55. TbItemParamItem itemParamItem = null;  
  56. if (null !=null && !list.isEmpty()) {  
  57. itemParamItem = list.get(0);  
  58. }  
  59. return itemParamItem;  
  60. }  
  61.    
  62. }  


2.3.3.  Controller  

[java]  view plain  copy
  1. @Controller  
  2. @RequestMapping("/items")  
  3. public class ItemController {  
  4.    
  5. @Autowired  
  6. private ItemService itemService;  
  7. @RequestMapping("/item/{id}")  
  8. @ResponseBody  
  9. public TaotaoResult getItemById(@PathVariable Longid) {  
  10. //有效性验证  
  11. if (id ==null) {  
  12. return TaotaoResult.build(400,"参数中必须包含id");  
  13. }  
  14. TbItem tbItem = null;  
  15. //根据id查询商品信息  
  16. try {  
  17. tbItem = itemService.getItemById(id);  
  18. catch (Exception e) {  
  19. e.printStackTrace();  
  20. //发生异常时返回异常信息  
  21. return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));  
  22. }  
  23. return TaotaoResult.ok(tbItem);  
  24. }  
  25. @RequestMapping("/itemdesc/{id}")  
  26. @ResponseBody  
  27. public TaotaoResult getItemDescById(@PathVariable Longid) {  
  28. //有效性验证  
  29. if (id ==null) {  
  30. return TaotaoResult.build(400,"参数中必须包含id");  
  31. }  
  32. TbItemDesc tbItemDesc = null;  
  33. //根据id查询商品明细信息  
  34. try {  
  35. tbItemDesc = itemService.getItemDescById(id);  
  36. catch (Exception e) {  
  37. e.printStackTrace();  
  38. //发生异常时返回异常信息  
  39. return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));  
  40. }  
  41. return TaotaoResult.ok(tbItemDesc);  
  42. }  
  43. @RequestMapping("/itemparam/{id}")  
  44. @ResponseBody  
  45. public TaotaoResult getItemParamById(@PathVariable Longid) {  
  46. //有效性验证  
  47. if (id ==null) {  
  48. return TaotaoResult.build(400,"参数中必须包含id");  
  49. }  
  50. TbItemParamItem tbItemParamItem = null;  
  51. //根据id查询商品规格参数信息  
  52. try {  
  53. tbItemParamItem = itemService.getItemParamById(id);  
  54. catch (Exception e) {  
  55. e.printStackTrace();  
  56. //发生异常时返回异常信息  
  57. return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));  
  58. }  
  59. return TaotaoResult.ok(tbItemParamItem);  
  60. }  
  61. }  


2.4. Portal商品详情页实现

2.4.1. 商品POJO

由于页面展示商品信息时,需要展示图片列表。多张图片在数据库中存储的格式是存储在同一个字段中使用逗号分隔的。所以商品展示时需要在pojo中做处理。故此在portal中自定义一个商品的pojo类。

[java]  view plain  copy
  1. public class Item {  
  2.     private Long id;  
  3.     private String title;  
  4.     private String sellPoint;  
  5.     private Long price;  
  6.     private Integer num;  
  7.     private String barcode;  
  8.     private String image;  
  9.     private Long cid;  
  10.     private Byte status;  
  11.     private Date created;  
  12.     private Date updated;  
  13.     //省略get、set方法。。。。。。  
  14.     //添加此方法拆分图片列表  
  15.  public String[] getImages() {  
  16.     if (image != null && image != "") {  
  17.     String[] strings = image.split(",");  
  18.     return strings;  
  19.     }  
  20.     return null;  
  21.  }  
  22. }  



2.4.2. Service 

[java]  view plain  copy
  1. @Service  
  2. public class ItemServiceImplimplements ItemService {  
  3.    
  4. @Value("${REST_BASE_URL}")  
  5. private String REST_BASE_URL;  
  6. @Value("${ITEMS_ITEM_URL}")  
  7. private String ITEMS_ITEM_URL;  
  8. @Value("${ITEMS_ITEMDESC_URL}")  
  9. private String ITEMS_ITEMDESC_URL;  
  10. @Value("${ITEMS_ITEMPARAM_URL}")  
  11. private String ITEMS_ITEMPARAM_URL;  
  12.    
  13. @Override  
  14. public Item getItemById(Longid) throws Exception {  
  15. // 查询商品信息  
  16. String result = HttpClientUtil.doGet(REST_BASE_URL +ITEMS_ITEM_URL + id);  
  17. // 转换成java对象  
  18. TaotaoResult taotaoResult = TaotaoResult.formatToPojo(result,Item.class);  
  19. Item item =null;  
  20. if (taotaoResult.getStatus() == 200) {  
  21. item = (Item)taotaoResult.getData();  
  22. }  
  23.    
  24. return item;  
  25. }  
  26.    
  27. @Override  
  28. public TbItemDesc geTbItemDescById(Longid) throws Exception {  
  29. // 查询商品信息  
  30. String result = HttpClientUtil.doGet(REST_BASE_URL +ITEMS_ITEMDESC_URL + id);  
  31. // 转换成java对象  
  32. TaotaoResult taotaoResult = TaotaoResult.formatToPojo(result, TbItemDesc.class);  
  33. TbItemDesc itemDesc = null;  
  34. if (taotaoResult.getStatus() == 200) {  
  35. itemDesc = (TbItemDesc) taotaoResult.getData();  
  36. }  
  37.    
  38. return itemDesc;  
  39. }  
  40.    
  41. @Override  
  42. public String geTbItemParamItemById(Longid) throws Exception {  
  43. // 查询商品信息  
  44. String result = HttpClientUtil.doGet(REST_BASE_URL +ITEMS_ITEMPARAM_URL + id);  
  45. // 转换成java对象  
  46. TaotaoResult taotaoResult = TaotaoResult.formatToPojo(result, TbItemParamItem.class);  
  47. String resultHtml = "";  
  48. if (taotaoResult.getStatus() == 200) {  
  49. try {  
  50. TbItemParamItem itemParamItem = (TbItemParamItem)taotaoResult.getData();  
  51. //取规格参数信息  
  52. String paramData = itemParamItem.getParamData();  
  53. //把规格参数转换成java对象  
  54. List<Map> paramList = JsonUtils.jsonToList(paramData, Map.class);  
  55. //拼装html  
  56. resultHtml ="<table cellpadding=\"0\" cellspacing=\"1\" width=\"100%\" border=\"0\" class=\"Ptable\">\n" +  
  57. "    <tbody>\n";  
  58. for (Map map :paramList) {  
  59. resultHtml +=  
  60. "        <tr>\n" +  
  61. "            <th class=\"tdTitle\" colspan=\"2\">"+map.get("group")+"</th>\n" +  
  62. "        </tr>\n";  
  63. List<Map> params = (List<Map>)map.get("params");  
  64. for (Map map2 :params) {  
  65. resultHtml +=  
  66. "        <tr>\n" +  
  67. "            <td class=\"tdTitle\">"+map2.get("k")+"</td>\n" +  
  68. "            <td>"+map2.get("v")+"</td>\n" +  
  69. "        </tr>\n" ;  
  70. }  
  71. }  
  72. resultHtml += "    </tbody>\n" +  
  73. "</table>";  
  74. catch (Exception e){  
  75. //如果转换发送异常,忽略。返回一个空字符串。  
  76. e.printStackTrace();  
  77. }  
  78. }  
  79.    
  80. return resultHtml;  
  81. }  
  82.    
  83. }  

2.4.3. Controller 


[java]  view plain  copy
  1. @Controller  
  2. public class ItemController {  
  3.    
  4. @Autowired  
  5. private ItemService itemService;  
  6. @RequestMapping("/item/{id}")  
  7. public String showItem(@PathVariable Longid, Model model) throws Exception {  
  8. //取商品信息  
  9. Item item = itemService.getItemById(id);  
  10. //把结果传递给页面  
  11. model.addAttribute("item",item);  
  12. //返回逻辑视图  
  13. return "item";  
  14. }  
  15. @RequestMapping(value="/item/desc/{id}", produces=MediaType.TEXT_HTML_VALUE+";charset=utf-8")  
  16. @ResponseBody  
  17. public String showItemDesc(@PathVariable Longid) throws Exception {  
  18. //取商品描述  
  19. TbItemDesc itemDesc = itemService.geTbItemDescById(id);  
  20. //返回商品描述信息  
  21. return itemDesc.getItemDesc();  
  22. }  
  23. @RequestMapping(value="/item/param/{id}", produces=MediaType.TEXT_HTML_VALUE+";charset=utf-8")  
  24. @ResponseBody  
  25. public String showItemParam(@PathVariable Longid) throws Exception {  
  26. //取规格参数  
  27. String itemParamItem = itemService.geTbItemParamItemById(id);  
  28. //返回规格参数信息  
  29. return itemParamItem;  
  30. }  
  31. }  

2.4.4. 效果:

 

 

 

 

 

2.5. 添加缓存逻辑  

[java]  view plain  copy
  1. @Override  
  2.     public TbItem getItemById(Long id) throws Exception {  
  3.         //缓存中命中  
  4.         //在redis中无法对hash中的可以做expire。所以使用另外一种方法:key的命名方法为“主key:id”  
  5.         String itemCache = jedisCluster.get(TB_ITEM_KEY + ":" + id);  
  6.         try {  
  7.             if (!StringUtils.isBlank(itemCache)) {  
  8.                 TbItem tbItem = JsonUtils.jsonToPojo(itemCache, TbItem.class);  
  9.                 return tbItem;  
  10.             }  
  11.         } catch (Exception e) {  
  12.             e.printStackTrace();  
  13.         }  
  14.         //如果缓存中没有数据,查询数据库  
  15.         TbItem tbItem = itemMapper.selectByPrimaryKey(id);  
  16.         //把数据缓存起来  
  17.         try {  
  18.             jedisCluster.set(TB_ITEM_KEY + ":" + id, JsonUtils.objectToJson(tbItem));  
  19.             //设置过期时间,有效期一天  
  20.             jedisCluster.expire(TB_ITEM_KEY + ":" + id, 60*60*24);  
  21.         } catch (Exception e) {  
  22.             e.printStackTrace();  
  23.         }  
  24.         return tbItem;  
  25.     }  

 

3. 缓存同步

Redis是内存数据库也属于稀缺资源,所以不应该永久占用,所以要设置过期时间。当商品内容更新后,需要同步缓存。同步方法参见内容部分的缓存同步方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值