1. 程式人生 > >商品詳情頁面展示——淘淘商城(二十二)

商品詳情頁面展示——淘淘商城(二十二)

商品資訊服務釋出

需求

  • 提供三個介面,分別提供商品基本資訊、商品描述、商品引數,並設定快取時間為1天。
  • 在taotao-rest中開發。
  • 商品基本資訊:
    • 請求url:/item/base/{itemId}
    • 請求引數:url中的商品id
    • 響應資訊:TaoTaoResult,包含商品基本資訊。
  • 商品描述:
    • 請求url:/item/desc/{itemId}
    • 請求引數:url中的商品id
    • 響應資訊:TaoTaoResult,包含商品描述。
  • 商品基本資訊:
    • 請求url:/item/param/{itemId}
    • 請求引數:url中的商品id
    • 響應資訊:TaoTaoResult,包含商品引數。

Service層

  • 在redis.properties中設定redis相關引數。
    • 商品基本資訊在redis中快取的key格式為:REDIS_ITEM_KEY:商品id:ITEM_BASE_KEY。
    • 這種以 : 分隔的key能夠有層次的表示redis中的資料,並且彌補hash型別不能設定國企時間的缺陷。
      9.rediskey.png
    • 商品描述和引數的key格式類似。
#商品的key
REDIS_ITEM_KEY=item
#商品基礎資訊的key
ITEM_BASE_KEY=base
#商品描述的key
ITEM_DESC_KEY=desc
#商品引數的key
ITEM_PARAM_KEY=param

#商品過期時間
REDIS_ITEM_EXPIRE=86400
  • 建立ItemService和對應實現類,根據id獲取商品基本資訊、描述、引數,並使用TaoTaoResult包裝。
    • 注意快取的讀取和寫入,以及過期時間的設定。
@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private TbItemMapper itemMapper;
    @Autowired
    private TbItemDescMapper itemDescMapper;
    @Autowired
    private TbItemParamItemMapper itemParamItemMapper;
    @Autowired
private RedisDao redisDao; @Value("${REDIS_ITEM_KEY}") private String REDIS_ITEM_KEY; @Value("${ITEM_BASE_KEY}") private String ITEM_BASE_KEY; @Value("${ITEM_DESC_KEY}") private String ITEM_DESC_KEY; @Value("${ITEM_PARAM_KEY}") private String ITEM_PARAM_KEY; @Value("${REDIS_ITEM_EXPIRE}") private Integer REDIS_ITEM_EXPIRE; @Override public TaotaoResult getItemBaseInfo(long itemId) { //該商品redis中商品基本資訊對應的key String key = REDIS_ITEM_KEY + ":" + itemId + ":" + ITEM_BASE_KEY; //快取中讀取 try { String json = redisDao.get(key); if (!StringUtils.isBlank(json)) { TbItem item = JsonUtils.jsonToPojo(json, TbItem.class); return TaotaoResult.ok(item); } } catch (Exception e) { e.printStackTrace(); } //查詢基本資訊 TbItem item = itemMapper.selectByPrimaryKey(itemId); //寫入快取 try { redisDao.set(key, JsonUtils.objectToJson(item)); redisDao.expire(key, REDIS_ITEM_EXPIRE); } catch (Exception e) { e.printStackTrace(); } return TaotaoResult.ok(item); } @Override public TaotaoResult getItemDesc(long itemId) { //該商品redis中商品描述對應的key String key = REDIS_ITEM_KEY + ":" + itemId + ":" + ITEM_DESC_KEY; //讀取快取 try { String json = redisDao.get(key); if (!StringUtils.isBlank(json)) { TbItemDesc itemDesc = JsonUtils.jsonToPojo(json, TbItemDesc.class); return TaotaoResult.ok(itemDesc); } } catch (Exception e) { e.printStackTrace(); } //查詢基本資訊 TbItemDesc itemDesc = itemDescMapper.selectByPrimaryKey(itemId); //寫入快取 try { redisDao.set(key, JsonUtils.objectToJson(itemDesc)); redisDao.expire(key, REDIS_ITEM_EXPIRE); } catch (Exception e) { e.printStackTrace(); } return TaotaoResult.ok(itemDesc); } @Override public TaotaoResult getItemParam(long itemId) { //該商品redis中商品引數對應的key String key = REDIS_ITEM_KEY + ":" + itemId + ":" + ITEM_PARAM_KEY; //讀取快取 try { String json = redisDao.get(key); if (!StringUtils.isBlank(json)) { TbItemParamItem itemParamItem = JsonUtils.jsonToPojo(json, TbItemParamItem.class); return TaotaoResult.ok(itemParamItem); } } catch (Exception e) { e.printStackTrace(); } //查詢基本資訊 TbItemParamItem itemParamItem = null; TbItemParamItemExample example = new TbItemParamItemExample(); Criteria criteria = example.createCriteria(); criteria.andItemIdEqualTo(itemId); List<TbItemParamItem> list = itemParamItemMapper.selectByExampleWithBLOBs(example); if (list != null && list.size() > 0) { itemParamItem = list.get(0); } //寫入快取 try { redisDao.set(key, JsonUtils.objectToJson(itemParamItem)); redisDao.expire(key, REDIS_ITEM_EXPIRE); } catch (Exception e) { e.printStackTrace(); } return TaotaoResult.ok(itemParamItem); } }

Controller層

  • 建立ItemController,提供根據id訪問基本資訊、描述、引數的介面,返回包含它們的json。
@Controller
@RequestMapping("/item")
public class ItemController {

    @Autowired
    private ItemService itemService;

    @RequestMapping("/base/{itemId}")
    @ResponseBody
    public TaotaoResult getItemBaseInfo(@PathVariable Long itemId) {
        TaotaoResult result = itemService.getItemBaseInfo(itemId);
        return result;
    }

    @RequestMapping("/desc/{itemId}")
    @ResponseBody
    public TaotaoResult getItemDesc(@PathVariable Long itemId) {
        TaotaoResult result = itemService.getItemDesc(itemId);
        return result;
    }

    @RequestMapping("/param/{itemId}")
    @ResponseBody
    public TaotaoResult getItemParam(@PathVariable Long itemId) {
        TaotaoResult result = itemService.getItemParam(itemId);
        return result;
    }

}

呼叫服務展示商品資訊

需求

分析

  • 搜尋商品之後,點選連結,可展示商品詳情頁面,初始時包含商品基本資訊。
    9.searchresult.png
  • item.jsp中,基本資訊直接由jsp載入。
    9.base.png
  • 商品描述和引數由ajax載入。
    • 商品引數通過繫結點選事件,按需載入。
    • 商品描述是用定時器,延時1s載入。
      9.paramdesc.png
      9.paramdescadd.png

總結

  • 在taotao-portal中開發。
  • 商品基本資訊:
    • 請求url:/item/{itemId}
    • 請求引數:商品id
    • 響應引數:商品詳情頁檢視item.jsp,包含商品基本資訊。
  • 商品描述:
    • 請求url:/item/desc/{itemId}
    • 請求引數:商品id
    • 響應引數:商品描述字串。
  • 商品基本資訊:
    • 請求url:/item/param/{itemId}
    • 請求引數:商品id
    • 響應引數:商品引數字串(包含html片段)。

Service層

  • rest.properties中配置服務層需要呼叫的url。
#商品基本資訊url
ITEM_BASE_URL=/item/base/
#商品描述url
ITEM_DESC_URL=/item/desc/
#商品引數url
ITEM_PARAM_URL=/item/param/
  • 建立ItemService和對應實現類,根據商品id,呼叫rest服務,組織資料返回商品資訊、描述、引數。
@Service
public class ItemServiceImpl implements ItemService {

    @Value("${REST_BASE_URL}")
    private String REST_BASE_URL;
    @Value("${ITEM_BASE_URL}")
    private String ITEM_BASE_URL;
    @Value("${ITEM_DESC_URL}")
    private String ITEM_DESC_URL;
    @Value("${ITEM_PARAM_URL}")
    private String ITEM_PARAM_URL;

    @Override
    public Item getItemBase(long itemId) {
        try {
            String json = HttpClientUtil.doGet(REST_BASE_URL + ITEM_BASE_URL + itemId);
            if (!StringUtils.isBlank(json)) {
                TaotaoResult taotaoResult = TaotaoResult.formatToPojo(json, TbItem.class);
                if (taotaoResult.getStatus() == 200) {
                    TbItem tbItem = (TbItem) taotaoResult.getData();

                    Item item = new Item();
                    item.setImage(tbItem.getImage());
                    item.setId(String.valueOf(tbItem.getId()));
                    item.setPrice(tbItem.getPrice());
                    item.setSellPoint(tbItem.getSellPoint());
                    item.setTitle(tbItem.getTitle());

                    return item;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

    @Override
    public String getItemDesc(Long itemId) {
        try {
            String json = HttpClientUtil.doGet(REST_BASE_URL + ITEM_DESC_URL + itemId);
            if (!StringUtils.isBlank(json)) {
                TaotaoResult taotaoResult = TaotaoResult.formatToPojo(json, TbItemDesc.class);
                if (taotaoResult.getStatus() == 200) {
                    TbItemDesc itemDesc = (TbItemDesc) taotaoResult.getData();
                    String desc = itemDesc.getItemDesc();
                    return desc;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    @Override
    public String getItemParam(Long itemId) {
        try {
            String json = HttpClientUtil.doGet(REST_BASE_URL + ITEM_PARAM_URL + itemId);
            if (!StringUtils.isBlank(json)) {
                TaotaoResult taotaoResult = TaotaoResult.formatToPojo(json, TbItemParamItem.class);
                if (taotaoResult.getStatus() == 200) {
                    TbItemParamItem itemParamItem = (TbItemParamItem) taotaoResult.getData();
                    String paramData = itemParamItem.getParamData();

                    //生成html
                    List<Map> jsonList = JsonUtils.jsonToList(paramData, Map.class);
                    StringBuffer sb = new StringBuffer();
                    sb.append(
                            "<table cellpadding=\"0\" cellspacing=\"1\" width=\"100%\" border=\"0\" class=\"Ptable\">\n");
                    sb.append("    <tbody>\n");
                    for (Map m1 : jsonList) {
                        sb.append("        <tr>\n");
                        sb.append("            <th class=\"tdTitle\" colspan=\"2\">" + m1.get("group") + "</th>\n");
                        sb.append("        </tr>\n");
                        List<Map> list2 = (List<Map>) m1.get("params");
                        for (Map m2 : list2) {
                            sb.append("        <tr>\n");
                            sb.append("            <td class=\"tdTitle\">" + m2.get("k") + "</td>\n");
                            sb.append("            <td>" + m2.get("v") + "</td>\n");
                            sb.append("        </tr>\n");
                        }
                    }
                    sb.append("    </tbody>\n");
                    sb.append("</table>");
                    //返回html片段
                    return sb.toString();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";

    }
}

Controller層

  • 建立ItemController,在item檢視中賦予商品基本資訊的物件,並提供描述和引數的查詢介面。
@Controller
@RequestMapping("/item")
public class ItemController {

    @Autowired
    private ItemService itemService;

    @RequestMapping("/{itemId}")
    public String showItem(@PathVariable Long itemId, Model model) {
        Item item = itemService.getItemBase(itemId);
        model.addAttribute("item", item);
        return "item";
    }

    @RequestMapping(value = "/desc/{itemId}", produces = MediaType.TEXT_HTML_VALUE + ";charset=utf-8")
    @ResponseBody
    public String getItemDesc(@PathVariable Long itemId) {
        String string = itemService.getItemDesc(itemId);
        return string;
    }

    @RequestMapping(value = "/param/{itemId}", produces = MediaType.TEXT_HTML_VALUE + ";charset=utf-8")
    @ResponseBody
    public String getItemParam(@PathVariable Long itemId) {
        String string = itemService.getItemParam(itemId);
        return string;
    }
}

執行工程

  • 啟動portal,rest,search,solr,nginx,從搜尋結果點選商品連結。
  • 商品基本資訊。
    9.itembase.png
  • 商品描述。
    9.itemdesc.png
  • 商品引數。
    9.param.png