页面静态化:

页面是存为html,动态的数据是通过接口来从服务端进行获取的。所以服务端只需要写接口。

极大的节省网络流量,提高响应速度。这种技术越来越流行,越来越多的公司开始使用这种技术。页面静态化,就是前后端分离。前端技术越来越多,越来越火的比如angularjs,vue.js

本次静态化利用的是浏览器的缓存。

一、首先在static文件夹下新建文件goods_detail.htm, 后缀名变了,为了防止thymeleaf的默认查找*.html格式的文件

二、更改goods_list.html中的部分代码:因为跳转的时候不再通过服务端来进行了,而是通过客户端来进行的。

<td><a th:href="'/goods_detail.htm?goodsId=' + ${goods.id}">详情</a></td>

需要取url中的参数。往商品详情跳转的时候传了一个参数:goodsId

三、取url中的参数

需要在goods_detail.htm中的ajax方法中用到这个参数的值,那么怎样取出来呢?需要写js代码(在common.js中),引入common.js即可。

common.js:
//根据参数名获取url参数
function getQueryString(name) {
 var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
 var r = window.location.search.substr(1).match(reg);
 if (r != null) return unescape(r[2]); return null;
}
//设定时间格式化函数,使用new Date().format("yyyyMMddhhmmss");  
Date.prototype.format = function (format) {  
    var args = {  
        "M+": this.getMonth() + 1,  
        "d+": this.getDate(),  
        "h+": this.getHours(),  
        "m+": this.getMinutes(),  
        "s+": this.getSeconds(),  
    };  
    if (/(y+)/.test(format))  
        format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));  
    for (var i in args) {  
        var n = args[i];  
        if (new RegExp("(" + i + ")").test(format))  
            format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? n : ("00" + n).substr(("" + n).length));  
    }  
    return format;  };

四、定义类GoodsDetailVo(作为从后端向前端传递数据的载体)

package com.mydre.miaosha.vo;
import com.mydre.miaosha.domain.MiaoshaUser;
public class GoodsDetailVo {
 private GoodsVo goodsVo;
 private int remainSeconds = 0;
 private int miaoshaStatus = 0; private MiaoshaUser miaoshaUser;

六、goods_detail.htm

<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></meta>
<title>商品列表</title>
<!-- jquery -->
<!-- 这里 / 代表 的是static文件夹,这是thymeleaf引入静态文件的方式。 -->
<script type="text/javascript" src="/js/jquery.min.js"></script>
<!-- bootstrap -->
<link rel="stylesheet" type="text/css" href="/bootstrap/css/bootstrap.min.css"></link>
<script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
<!-- jquery-validation -->
<script type="text/javascript" src="/jquery-validation/jquery.validate.min.js"></script>
<script type="text/javascript" src="/jquery-validation/localization/messages_zh.js"></script>
<!-- layer -->
<script type="text/javascript" src="/layer/layer.js"></script>
<!-- common.js -->
<script type="text/javascript" src="/js/common.js"></script>
</head>
<body>
<div class="panel panel-default">
 <div class="panel-heading">秒杀商品详情</div>
 <div class="panel-body">
 <span id="userTip">您还没有登录,请登录后再操作<br/></span>
 <span>没有收货地址的提示。。。</span>
 </div>
 <table class="table" id="goodslist">
 <tr>
 <td>商品名称</td>
 <td id="goodsName" colspan="3"></td>
 </tr>
 <tr>
 <td>商品图片</td>
 <td colspan="3"><img id="goodsImg" width="200" height="200"/></td>
 </tr>
 <tr>
 <td>秒杀开始时间</td>
 <td id="startTime"></td>
 <td>
 <input type="hidden" id="remainSeconds"/>
 <span id="miaoshaTip"></span>
 </td>
 <td>
 <form id="miaoshaForm" method="post" action="/miaosha/do_miaosha">
 <button class="btn btn-primary btn-block" type="submit" id="buyButton">立即秒杀</button>
 <input type="hidden" name="goodsId" id="goodsId"/>
 </form>
 </td>
 </tr>
 <tr>
 <td>商品原价</td>
 <td colspan="3" id="goodsPrice"></td>
 </tr>
 <tr>
 <td>秒杀价</td>
 <td colspan="3" id="miaoshaPrice"></td>
 </tr>
 <tr>
 <td>库存数量</td>
 <td colspan="3" id="stockCount"></td>
 </tr>
 </table>
</div>
</body>
<script>
function render(detail){
 var goodsVo = detail.goodsVo;
 var remainSeconds = detail.remainSeconds;
 var miaoshaStatus = detail.miaoshaStatus;
 var miaoshaUser = detail.miaoshaUser;
 //拿到服务端数据以后,即可以填充对象了
 if(miaoshaUser){
 $("#userTip").hide();
 }
 $("#remainSeconds").val(remainSeconds);
 $("#goodsImg").attr("src", goodsVo.goodsImg);
 $("#startTime").text(new Date(goodsVo.startDate).format("yyyy-MM-dd hh:mm:ss"));
 $("#goodsPrice").text(goodsVo.goodsPrice);
 $("#miaoshaPrice").text(goodsVo.miaoshaPrice);
 $("#stockCount").text(goodsVo.stockCount);
 
 $("#goodsId").val(goodsVo.id);
 countDown();
}
$(function(){
 //countDown();
 getDetail();
});
function getDetail(){
 var goodsId = getQueryString('goodsId');
 $.ajax({
 url: '/goods/detail/' + goodsId,
 type: 'GET',
 success:function(data){//成功的时候会有一个回调,data是返回的数据,该数据应该是一个对象类型,或字典类型
 if(data.code == 0){
 render(data.data);//这里需要一个渲染页面的函数 render
 }else{
 layer.msg(data);
 }
 },
 error:function(){
 layer.msg('客户端请求有误');
 }
 });
}
function countDown(){
 var remainSeconds = $("#remainSeconds").val();//javascript中的变量不能和小于0的值相比
 var timeout;
 if(remainSeconds > 0){//秒杀还未开始
 $("#buyButton").attr("disabled", true);
 $("#miaoshaTip").html("秒杀倒计时:"+ remainSeconds +"秒");
 timeout = setTimeout(function(){
 $("#countDown").text(remainSeconds - 1);
 $("#remainSeconds").val(remainSeconds - 1);
 countDown();
 },1000); 
 }else if(remainSeconds == 0){//秒杀正在进行
 if(timeout){
 clearTimeout(timeout);
 }
 $("#miaoshaTip").html("秒杀正在进行");
 $("#buyButton").attr("disabled", false);
 }else{//秒杀已经结束
 $("#buyButton").attr("disabled", true);
 $("#miaoshaTip").html("秒杀已经结束");
 }
}
</script></html>
七、GoodsController
 @RequestMapping(value="/detail/{goodsId}")//路由是这样写的 {goodsId}
 @ResponseBody
    public Result<GoodsDetailVo> detail(MiaoshaUser user, @PathVariable("goodsId")long goodsId) {
 //数据的存取是根据内部的逻辑来的,但是页面的缓存是根据key来的,一个goodsId可以标记一个缓存。
 GoodsVo oneGoodsVo = goodsService.getOneGoodsVoById(goodsId);
 long startAt = oneGoodsVo.getStartDate().getTime();
 long endAt = oneGoodsVo.getEndDate().getTime();
 long current = System.currentTimeMillis();
 int remainSeconds = 0;
 int miaoshaStatus = 0;//0未开始 1正在进行 2已结束
 if(current < startAt){//秒杀还未开始
 miaoshaStatus = 0;
 remainSeconds = (int)((startAt - current)/1000);
 }else if(current > endAt){//秒杀已经结束
 miaoshaStatus = 2;
 remainSeconds = -1;
 }else{//秒杀正在进行
 miaoshaStatus = 1;
 remainSeconds = 0;
 }
        //return "goods_detail";
 
 GoodsDetailVo goodsDetailVo = new GoodsDetailVo();
 goodsDetailVo.setGoodsVo(oneGoodsVo);
 goodsDetailVo.setMiaoshaStatus(miaoshaStatus); 
 goodsDetailVo.setRemainSeconds(remainSeconds);
 goodsDetailVo.setMiaoshaUser(user);
 
 return Result.success(goodsDetailVo);//对应ajax请求成功时回调函数success中的data。
 }