复习电商笔记-41-商品详情页

 

商品详情页

访问的链接:item.jd.com/商品ID.html

模拟它,我们的链接:www.jt.com/item/商品ID.html

 

 

查询商品数据

后台系统提供接口,利用httpclient方式。

 

 

获取商品详情

返回值问题:采用SysResult。原因:可以通过状态判断是否调用正常,如果200成功,才去获取数据,否则抛出异常。如果只按返回结果为空来判断,那很多特殊情况我们就无从判别。例如:按ID去查询,ID就不存在,返回为空,当做没有查询到记录,这显示是不合理的。这也就是为什么专门去构造一个SysResult对象。接口返回调用的状态、信息等内容。

注意:

可以引入后台系统中的Item对象,也可以在前台系统中创建新的pojo。使用哪种方式呢?依赖后台会加进很多class,所以重新创建的好。而且后台的pojo的JTA注解都可以去掉。

com.jt.web.pojo.Item

package com.jt.web.pojo;

import java.util.Date;

import com.fasterxml.jackson.annotation.JsonIgnore;

public class Item {

    private Long id;

    private String title;

    private String sellPoint;

    private Long price;

    private Integer num;

    private String barcode;

    private String image;

    private Long cid;

    private Integer status;

    private Date created;

    private Date updated;

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public Date getUpdated() {
        return updated;
    }

    public void setUpdated(Date updated) {
 this.updated = updated;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getSellPoint() {
        return sellPoint;
    }

    public void setSellPoint(String sellPoint) {
        this.sellPoint = sellPoint;
    }

    public Long getPrice() {
        return price;
    }

    public void setPrice(Long price) {
        this.price = price;
    }

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }

    public String getBarcode() {
        return barcode;
    }

    public void setBarcode(String barcode) {
        this.barcode = barcode;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
  this.image = image;
    }

    public Long getCid() {
        return cid;
    }

    public void setCid(Long cid) {
        this.cid = cid;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    @JsonIgnore	//json序列化时将java bean中的一些属性忽略掉
    public String[] getImages() {
        if (null != getImage()) {
            return getImage().split(",");
        }
        return null;
    }

    @Override
    public String toString() {
        return "Item [id=" + id + ", title=" + title + ", sellPoint=" + sellPoint + ", price=" + price
                + ", num=" + num + ", barcode=" + barcode + ", image=" + image + ", cid=" + cid + ", status="
                + status + ", created=" + getCreated() + ", updated=" + getUpdated() + "]";
    }

}

注意:重点在于image存放了多张图片,链接之间用逗号隔开,增加getImages方法来查分获取image数组。

在com.jt.manage.controller.ItemController增加查询方法。

  /**
     * 通过id查询商品数据
     * 
     * @param id
     * @return
     */
    @RequestMapping("query/{id}")
    @ResponseBody
    public SysResult queryList(@PathVariable("id") Long id) {
        try {
            Item item = this.itemService.queryById(id);
            if (item != null && item.getId() != null) {
                return SysResult.ok(item);
     }
        } catch (Exception e) {
            e.printStackTrace();
            return SysResult.build(202, "查询失败! id = " + id);
        }
        return SysResult.build(201, "查询不到商品数据 id = " + id);
    }

com.jt.web.service.ItemService

  public Item queryItemById(Long itemId) {
        // 数据从后台管理系统中获取,通过Httpclient获取
        String url = MANAGE_URL + "/item/query/" + itemId;
        Item item = null;
        try {
            String jsonData = this.httpClientService.doGet(url);
            SysResult sysResult = SysResult.formatToPojo(jsonData, Item.class);
            item = (Item) sysResult.getData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return item;
    }

com.jt.web.controller.ItemController

package com.jt.web.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.jt.manage.pojo.Item;
import com.jt.manage.pojo.ItemDesc;
import com.jt.web.service.ItemService;

@RequestMapping("item")
@Controller
public class ItemController {

    @Autowired
    private ItemService itemService;

    @RequestMapping("{itemId}")
    public ModelAndView showItem(@PathVariable("itemId") Long itemId) {
        ModelAndView mv = new ModelAndView("item");
        // 查询商品信息
        Item item = this.itemService.queryItemById(itemId);
        mv.addObject("item", item);
        
        return mv;
    }

}

 

 

标题显示商品标题

item.jsp

<title>${item.title} - 京淘</title>

 

 

商品价格

使用JSTL标签进行格式化:

groupingUsed是否千位符, Digits保留几位小数

¥<fmt:formatNumber groupingUsed="false" maxFractionDigits="2" minFractionDigits="2" value="${item.price / 100 }"/>

 

 

通过EL表达式展示商品属性

<div class="dt">商品编号:</div><div class="dd">
<span>${item.id }</span>
</div>
……
<div class="detail-content">
	${itemDesc.itemDesc }
</div>

 

 

显示商品规格参数数据

com.jt.web.controller.ItemController

package com.jt.web.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.jt.manage.pojo.ItemDesc;
import com.jt.web.pojo.Item;
import com.jt.web.service.ItemService;

@RequestMapping("item")
@Controller
public class ItemController {

    @Autowired
    private ItemService itemService;

    @RequestMapping("{itemId}")
    public ModelAndView showItem(@PathVariable("itemId") Long itemId) {
  ModelAndView mv = new ModelAndView("item");
        // 查询商品信息
        Item item = this.itemService.queryItemById(itemId);
        mv.addObject("item", item);
        
        //加载商品描述信息
        ItemDesc itemDesc = this.itemService.queryItemDescByItemId(itemId);
        mv.addObject("itemDesc", itemDesc);
        
        // 加载商品规格参数
        String itemParam = this.itemService.queryItemParamItemByItemId(itemId);
        mv.addObject("itemParam", itemParam);
        
        return mv;
    }
    
}

com.jt.web.service.ItemService

package com.jt.web.service;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.jt.common.service.RedisService;
import com.jt.common.spring.exetend.PropertyConfig;
import com.jt.common.vo.SysResult;
import com.jt.manage.pojo.ItemDesc;
import com.jt.manage.pojo.ItemParamItem;
import com.jt.web.pojo.Item;

@Service
public class ItemService {

    @Autowired
    private ApiService apiService;

    @PropertyConfig
    private String MANAGE_URL;

    @Autowired
    private RedisService redisService;

    private static final ObjectMapper MAPPER = new ObjectMapper();

    private static final String REDIS_ITEM_KEY = "URL_WEB_ITEM_";

    private static final String REDIS_ITEM_DESC_KEY = "URL_WEB_ITEM_DESC_";
    private static final String REDIS_ITEM_PARAM_ITEM_KEY = "URL_WEB_ITEM_PARAM_ITEM_";

    public Item queryItemById(Long itemId) {
        String key = REDIS_ITEM_KEY + itemId;
        // 从缓存中命中
        try {
            String redisData = this.redisService.get(key);
            if (StringUtils.isNoneEmpty(redisData)) {
                return MAPPER.readValue(redisData, Item.class);
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        // 数据从后台管理系统中获取,通过Httpclient获取
        String url = MANAGE_URL + "/item/query/" + itemId;
        Item item = null;
        try {
            String jsonData = this.apiService.doGet(url);
            SysResult sysResult = SysResult.formatToPojo(jsonData, Item.class);
            item = (Item) sysResult.getData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (null != item) {
            // 写入到缓存中
            try {
                this.redisService.set(key, MAPPER.writeValueAsString(item),
                        60 * 60 * 24 * 10);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return item;
    }

    public ItemDesc queryItemDescByItemId(Long itemId) {
        String key = REDIS_ITEM_DESC_KEY + itemId;
        // 从缓存中命中
        try {
            String redisData = this.redisService.get(key);
            if (StringUtils.isNoneEmpty(redisData)) {
                return MAPPER.readValue(redisData, ItemDesc.class);
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        String url = MANAGE_URL + "/item/query/item/desc/" + itemId;
        ItemDesc itemDesc = null;
        try {
            String jsonData = this.apiService.doGet(url);
            SysResult sysResult = SysResult.formatToPojo(jsonData, ItemDesc.class);
    itemDesc = (ItemDesc) sysResult.getData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (null != itemDesc) {
            // 写入到缓存中
            try {
                this.redisService.set(key, MAPPER.writeValueAsString(itemDesc),
                        60 * 60 * 24 * 10);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return itemDesc;
    }

    /**
     * 加载商品规格参数
     * 
     * @param itemId
     * @return
     */
    public String queryItemParamItemByItemId(Long itemId) {
        String key = REDIS_ITEM_PARAM_ITEM_KEY + itemId;
        // 从缓存中命中
        try {
            String redisData = this.redisService.get(key);
            if (StringUtils.isNoneEmpty(redisData)) {
                return redisData;
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        String url = MANAGE_URL + "/item/param/item/query/" + itemId;
        String strResult = null;
        try {
            String jsonData = this.apiService.doGet(url);
            SysResult sysResult = SysResult.formatToPojo(jsonData, ItemParamItem.class);
            ItemParamItem itemParamItem = (ItemParamItem) sysResult.getData();
            String paramData = itemParamItem.getParamData();
            ArrayNode arrayNode = (ArrayNode) MAPPER.readTree(paramData);
            StringBuilder sb = new StringBuilder();
            sb.append("<table cellpadding=\"0\" cellspacing=\"1\" width=\"100%\" border=\"0\" class=\"Ptable\"><tbody>");

            for (JsonNode jsonNode : arrayNode) {
                sb.append("<tr><th class=\"tdTitle\" colspan=\"2\">" + jsonNode.get("group").asText()
                        + "</th></tr><tr>");
                ArrayNode params = (ArrayNode) jsonNode.get("params");
                for (JsonNode param : params) {
   sb.append("<tr><td class=\"tdTitle\">" + param.get("k").asText() + "</td><td>"
                            + param.get("v").asText() + "</td></tr>");
                }
            }
            sb.append("</tbody></table>");
            strResult = sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (null != strResult) {
            // 写入到缓存中
            try {
                this.redisService.set(key, strResult, 60 * 60 * 24 * 30);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return strResult;
    }

    public void updateRedis(Long itemId) {
        this.redisService.del(REDIS_ITEM_KEY + itemId);
        this.redisService.del(REDIS_ITEM_DESC_KEY + itemId);
        this.redisService.del(REDIS_ITEM_PARAM_ITEM_KEY + itemId);
    }

}

上面这种方式是在类中拼接html代码,这样做不是很好,如果格式变化,就需要修改类重新发布。那也可以在jsp页面循环,也有问题,在jsp页面解析json比较麻烦。当然也可以用js来解析json。它也有问题,如果使用js来生成,那搜索引擎是抓不到这动态生成的内容的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值