查看京东和天猫,发现主流电商的商品详情页都是独立的域名展示。
因为商品数量大,访问的频率很高,需要单独把商品详情分离出来,方便对商品详情功能进行扩容(增加集群数量)。
我们搭建表现层taotao-item-web即可,调用taotao-manager的服务,获取商品数据。
注意:参照taotao-portal加入配置文件
springmvc.xml
web.xml
taotao-item-web
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
encoding
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
encoding
/*
taotao-portal
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring/springmvc.xml
1
taotao-portal
*.html
package com.taotao.item.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.taotao.manager.pojo.Item;
import com.taotao.manager.pojo.ItemDesc;
import com.taotao.manager.service.ItemDescService;
import com.taotao.manager.service.ItemService;
/**
* 商品详情表现层
* @author Administrator
*
*/
@Controller
@RequestMapping("item")
public class ItemController {
@Autowired
private ItemService itemService;
@Autowired
private ItemDescService itemDescService;
@RequestMapping(value="{itemId}", method=RequestMethod.GET)
public String toItem(Model model, @PathVariable Long itemId){
//使用商品服务查询商品
Item item = this.itemService.queryById(itemId);
ItemDesc itemDesc = this.itemDescService.queryById(itemId);
//封装查询数据
model.addAttribute("item", item);
model.addAttribute("itemDesc", itemDesc);
//返回结果视图
return "item";
}
}
商品详情页是消费者了解商品的主要途径,访问的频率非常高。所以需要对商品详情页进行优化,以提高访问的速度。
(1)、使用redis添加缓存
redis的访问速度快,能够较大的提升查询数据的速度,减轻MySQL数据库的访问压力。如果使用缓存的方式,需要注意数据同步的问题
(2)、使用静态化
把动态页面(jsp,php,asp等),转变成静态页面(html)
(1)、访问静态页面不需要经过程序处理,可以提高速度。(处理速度,和数据库访问速度)
(2)、稳定性高。
(3)、从安全角度讲,静态网页不易遭到黑客攻击。
(4)、静态页面相对于动态页面更容易被搜索引擎收录。(SEO)
freemarker是java语言开发
freemarker是一个模板引擎,可以基于模板生成文本(html)
freemarker和应用服务器(Tomcat、jetty)是没有关联的,不需要使用jsp和servlet技术
freemarker除了前端页面展示的功能外,还可以生成xml,java
企业一般用freemarker做生成静态页面功能
freemarker文档地址
package cn.itcast.freemaker.test;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class FreemakerTest {
public static void main(String[] args) throws Exception {
// 1.创建freemaker的核心对象
Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
// 2.给核心对象设置模版所在位置
System.out.println(System.getProperty("user.dir"));
cfg.setDirectoryForTemplateLoading(new File(System.getProperty("user.dir") + "/src/ftl"));
// 3.使用核心对象获取模版对象,参数就是模版的名称
// 官方要求模版必须是ftl类型,但是实际上任何后缀名都可以,只要保证内容是字符串即可
Template template = cfg.getTemplate("test.html");
// 4.创建数据模型,使用的是Map
Map root = new HashMap();
root.put("value", "world");
// 5.声明输出的Writer对象
Writer out = new FileWriter(new File("H:/fremaker/result.html"));
// 6.使用模版输出静态页面,需要两个参数,一个参数是模型数据,另一个是输出的Writer对象
template.process(root, out);
}
}
(1)、测试类代码
(2)、模版代码
(3)、测试效果
(1)、测试类代码
(2)、模版代码
(3)、测试效果
(1)、测试类代码
(2)、模版代码
(3)、测试效果
(1)、测试类代码
(2)、模版代码
(3)、测试效果
(1)、测试类代码
(2)、模版代码
(3)、测试效果
(1)、测试类代码
(2)、模版代码
(3)、测试效果
(1)、模版代码
(2)、测试效果
(1)、item.jsp的改造
a、删除jsp的声明头信息
b、将jsp的include标签替换为freemarker的include标签
(2)、将所有的模版中jsp信息全部改为freemarker的标签
footer.jsp
item.ftl
package com.taotao.item.message;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.taotao.manager.pojo.Item;
import com.taotao.manager.pojo.ItemDesc;
import com.taotao.manager.service.ItemDescService;
import com.taotao.manager.service.ItemService;
import freemarker.template.Configuration;
import freemarker.template.Template;
/**
* 静态化页面的监听类
* @author Administrator
*
*/
public class ItemMessageListener implements MessageListener {
private static final ObjectMapper MAPPER = new ObjectMapper();
@Override
public void onMessage(Message message) {
// 判断消息类型是否是TextMessage
if (message instanceof TextMessage) {
// 是,进行强转
TextMessage textMessage = (TextMessage) message;
try {
// 获取消息
String json = textMessage.getText();
if (StringUtils.isNotBlank(json)) {
// 解析json
JsonNode jsonNode = MAPPER.readTree(json);
// 获取操作符type
String type = jsonNode.get("type").asText();
// 获取商品id
long itemId = jsonNode.get("itemId").asLong();
// 进行消息的消费
if ("save".equals(type)) {
this.getHtml(itemId);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;
@Autowired
private ItemService itemService;
@Autowired
private ItemDescService itemDescService;
/**
* 根据商品id进行静态化处理
*
* @param itemId
* @throws Exception
*/
private void getHtml(long itemId) throws Exception {
// 获取freemarker的核心对象
Configuration cfg = this.freeMarkerConfigurer.getConfiguration();
// 使用核心对象获取模版
Template template = cfg.getTemplate("item.ftl");
// 准备模版数据
Map root = new HashMap();
// 获取商品基础数据
Item item = this.itemService.queryById(itemId);
ItemDesc itemDesc = this.itemDescService.queryById(itemId);
root.put("item", item);
root.put("itemDesc", itemDesc);
// 声明Writer输出对象
Writer out = new FileWriter(new File("H:/fremaker/item/" + itemId + ".html"));
// 使用模版输出静态页
template.process(root, out);
}
}