惯用技法
目前常用的就是angularjs 和 Vue.js
利用浏览器来缓存我们的页面。
因此我们的页面要保证是纯静态的的页面,和后端的数据的交互都要通过 ajax来获取到数据.
思想:
- 将我们的页面(比如详情页面)上的任何从request等内置对象中获取的操作删除掉 比如 ${}
- 把要从后端获取的数据,在html上设置hidden来存储值。
- 加入一个渲染的js函数,一旦请求了后端,那么就刷新这些hidden变量的值。
- 任何跳转到该详情页面上的链接都不要通过请求后台来进行,就当当前的详情页面是一个静态的资源页面,回到我们当初直接跳转到html的时代
- 直接指定该静态详情页的文件名进行跳转。
所以用我们这个springboot系列的应用来进行改造。
首先呢就是我们的Controller,这个方法要返回json数据,而不是放在model中供页面获取的。
因此返回值要更改下
Controller的修改,方法返回的json包含了Model中数据
/**
* 页面静态化的例子使用
*
* @param model
* @param user
* @param goodsId
* @return
* @throws Exception
*/
@RequestMapping(value = "/detailStatic/{goodsId}")
@ResponseBody
public Result<GoodsDetailVo> detailWithCache(HttpServletRequest request, HttpServletResponse response, User user,
@PathVariable("goodsId") Long goodsId) throws Exception {
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
long startAt = goods.getStartDate().getTime();
long endAt = goods.getEndDate().getTime();
long now = System.currentTimeMillis();
int miaoshaStatus = 0;
int remainSeconds = 0;
if (now < startAt) {// 秒杀还没开始,倒计时
miaoshaStatus = 0;
// 单位是毫秒
remainSeconds = (int) ((startAt - now) / 1000);
} else if (now > endAt) {// 秒杀已经结束
miaoshaStatus = 2;
remainSeconds = -1;
} else {// 秒杀进行中
miaoshaStatus = 1;
remainSeconds = 0;
}
GoodsDetailVo vo = new GoodsDetailVo();
vo.setGoods(goods);
vo.setUser(user);
vo.setRemainSeconds(remainSeconds);
vo.setMiaoshaStatus(miaoshaStatus);
return Result.sucess(vo);
}
商品列表请求方式修改
原来的请求方式:
<td><a th:href="'/goods/to_detailCache/'+${goods.id}">详情</a></td>
修改之后的请求方式: 直接跳转到静态页面
<td><a th:href="'/goods_detail.htm?goodsId='+${goods.id}">详情</a></td>
goods_detail.htm页面改造
- 去掉之前使用 ${} 方式获取 Model中数据的代码,全部使用控件来替代
- 页面上不含有直接从Model中获取数据的代码
- 去掉Thymeleaf引入文件的那个符号 @{}
- 之前凡是从Model中获取数据的地方全部使用ajax请求后台获取之后渲染到控件里面
- 当前页面只使用js来请求后台
<!DOCTYPE HTML>
<html >
<head>
<title>商品详情</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- jquery -->
<script type="text/javascript" src="/js/jquery.min.js"></script>
<!-- bootstrap -->
<link rel="stylesheet" type="text/css" href="/bootstrap/css/bootstrap.min.css" />
<script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
<!-- jquery-validator -->
<script type="text/javascript" src="/jquery-validation/jquery.validate.min.js"></script>
<script type="text/javascript" src="/jquery-validation/localization/messages_zh.min.js"></script>
<!-- layer -->
<script type="text/javascript" src="/layer/layer.js"></script>
<!-- md5.js -->
<script type="text/javascript" src="/js/md5.min.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 colspan="3" id="goodsName"></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>-->
<button class="btn btn-primary btn-block" type="button" id="buyButton">立即秒杀</button>
<input type="hidden" name="goodsId" id="goodsId" />
</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 miaoshaStatus = detail.miaoshaStatus;
var remainSeconds = detail.remainSeconds;
var goods = detail.goods;
var user = detail.user;
if(user){
$("#userTip").hide();
}
$("#goodsName").text(goods.goodsName);
$("#goodsImg").attr("src", goods.goodsImg);
$("#startTime").text(new Date(goods.startDate).format("yyyy-MM-dd hh:mm:ss"));
$("#remainSeconds").val(remainSeconds);
$("#goodsId").val(goods.id);
$("#goodsPrice").text(goods.goodsPrice);
$("#miaoshaPrice").text(goods.miaoshaPrice);
$("#stockCount").text(goods.stockCount);
countDown();
}
$(function(){
//countDown();
getDetail();
});
function getDetail(){
var goodsId = g_getQueryString("goodsId");
$.ajax({
url:"/goods/detailStatic/"+goodsId,
type:"GET",
success:function(data){
if(data.code == 200){
render(data.data);
}else{
layer.msg(data.msg);
}
},
error:function(){
layer.msg("客户端请求有误");
}
});
}
function countDown(){
var remainSeconds = $("#remainSeconds").val();
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){//秒杀进行中
$("#buyButton").attr("disabled", false);
if(timeout){
clearTimeout(timeout);
}
$("#miaoshaTip").html("秒杀进行中");
}else{//秒杀已经结束
$("#buyButton").attr("disabled", true);
$("#miaoshaTip").html("秒杀已经结束");
}
}
</script>
</html>
看看效果