惯用技法
目前常用的就是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>
修改之后的请求方式: 直接跳转到静态页面
扫描二维码关注公众号,回复:
1033762 查看本文章
<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>
看看效果