1. 程式人生 > >day76_淘淘商城專案_09_商品詳情頁動態展示實現(jsp+redis) + FreeMarker模板引擎入門 + 商品詳情頁靜態化實現(Win版本的nginx作http伺服器)_匠心筆記

day76_淘淘商城專案_09_商品詳情頁動態展示實現(jsp+redis) + FreeMarker模板引擎入門 + 商品詳情頁靜態化實現(Win版本的nginx作http伺服器)_匠心筆記

淘淘商城專案_09


課程計劃

  • 1、商品詳情頁面展示,動態展示(jsp + redis)
  • 2、使用freemarker實現網頁靜態化(解決高併發)
  • 3、使用ActiveMq同步生成靜態網頁

1、商品詳情頁面展示,動態展示(jsp + redis)


從架構中可以看出商品詳情頁面是一個表現層工程。
建立一個商品詳情頁面展示的Maven工程。

1.1、工程搭建

表現層工程taotao-item-web。打包方式war。可以參考表現層工程taotao-portal-web。
不使用骨架建立該Maven工程,繼承父工程,不在贅圖!

1.1.1、pom檔案

配置對taotao-manager-interface的依賴和修改tomcat埠號。

<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>
  <artifactId>taotao-item-web</artifactId>
  <packaging>war</packaging>
	<dependencies>
		<!-- 配置對taotao-common的依賴 -->
		<dependency>
			<groupId>com.taotao</groupId>
			<artifactId>taotao-common</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<!-- 配置對taotao-manager-interface的依賴:表現層呼叫服務要通過該介面 -->
		<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的依賴 -->
		<!-- dubbo相關 -->
		<dependency>
		    <groupId>com.alibaba</groupId>
		    <artifactId>dubbo</artifactId>
		    <!-- 排除對低版本jar包的依賴 -->
		    <exclusions>
		    	<exclusion>
		    		<artifactId>spring</artifactId>
		    		<groupId>org.springframework</groupId>
		    	</exclusion>
		    	<exclusion>
		    		<artifactId>netty</artifactId>
		    		<groupId>org.jboss.netty</groupId>
		    	</exclusion>
		    </exclusions>
		</dependency>
		<dependency>
		    <groupId>org.apache.zookeeper</groupId>
		    <artifactId>zookeeper</artifactId>
		</dependency>
		<dependency>
		    <groupId>com.github.sgroschupf</groupId>
		    <artifactId>zkclient</artifactId>
		</dependency>
	</dependencies>
    <build>
        <plugins>
            <!-- 配置Tomcat外掛  -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8086</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

1.1.2、框架整合

整合後的框架結構如下圖所示(並匯入靜態頁面):

1.1.3、springmvc.xml

<?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-4.2.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-4.2.xsd">
	<!-- 配置載入屬性檔案 -->
	<context:property-placeholder location="classpath:resource/resource.properties"/>
	
	<!-- 配置包掃描器,掃描所有需要帶@Controller註解的類 -->
	<context:component-scan base-package="com.taotao.item.controller" />
	
	<!-- 配置註解驅動 -->
	<mvc:annotation-driven />
	<!-- 配置檢視解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
	
	<!-- 引用dubbo服務 :需要先引入dubbo的約束-->
	<dubbo:application name="taotao-item-web"/>
	<dubbo:registry protocol="zookeeper" address="192.168.25.128:2181"/>	
	<!-- <dubbo:reference interface="com.taotao.content.service.ContentService" id="contentService" /> -->
</beans>

1.1.4、web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>taotao-item-web</display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	<!-- 配置解決post亂碼的過濾器 -->
	<filter>
		<filter-name>characterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>characterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- 配置springmvc的前端控制器 -->
	<servlet>
		<servlet-name>taotao-item-web</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- contextConfigLocation不是必須的, 如果不配置contextConfigLocation, 
			 springmvc的配置檔案預設在:WEB-INF/servlet的name+"-servlet.xml" -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring/springmvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>taotao-item-web</servlet-name>
		<!-- 攔截(*.html)結尾的請求,實現了網頁的偽靜態化,SEO:搜尋引擎優化-->
		<url-pattern>*.html</url-pattern>
	</servlet-mapping>
</web-app>

1.2、功能分析

在搜尋結果頁面點選商品圖片或者商品標題,展示商品詳情頁面。
在商品搜尋系統中的搜尋結果頁面search.jsp中,修改如下:

請求的url:/item/{itemId}
引數:商品id
返回值:String 邏輯檢視
業務邏輯:
  1、從url中取引數,商品id
  2、根據商品id查詢商品資訊(tb_item)得到一個TbItem物件,但是呢,缺少images屬性,我們可以建立一個pojo繼承TbItem,新增一個getImages()方法,放在在taotao-item-web工程中。由於沒有涉及到網路傳輸,所以該pojo不需要實現序列化介面。
程式碼如下:

/**
 * 增加新屬性images的TbItem
 * @author	chenmingjun
 * @date	2018年11月27日下午1:23:26
 * @version 1.0
 */
public class Item extends TbItem {
	
	public Item() {
		
	}

	public Item(TbItem tbItem) {
		// 由於我們根據商品id查詢到的是TbItem,但是我們需要的是Item
		// 方式一:初始化屬性,將TbItem中的屬性的值設定到Item中的屬性中來
		this.setId(tbItem.getId());
		this.setTitle(tbItem.getTitle());
		this.setSellPoint(tbItem.getSellPoint());
		this.setPrice(tbItem.getPrice());
		this.setNum(tbItem.getNum());
		this.setBarcode(tbItem.getBarcode());
		this.setImage(tbItem.getImage());
		this.setCid(tbItem.getCid());
		this.setStatus(tbItem.getStatus());
		this.setCreated(tbItem.getCreated());
		this.setUpdated(tbItem.getUpdated());
		
		// 方式二:使用工具類,將“原來資料TbItem”中的屬性的值拷貝到“現在資料Item”的屬性中來
		// BeanUtils.copyProperties(tbItem, this);
	}
	
	public String[] getImages() {
		String image2 = this.getImage();
		if (image2 != null && !"".equals(image2)) {
			String[] strings = image2.split(",");
			return strings;
		}
		return null;
	}
}

  3、根據商品id查詢商品描述。
  4、展示到頁面。

1.3、Dao層

  查詢tb_item、tb_item_desc兩個表,都是單表查詢。可以使用逆向工程。

1.4、Service層

1.4.1、分析

在taotao-manager-interface和taotao-manager-service工程中新增介面的方法和實現。
1、根據商品id查詢商品資訊
引數:商品id
返回值:TbItem
2、根據商品id查詢商品描述
引數:商品id
返回值:TbItemDesc

1.4.2、介面定義

taotao-manager-interface工程中定義ItemService.java

	/**
	 * 測試:根據商品id查詢商品資訊
	 * @param itemId
	 * @return
	 */
	TbItem getItemById(Long itemId);
	
	/**
	 * 根據商品id查詢商品描述
	 * @param itemId
	 * @return
	 */
	TbItemDesc getItemDescById(Long itemId);

1.4.3、介面實現

taotao-manager-service工程中ItemServiceImpl.java

	@Override
	public TbItem getItemById(Long itemId) {
		TbItem tbItem = itemMapper.selectByPrimaryKey(itemId);
		return tbItem;
	}

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

1.4.4、釋出服務

在taotao-manager-service工廠中applicationContext-service.xml中釋出服務:

1.5、表現層

1.5.1、分析

表現層呼叫服務層的方法,表現層應當是商品詳情工程taotao-item-web。

1.5.2、引用服務

先在taotao-item-web工程中的pom.xml中配置對taotao-manager-interface的依賴。
再在taotao-item-web工程中的springmvc.xml中引入服務:

1.5.3、Controller

請求的url:/item/{itemId}
引數:商品id
返回值:String 邏輯檢視

/**
 * 商品詳情的Controller
 * @author	chenmingjun
 * @date	2018年11月27日下午2:48:52
 * @version 1.0
 */
@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);
		// 返回邏輯檢視item.jsp
		return "item";
	}
}

以上是通過資料庫查詢得到商品的資料,進行展示,但是一般商品的詳情頁面的訪問的併發量是比較高的,所以為了減輕資料庫的壓力,需要做優化
優化方案就是:新增快取

1.6、向業務邏輯中新增快取

1.6.1、快取新增分析

使用redis做快取。
業務邏輯:
  1、根據商品id到快取中命中。
  2、查到快取,直接返回。
  3、查不到快取,查詢資料庫。
  4、查到資料,把資料放到快取中。
  5、返回資料。
快取中快取熱點資料,為了提高快取的使用率,需要設定快取的有效期一般是一天的時間,可以根據實際情況調整
需要使