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是內存數據庫也屬於稀缺資源,所以不應該永久佔用,所以要設置過期時間。當商品內容更新後,需要同步緩存。同步方法參見內容部分的緩存同步方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章