zoukankan      html  css  js  c++  java
  • java初探(1)之静态页面化——客户端缓存

    利用服务端缓存技术,将页面和对象缓存在redis中,可以减少时间浪费,内存开销。但在每次请求的过程中,仍然会有大量静态资源的请求和返回。

    使用静态页面技术,页面不必要使用页面交互技术,比如thymeleaf,jsp等。而是写一个纯的html静态页面,然后在页面端通过js的ajax请求,获得数据,并通过配置,将静态页面直接缓存到客户端,等下次请求的时候,如果页面没有发生变化,则可以不用对静态资源进行提交和返回。

    当进入商品列表页面时,详情的点击不在通过controller类来将缓存的html返回,而是直接跳转到商品详情的页面,并给一个商品id的参数

    <td><a th:href="'/goods_detail.htm?goodsId='+${goods.id}">详情</a></td>
    • 商品详情页纯html页面  

    <!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"onclick="doMiaosha()">立即秒杀</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>
    </html>
    View Code

    删去所有与thymeleaf相关的标签,将需要展示变量的地方,设置id属性

    然后提供一个入口函数

    $(function () {
            getDetail();
        });
        
        function getDetail() {
            //获取goodsId
            var goodsId=g_getQueryString("goodsId");
    
            //设置ajax请求,得到数据
            $.ajax({
    
                url:"/goods/detail/"+goodsId,
                type:"GET",
                success:function (data) {
                    if(data.code==0){
                        //展示数据
                    }else{
                        //展示错误信息
                        layer.msg(data.msg);
                    }
                },
                error:function () {
                    //未请求成功信息
                    layer.msg("客户端请求有误")
                }
            });
        }

    修改controller类,向页面发送所需要的数据

    •  

      detail方法

      

    @RequestMapping(value = "/to_detail/{goodsId}")
        @ResponseBody
        public Result<GoodsDetailVo> detail( MiaoshaUser user,
                                            @PathVariable("goodsId") long goodsId){
    
            //得到商品信息
            GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
    
            //得到秒杀的开始时间、结束时间、以及当前时间
            long startAt = goods.getStartDate().getTime();
            long endAt = goods.getEndDate().getTime();
            long now = System.currentTimeMillis();
    
            //设置剩余时间
            int remainSeconds=0;
    
            //设置秒杀状态
            int miaoshaStatus=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.setRemainSeconds(remainSeconds);
            vo.setUser(user);
            vo.setMiaoshaStatus(miaoshaStatus);
    
            //返回页面需要的信息
            return Result.success(vo);
        }

    当入口函数得到数据之后,就可以编写展示数据的js代码,一般这些代码是使用前端框架进行编写的。

    function render(detail) {
            //取到vo传过来的四个属性
    
            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() {
    
            //获取剩余时间
            var remainSeconds = $("#remainSeconds").val();
    
            //定义超时变量
            var timeout;
            if(remainSeconds>0){
                //秒杀还没有开始
                //隐藏秒杀的按钮,展示倒计时提醒
                $("#buyButton").attr("disabled", true);
                $("#miaoshaTip").html("秒杀倒计时:"+remainSeconds+"秒");
    
                //利用setTimeout进行时间控制
                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("秒杀已经结束");
            }
        }

    以上就将详情页静态化了

    • 秒杀的静态化

    点击立即秒杀按钮,将执行doMiaosha()的js代码,又是一个ajax请求,但这次不是跳转到静态页面,而是通过Controller类来做一定的秒杀逻辑,然后返回值,如果秒杀成功,则跳转到静态页面。而静态页面也将静态化。

    function doMiaosha() {
            $.ajax({
                url:"/miaosha/do_miaosha",
                type:"POST",
                data:{
                    goodsId:$("#goodsId").val(),
                },
                success:function(data){
                    if(data.code == 0){
                        window.location.href="/order_detail.htm?orderId="+data.data.id;
                    }else{
                        layer.msg(data.msg);
                    }
                },
                error:function(){
                    layer.msg("客户端请求有误");
                }
            });
        }

    修改controller类的"/miaosha/do_miaosha"请求,将直接返回页面,到现在将结果返回来判断是否跳转到另一个静态页面。

    @RequestMapping(value = "/do_miaosha",method = RequestMethod.POST)
        @ResponseBody
        public Result<OrderInfo> list(Model model, MiaoshaUser user,
                           @RequestParam("goodsId") long goodsId){
    
            model.addAttribute("user",user);
            if(user==null){
                //如果没有获取到user值,报异常
                return Result.error(CodeMsg.SESSION_ERROR);
            }
    
            //判断库存
            GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
            Integer stock= goods.getStockCount();
    
            if(stock<=0){
                model.addAttribute("errmsg", CodeMsg.MIAO_SHA_OVER.getMsg());
                return Result.error(CodeMsg.MIAO_SHA_OVER);
            }
    
            //判断是否已经秒杀到了
            MiaoshaOrder order=orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
    
            if(order!=null){
                return Result.error(CodeMsg.REPEATE_MIAOSHA);
            }
    
            //进行秒杀逻辑
            //减库存,下订单,写入秒杀订单
            OrderInfo orderInfo=miaoshaService.miaosha(user, goods);
    
            return Result.success(orderInfo);
        }

    当秒杀成功,将返回一个订单信息的类,然后将订单id拿到作为参数跳转到订单页面

    当然,订单页面也将是一个纯html的静态页面,并将通过入口函数,得到所有需要的数据。

    • 订单的html页面

    <!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>
        <table class="table" id="goodslist">
            <tr>
                <td>商品名称</td>
                <td colspan="3" id="goodsName"></td>
            </tr>
            <tr>
                <td>商品图片</td>
                <td colspan="2"><img  id="goodsImg" width="200" height="200" /></td>
            </tr>
            <tr>
                <td>订单价格</td>
                <td colspan="2"  id="orderPrice"></td>
            </tr>
            <tr>
                <td>下单时间</td>
                <td id="createDate" colspan="2"></td>
            </tr>
            <tr>
                <td>订单状态</td>
                <td id="orderStatus">
                </td>
                <td>
                    <button class="btn btn-primary btn-block" type="submit" id="payButton">立即支付</button>
                </td>
            </tr>
            <tr>
                <td>收货人</td>
                <td colspan="2">玉皇大帝</td>
            </tr>
            <tr>
                <td>收货地址</td>
                <td colspan="2">天宫一号</td>
            </tr>
        </table>
    </div>
    </body>
    View Code

    入口函数,请求数据的逻辑

     //入口函数
        $(function () {
            getOrderDetail();
        })
    
        function getOrderDetail() {
    
            //一个ajax请求
            var orderId = g_getQueryString("orderId");
            $.ajax({
                url:"/order/detail",
                type:"GET",
                data:{
                    orderId:orderId
                },
                success:function(data){
                    if(data.code == 0){
                        //展示数据
                        render(data.data);
                    }else{
                        layer.msg(data.msg);
                    }
                },
                error:function(){
                    layer.msg("客户端请求有误");
                }
            });
    
        }

    控制器代码

    @Controller
    @RequestMapping("/order")
    public class OrderController {
    
    
        @Autowired
        private OrderService orderService;
    
        @Autowired
        private GoodsService goodsService;
    
        @RequestMapping("/detail")
        @ResponseBody
        public Result<OrderDetailVo> info(Model model, MiaoshaUser user,
                                          @RequestParam("orderId") long orderId){
    
            //判断用户是否存在
            if(user==null){
                return Result.error(CodeMsg.SESSION_ERROR);
            }
    
            //获取order
            OrderInfo order = orderService.getOrderById(orderId);
            if(order==null){
                Result.error(CodeMsg.ORDER_NOT_EXIST);
            }
            //得到订单页面需要的参数
            long goodsId = order.getGoodsId();
            GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
            OrderDetailVo vo = new OrderDetailVo();
            vo.setOrder(order);
            vo.setGoods(goods);
            return Result.success(vo);
    
        }
    
    }

    订单页面内js的数据展示代码

    function render(detail) {
        //获取商品和订单信息
        var goods = detail.goods;
        var order = detail.order;
    
        //对数据进行展示
        $("#goodsName").text(goods.goodsName);
        $("#goodsImg").attr("src", goods.goodsImg);
        $("#orderPrice").text(order.goodsPrice);
        $("#createDate").text(new Date(order.createDate).format("yyyy-MM-dd hh:mm:ss"));
    
        //对订单的状态进行判断
    
        var status = "";
        if(order.status == 0){
            status = "未支付"
        }else if(order.status == 1){
            status = "待发货";
            $("payButton").hide();
        }
        $("#orderStatus").text(status);
    
    }

    到此,页面的静态化就完成了

      

  • 相关阅读:
    redis的发布与订阅机制
    三次握手与四次挥手详解
    super的实例及实现原理
    【node.js】入门篇
    简单理解什么是数据库CDC?(以mysql为例)
    Java小工具类(一)json的K-V转换为Java类属性
    linux系统文件拷贝命令rsync
    linux系统配置常用命令top
    关于ganymed-ssh2版本262和build210的SCPClient类的区别
    阿里巴巴java-数据库开发手册(2020泰山版)
  • 原文地址:https://www.cnblogs.com/lovejune/p/12343705.html
Copyright © 2011-2022 走看看