• Java高并发秒杀API之web层1


    4.交换逻辑编程

    ----4.1 cookies登陆交互-------------------------------------------------

    注意:js的文件夹不能放在WEB-INF下,否则访问不到

    参照:jsp文件引入js文件的方式(项目部署于web容器中)http://www.cnblogs.com/tomspapaya/p/3502563.html

        webapp-

      resources-script/sekill.js

      WEB-INF-

        jsp/common

         detail.jsp

      引入地址为<script src="/seckill/resources/script/seckill.js" type="text/javascript"></script>

    URL:------------------------------------------------------------------------------------------

    Eclipse中,seckill启动时地址就是http://localhost:8080/seckill/为index.jsp

      @Controller

          @RequestMapping("/seckill")

           public class SeckillController {

    去掉@RequestMapping("/seckill"):list页面为http://localhost:8080/seckill/list

    添加@RequestMapping("/seckill"):地址会变为http://localhost:8080/seckill/seckill/list

     SecController.java:
    package org.seckill.web;
    
    import java.util.Date;
    import java.util.List;
    
    import org.seckill.dto.Exposer;
    import org.seckill.dto.SeckillExecution;
    import org.seckill.dto.SeckillResult;
    import org.seckill.entity.Seckill;
    import org.seckill.enums.SeckillStatEnum;
    import org.seckill.exception.RepeatKillExeception;
    import org.seckill.exception.SeckillCloseException;
    import org.seckill.service.SeckillService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.CookieValue;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller//類似@Service @component 
    //@RequestMapping("/seckill")
    //url:/模塊/資源/{id}/細分 http://localhost:8080/seckill/seckill/list
    //去掉@RequestMapping("/seckill")变为http://localhost:8080/seckill/list
    public class SeckillController {
        
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
        
        @Autowired
        private SeckillService seckillService;
        
        @RequestMapping(value="/list",method = RequestMethod.GET)
        //二級URL
        public String list(Model model){
            //獲取列表頁
            List<Seckill> list = seckillService.getSeckillList();
            model.addAttribute("list",list);
            //list.jsp + model = ModelAndView
            return "list";//spring-web.xml配置了prefix和suffix ->WEB-INF/jsp/list.jsp
            
        }
        
        //
        @RequestMapping(value = "/{seckillId}/detail",method = RequestMethod.GET)
        //也可不写@PathVariable("seckillId"),默认能识别出,但最好还写出
        /*使用基本类型接收数据还是用包装类?
            使用@PathVariable时注意两点:
            1:参数接收类型使用基本类型
            2:不用基本类型时,给defaultValue值
            推荐使用包装类*/
        public String detail(@PathVariable("seckillId")Long seckillId,Model model){
            //null时,redirect到list.jsp
            if(seckillId == null){
                return "redirect:/seckill/list";
            }
            Seckill seckill = seckillService.getById(seckillId);
            if(seckill == null){
                return "forward:/seckill/list";
            }
            model.addAttribute("seckill",seckill);
            return "detail";
        }
        
        /*ajax json   RequestMethod.POST直接输入地址无效
         * @ResponseBody 当springmvc看到@ResponseBody的时候会将SeckillResult<Exposer>返回值封装成json
    
         * produces = {"application/json;charset=UTF-8"}解决json中的数据乱码问题
         * */
        @RequestMapping(value = "/{seckillId}/exposer",
                method = RequestMethod.POST,
                produces = {"application/json;charset=UTF-8"})
        @ResponseBody
        //public void/*TODO*/ exposer(Long seckillId){
        public SeckillResult<Exposer> exposer(Long seckillId){
    
            SeckillResult<Exposer> result;
            try{
                Exposer exposer =seckillService.exportSeckillUrl(seckillId);
                result = new SeckillResult<Exposer>(true,exposer);
            }catch (Exception e){
                logger.error(e.getMessage(),e);
                result = new SeckillResult<Exposer>(false,e.getMessage());
            }
            return result;
        }
        
        @RequestMapping(value = "/{seckillId}/{md5}/execution",
                method = RequestMethod.POST,
                produces = {"application/json;charset=UTF-8"})
        public SeckillResult<SeckillExecution> execute(@PathVariable("seckillId")Long seckillId,
                                                       @PathVariable("md5")String md5,
                                                       @CookieValue(value = "killPhone",required = false)Long phone){
            /*请求的requestpattern中没有这个cookie killPhone时,springMVC 会报错,required = false表示killPhone不是必须,就不会报错,验证逻辑放入程序*/
            //springMVC valid
            if(phone == null){
                return new SeckillResult<SeckillExecution>(false,"未注册");
            }
            SeckillResult<SeckillExecution> result;
            try{
                SeckillExecution execution = seckillService.executeSeckill(seckillId, phone, md5);
                return new SeckillResult<SeckillExecution>(true,execution);
            } catch (SeckillCloseException e) {
                SeckillExecution execution = new SeckillExecution(seckillId,SeckillStatEnum.REPEAT_KILL);
                return new SeckillResult<SeckillExecution>(false,execution);
            } catch (RepeatKillExeception e) {
                SeckillExecution execution = new SeckillExecution(seckillId,SeckillStatEnum.END);
                return new SeckillResult<SeckillExecution>(false,execution);
            }catch (Exception e){
                logger.error(e.getMessage(),e);
                SeckillExecution execution = new SeckillExecution(seckillId,SeckillStatEnum.INNER_ERROR);
                return new SeckillResult<SeckillExecution>(false,execution);
            }
        } 
        @RequestMapping(value = "/time/now",
                    method = RequestMethod.GET)
        public SeckillResult<Long> time(){
            Date now = new Date();
            return new SeckillResult(true,now.getTime());
        }
    
    }

     detail.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!-- 引入jstl -->
    <%@include file="common/tag.jsp" %>
    <!DOCTYPE html>
    <html>
       <head>
          <title>秒杀詳情</title>
        <%@include file="common/head.jsp" %>
       </head>
       <body>
       <!-- 頁面顯示部分 :推荐放入一个div中-->
               <div class="container">
                   <div class="panel panel-default">
                       <div class="panel-heading text-center">
                           <h2>秒杀详情</h2>
                           <div class="panel-heading">${seckill.name}</div>
                       </div>
                       <div class="panel-body">
                        <!-- 开发交互时补全 -->
                            <h2 class="text-danger">
                                <!-- time icon -->
                                <span class="glyphicon glyphicon-time"></span>
                                <!-- time count -->
                                <span class="glyphicon" id="seckill-box"></span>
                            </h2>
                       </div>
                   </div>
               </div>
               <!-- pop layer :in put phone number ,fade 隐藏-->
               <div id="killPhoneModal" class="modal fade">
                   <div class="modal-dialog">
                     <div class="modal-content">
                     <div class="modal-header">
                       <h3 class="modal-title text-center">
                           <span class="glyphicon glyphicon-phone"></span>
                       </h3>
                     </div>
                     <div class="modal-body">
                       <div class="row">
                           <div class="col-xs-8 col-xs-offset-2">
                             <input type="text" name="killPhone" id="killPhoneKey"
                              placeholder="in put phone number" class="form-control">
                           </div>
                       </div>
                     </div>
                     <div class="modal-footer">
                       <!-- 验证信息 -->
                       <span id="killPhoneMessage" jclass="glphicon"></span>
                       <button type="button" id="killPhoneBtn" class="btn btn-success">
                         <span class="glyphicon glyphicon-phone"></span>
                         submit
                       </button>
                       </div>
                     </div>                  
                     </div>
                   </div>
               </div>
       </body> 
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <!-- 使用CDN获取公共js http://www.bootcdn.cn
        使用CDN原因:使用可靠的CDN比发布到项目里更可靠(使用方式搜索 jquery-count ,把script标签复制到页面)
     -->
     <!-- jquery cookie 操作plugin -->
     <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
    <!-- 搜索jquery-count得到 -->
    <!-- jquery countDown 倒计时plugin -->
    <script src="https://cdn.bootcss.com/jquery-countdown/2.0.1/jquery.countdown.min.js"></script>
    <!-- 开始编写交互逻辑
     注意: text="text/javascript"/> 浏览器会不加载 虽然HTML语法是对的,js有特殊性必须写成如下-->
    <script src="/seckill/resources/script/seckill.js" type="text/javascript"></script>
    <script text="text/javascript">
    $(function(){
        console.log("!!!!!!detail.jsp");
        //使用EL表达式传入参数
        seckill.detail.init({
            seckillId : ${seckill.seckillId},
            startTime : ${seckill.startTime.time},//毫秒
            endTime : ${seckill.endTime.time}
        });
    });
    </script>
    </html>
    //存放主要交换逻辑js代码
    //javascript模块化
    //seckill.detail.init(params);
    var seckill={
        //封装秒杀相关ajax的url    
        URL:{
            
        },
        //验证手机号 isNaN(phone)数字验证
        validatePhone:function(phone){
            if(phone && phone.length == 11 && !isNaN(phone)){
                return true;
            } else {
                return false;
            }
        },
        //详情页秒杀逻辑
        detail:{
            
            //详情页初始化
            init:function(params){
                console.log("!!!!!!detail");
                //手机验证和登录,计时交互
                //规划交互流程
                //在cookie中查找手机号
                var killPhone = $.cookie('killPhone');
                var startTime = params['startTime'];
                var endTime = params['endTime'];
                var seckillId = params['seckillId'];
                //验证手机号
                if(!seckill.validatePhone(killPhone)){
                    //绑定phone
                    //控制输出
                    console.log("!!!!!!killPhoneModal");
                    var killPhoneModal = $('#killPhoneModal');
                    //modal bootstrap组件,调用方法显示弹出层
                    killPhoneModal.modal({
                        show:true,//show pop layer
                        backdrop:'static',//禁止位置关闭
                        keyboard:false//关闭键盘事件
                    });
                    $('#killPhoneBtn').click(function(){
                        var inputPhone =$('#killPhoneKey').val();
                        console.log('inputPhone:'+inputPhone);
                        if(seckill.validatePhone(inputPhone)){
                            //电话写入cookie 
                            //  {expires:7,path:'/seckill'}有效期7天,在/seckill路径下有效
                            $.cookie('killPhone',inputPhone,{expires:7,path:'/seckill'});
                            //刷新页面
                            window.location.reload();
                        } else{
                            //1.隐藏节点,2编辑节点,3显示内容
                            $('#killPhoneMessage').hide().html('<laber class="label label-danger">phone number is wrong</laber>').show(300);
                        }
                    });
                    //已经登录
                }
            }
        }
            
    }

    ----4.1 cookies登陆交互-------------------------------------------------

  • 相关阅读:
    pytorch实现BiLSTM+CRF用于NER(命名实体识别)
    pytorch中如何处理RNN输入变长序列padding
    pytorch nn.LSTM()参数详解
    Pytorch的LSTM的理解
    转:pytorch版的bilstm+crf实现sequence label
    【Tensorflow】tf.nn.atrous_conv2d如何实现空洞卷积?膨胀卷积
    iOS iphone5屏幕适配 autosizing
    IOS文件存储小结
    IIS6_IIS7日志文件位置
    xcode中没有autoSizing的设置
  • 原文地址:https://www.cnblogs.com/charles999/p/7215992.html
Copyright © 2020-2023  润新知