黑马淘淘商城第九天 商品详情页面展示,动态展示 jsp + redis 、使用freemarker实现网页静态化、ActiveMq同步生成静态网页

1. 课程计划

第九天:

1、商品详情页面展示,动态展示 jsp + redis
2、使用freemarker实现网页静态化
3、ActiveMq同步生成静态网页

2. 商品详情页面展示

创建一个商品详情页面展示的工程。是一个表现层工程。

2.1. 工程搭建

Taotao-item-web。打包方式war。可以参考taotao-portal-web
在这里插入图片描述
2.1.1. Pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.taotao</groupId>
		<artifactId>taotao-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>com.taotao</groupId>
	<artifactId>taotao-item-web</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<dependencies>
		<dependency>
			<groupId>com.taotao</groupId>
			<artifactId>taotao-manager-interface</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
		</dependency>
		<!-- JSP相关 -->
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jsp-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<!-- dubbo相关 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<!-- 排除依赖 -->
			<exclusions>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.jboss.netty</groupId>
					<artifactId>netty</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
		</dependency>
		<dependency>
			<groupId>com.github.sgroschupf</groupId>
			<artifactId>zkclient</artifactId>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
	</dependencies>
	<!-- 配置tomcat插件 -->
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<configuration>
					<port>8086</port>
					<path>/</path>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

淘淘静态页面
在这里插入图片描述

2.2. 功能分析

在搜索结果页面点击商品图片或者商品标题,展示商品详情页面。
在这里插入图片描述
请求的url:/item/{itemId}
参数:商品id
返回值:String 逻辑视图
业务逻辑:
1、从url中取参数,商品id
2、根据商品id查询商品信息(tb_item)得到一个TbItem对象,缺少images属性,可以创建一个pojo继承TbItem,添加一个getImages方法。在taotao-item-web工程中。

public class Item extends TbItem {

	public String[] getImages() {
		String image2 = this.getImage();
		if (image2 != null && !"".equals(image2)) {
			String[] strings = image2.split(",");
			return strings;
		}
		return null;
	}
	
	public Item() {
		
	}
	
	public Item(TbItem tbItem) {
		this.setBarcode(tbItem.getBarcode());
		this.setCid(tbItem.getCid());
		this.setCreated(tbItem.getCreated());
		this.setId(tbItem.getId());
		this.setImage(tbItem.getImage());
		this.setNum(tbItem.getNum());
		this.setPrice(tbItem.getPrice());
		this.setSellPoint(tbItem.getSellPoint());
		this.setStatus(tbItem.getStatus());
		this.setTitle(tbItem.getTitle());
		this.setUpdated(tbItem.getUpdated());
	}
	
}

3、根据商品id查询商品描述。
4、展示到页面。

2.3. Dao层

查询tb_item, tb_item_desc两个表,都是单表查询。可以使用逆向工程。

1、根据商品id查询商品信息
参数:商品id
返回值:TbItem
2、根据商品id查询商品描述
参数:商品id
返回值:TbItemDesc

@Override
	public TbItemDesc getItemDescById(long itemId) {
		TbItemDesc itemDesc = itemDescMapper.selectByPrimaryKey(itemId);
		return itemDesc;
	}

在这里插入图片描述
2.4.1. 发布服务
在这里插入图片描述

2.5. 表现层

2.5.1. 引用服务
在这里插入图片描述
2.5.2. Controller
请求的url:/item/{itemId}
参数:商品id
返回值:String 逻辑视图

@Controller
public class ItemController {

	@Autowired
	private ItemService itemService;
	
	@RequestMapping("/item/{itemId}")
	public String showItemInfo(@PathVariable Long itemId, Model model) {
		//跟据商品id查询商品信息
		TbItem tbItem = itemService.getItemById(itemId);
		//把TbItem转换成Item对象
		Item item = new Item(tbItem);
		//根据商品id查询商品描述
		TbItemDesc tbItemDesc = itemService.getItemDescById(itemId);
		//把数据传递给页面
		model.addAttribute("item", item);
		model.addAttribute("itemDesc", tbItemDesc);
		return "item";
	}
}

2.6. 向业务逻辑中添加缓存

2.6.1. 缓存添加分析
使用redis做缓存。

业务逻辑:
1、根据商品id到缓存中命中
2、查到缓存,直接返回。
3、差不到,查询数据库
4、把数据放到缓存中
5、返回数据

缓存中缓存热点数据,提供缓存的使用率。需要设置缓存的有效期。一般是一天的时间,可以根据实际情况跳转。

需要使用String类型来保存商品数据。
可以加前缀方法对象redis中的key进行归类。
ITEM_INFO:123456:BASE
ITEM_INFO:123456:DESC
在这里插入图片描述
如果把二维表保存到redis中:
1、表名就是第一层
2、主键是第二层
3、字段名第三次
三层使用“:”分隔作为key,value就是字段中的内容。

2.6.2. 把redis相关的jar包添加到工程
在这里插入图片描述
淘淘工具类
在这里插入图片描述
2.6.3. 添加缓存

@Override
	public TbItem getItemById(long itemId) {
		try {
			//查询缓存
			String json = jedisClient.get(ITEM_INFO_PRE + ":" + itemId + ":BASE");
			if (StringUtils.isNotBlank(json)) {
				//把json转换为java对象
				TbItem item = JsonUtils.jsonToPojo(json, TbItem.class);
				return item;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		//根据商品id查询商品信息
		//TbItem tbItem = itemMapper.selectByPrimaryKey(itemId);
		TbItemExample example = new TbItemExample();
		//设置查询条件
		Criteria criteria = example.createCriteria();
		criteria.andIdEqualTo(itemId);
		List<TbItem> list = itemMapper.selectByExample(example);
		if (list != null && list.size() > 0) {
			TbItem item = list.get(0);
			try {
				//把数据保存到缓存
				jedisClient.set(ITEM_INFO_PRE + ":" + itemId + ":BASE", JsonUtils.objectToJson(item));
				//设置缓存的有效期
				jedisClient.expire(ITEM_INFO_PRE + ":" + itemId + ":BASE", ITEM_INFO_EXPIRE);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return item;
		}
		return null;
	}

取商品描述添加缓存:

@Override
	public TbItemDesc getItemDescById(long itemId) {
		try {
			String json = jedisClient.get(ITEM_INFO_PRE + ":" + itemId + ":DESC");
			//判断缓存是否命中
			if (StringUtils.isNotBlank(json) ) {
				//转换为java对象
				TbItemDesc itemDesc = JsonUtils.jsonToPojo(json, TbItemDesc.class);
				return itemDesc;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		TbItemDesc itemDesc = itemDescMapper.selectByPrimaryKey(itemId);
		try {
			jedisClient.set(ITEM_INFO_PRE + ":" + itemId + ":DESC", JsonUtils.objectToJson(itemDesc));
			//设置过期时间
			jedisClient.expire(ITEM_INFO_PRE + ":" + itemId + ":DESC", ITEM_INFO_EXPIRE);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return itemDesc;

在这里插入图片描述

3. 网页静态化

可以使用Freemarker实现网页静态化。

3.1. 什么是freemarker

FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP。它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 等。

目前企业中:主要用Freemarker做静态页面或是页面展示

3.2. Freemarker的使用方法

把freemarker的jar包添加到工程中。
Maven工程添加依赖

<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker</artifactId>
  <version>2.3.23</version>
</dependency>

在这里插入图片描述
使用步骤:
第一步:创建一个Configuration对象,直接new一个对象。构造方法的参数就是freemarker对于的版本号。
第二步:设置模板文件所在的路径。
第三步:设置模板文件使用的字符集。一般就是utf-8.
第四步:加载一个模板,创建一个模板对象。
第五步:创建一个模板使用的数据集,可以是pojo也可以是map。一般是Map。
第六步:创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名。
第七步:调用模板对象的process方法输出文件。
第八步:关闭流。

模板:
${hello}

@Test
	public void genFile() throws Exception {
		// 第一步:创建一个Configuration对象,直接new一个对象。构造方法的参数就是freemarker对于的版本号。
		Configuration configuration = new Configuration(Configuration.getVersion());
		// 第二步:设置模板文件所在的路径。
		configuration.setDirectoryForTemplateLoading(new File("D:/workspaces-itcast/term197/taotao-item-web/src/main/webapp/WEB-INF/ftl"));
		// 第三步:设置模板文件使用的字符集。一般就是utf-8.
		configuration.setDefaultEncoding("utf-8");
		// 第四步:加载一个模板,创建一个模板对象。
		Template template = configuration.getTemplate("hello.ftl");
		// 第五步:创建一个模板使用的数据集,可以是pojo也可以是map。一般是Map。
		Map dataModel = new HashMap<>();
		//向数据集中添加数据
		dataModel.put("hello", "this is my first freemarker test.");
		// 第六步:创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名。
		Writer out = new FileWriter(new File("D:/temp/term197/out/hello.html"));
		// 第七步:调用模板对象的process方法输出文件。
		template.process(dataModel, out);
		// 第八步:关闭流。
		out.close();
	}

3.3. 模板的语法

3.3.1. 访问map中的key
${key}

3.3.2. 访问pojo中的属性
Student对象。学号、姓名、年龄
${key.property}
在这里插入图片描述

3.3.3. 取集合中的数据
<#list studentList as student>
s t u d e n t . i d / {student.id}/ student.id/{studnet.name}
</#list>
在这里插入图片描述
在这里插入图片描述
3.3.4. 取循环中的下标
<#list studentList as student>
${student_index}
</#list>
在这里插入图片描述
3.3.5. 判断
<#if student_index % 2 == 0>
<#else>
</#if>
在这里插入图片描述
3.3.6. 日期类型格式化
在这里插入图片描述
3.3.7. Null值的处理
在这里插入图片描述
3.3.8. Include标签
<#include “模板名称”>
.......................................................................................................................................................................................

3.4. Freemarker整合spring

引入jar包:
Freemarker的jar包
在这里插入图片描述

3.4.1. 创建整合spring的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	<bean id="freemarkerConfig"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
		<property name="defaultEncoding" value="UTF-8" />
	</bean>


</beans>

需要编写一Controller进行测试

3.4.2. Controller
请求的url:/genhtml
参数:无
返回值:ok (String, 需要使用@ResponseBody)
业务逻辑:
1、从spring容器中获得FreeMarkerConfigurer对象。
2、从FreeMarkerConfigurer对象中获得Configuration对象。
3、使用Configuration对象获得Template对象。
4、创建数据集
5、创建输出文件的Writer对象。
6、调用模板对象的process方法,生成文件。
7、关闭流。

加载配置文件:
在这里插入图片描述

@Controller
public class HtmlGenController {
	
	@Autowired
	private FreeMarkerConfigurer freeMarkerConfigurer;

	@RequestMapping("/genhtml")
	@ResponseBody
	public String genHtml()throws Exception {
		// 1、从spring容器中获得FreeMarkerConfigurer对象。
		// 2、从FreeMarkerConfigurer对象中获得Configuration对象。
		Configuration configuration = freeMarkerConfigurer.getConfiguration();
		// 3、使用Configuration对象获得Template对象。
		Template template = configuration.getTemplate("hello.ftl");
		// 4、创建数据集
		Map dataModel = new HashMap<>();
		dataModel.put("hello", "1000");
		// 5、创建输出文件的Writer对象。
		Writer out = new FileWriter(new File("D:/temp/term197/out/spring-freemarker.html"));
		// 6、调用模板对象的process方法,生成文件。
		template.process(dataModel, out);
		// 7、关闭流。
		out.close();
		return "OK";
	}
}

3.5. 商品详情页面静态化

3.5.1. 网页的静态化方案
输出文件的名称:商品id+“.html”
输出文件的路径:工程外部的任意目录。
网页访问:使用nginx访问网页。在此方案下tomcat只有一个作用就是生成静态页面。
工程部署:可以把taotao-item-web部署到多个服务器上。
生成静态页面的时机:商品添加后,生成静态页面。可以使用Activemq,订阅topic(商品添加)

1商品详情页面生成Listener
1:在taotao-item-web中添加activemq的依赖
在这里插入图片描述
2:实现ActiveMQ的监听器MessagerListener
在这里插入图片描述

@Autowired
    private ItemService itemService;
    @Autowired
    private FreeMarkerConfigurer freemarkerConfig;
    @Value("${HTML_OUT_PATH}")
    private String HTML_OUT_PATH;
    @Override
    public void onMessage(Message message) {
        
        try {
            //1.创建一个MessageListener接口的实现类用于监听创建商品的时候发出的消息
            //2.从message中获取商品的id
            TextMessage textMessage=(TextMessage) message;
            String strItemId = textMessage.getText();
            //3.查询商品的基本信息和商品的描述
            TbItem tbItem = itemService.getItemById(Long.parseLong(strItemId));
            TbItemDesc tbItemDesc = itemService.getItemDescById(Long.parseLong(strItemId));
            Item item=new Item(tbItem);
            //4.创建商品详情页面模板
            Map<String,Object> data=new HashMap<String,Object>();
            data.put("item", item);
            data.put("itemDesc", tbItemDesc);
            Configuration configuration = freemarkerConfig.getConfiguration();
            // 根据spring的freemarker的配置文件加载/WEB-INF/ftl/下面的模板页面
            Template template = configuration.getTemplate("item.ftl");
            //5.指出文件输出目录
            Writer out = new FileWriter(new File(HTML_OUT_PATH+strItemId+".html"));
            //6.生成静态文件
            template.process(data, out);
            //7.关闭io流
            out.close();
        } catch (JMSException | IOException | TemplateException e) {
            e.printStackTrace();
        }
    }

3:在taotao-item-web中配置activemq
在这里插入图片描述
为了让该配置文件也被spring加载进去,所以需要在web.xml中修改成:
在这里插入图片描述

<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
	<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://192.168.25.128:61616" />
	</bean>
	<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
	<bean id="connectionFactory"
		class="org.springframework.jms.connection.SingleConnectionFactory">
		<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
		<property name="targetConnectionFactory" ref="targetConnectionFactory" />
	</bean>
	
	<!--这个是主题目的地,一对多的 -->
	<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
		<constructor-arg value="item-change-topic" />
	</bean>
	
	<!-- 接收消息 -->
	<!-- 配置监听器 -->
	<bean id="htmlGenListener" class="com.taotao.item.listener.HtmlGenListener" />
	<!-- 消息监听容器 -->
	<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="topicDestination" />
		<property name="messageListener" ref="htmlGenListener" />
	</bean>

4:在resource.properties
在这里插入图片描述
14.把jsp改造为freemarker模板.avi
A: 修改已经存在的jsp为ftl模板页面
将jsp文件夹下面的页面拷贝到ftl下面,然后修改后缀名
在这里插入图片描述
注意:
1.去掉jsp有关语句<%@…%>
2.将jsp中的循环语句和条件语句转换成freemarker<#list><#if>
在这里插入图片描述
在这里插入图片描述
3.处理空值
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值