溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java中SpringMVC的使用方法

發(fā)布時間:2021-10-11 09:08:38 來源:億速云 閱讀:112 作者:柒染 欄目:開發(fā)技術(shù)

今天就跟大家聊聊有關(guān)Java中SpringMVC的使用方法,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

目錄
  • 設(shè)計Restful接口

  • SpringMVC

    • 項目整合SpringMVC

  • 使用SpringMVC實現(xiàn)Restful接口

    • 邏輯交互

      • 身份認證

      • 計時面板

    • 總結(jié)

      設(shè)計Restful接口

      根據(jù)需求設(shè)計前端交互流程。

      三個職位:

      • 產(chǎn)品:解讀用戶需求,搞出需求文檔

      • 前端:不同平臺的頁面展示

      • 后端:存儲、展示、處理數(shù)據(jù)

      前端頁面流程:

      Java中SpringMVC的使用方法

      詳情頁流程邏輯:

      Java中SpringMVC的使用方法

      標準系統(tǒng)時間從服務(wù)器獲取。

      Restful:一種優(yōu)雅的URI表述方式、資源的狀態(tài)和狀態(tài)轉(zhuǎn)移。

      Restful規(guī)范:

      • GET 查詢操作

      • POST 添加/修改操作(非冪等)

      • PUT 修改操作(冪等,沒有太嚴格區(qū)分)

      • DELETE 刪除操作

      URL設(shè)計:

      /模塊/資源/{標示}/集合/...
      /user/{uid}/friends -> 好友列表
      /user/{uid}/followers -> 關(guān)注者列表

      秒殺API的URL設(shè)計

      GET /seckill/list 秒殺列表
      GET /seckill/{id}/detail 詳情頁
      GET /seckill/time/now 系統(tǒng)時間
      POST /seckill/{id}/exposer 暴露秒殺
      POST /seckill/{id}/{md5}/execution 執(zhí)行秒殺

      下一步就是如何實現(xiàn)這些URL接口。

      SpringMVC

      理論

      Java中SpringMVC的使用方法

      適配器模式(Adapter Pattern),把一個類的接口變換成客戶端所期待的另一種接口, Adapter模式使原本因接口不匹配(或者不兼容)而無法在一起工作的兩個類能夠在一起工作。

      SpringMVC的handlerController,HttpRequestHandler,Servlet等)有多種實現(xiàn)方式,例如繼承Controller的,基于注解控制器方式的,HttpRequestHandler方式的。由于實現(xiàn)方式不一樣,調(diào)用方式就不確定了。

      看HandlerAdapter接口有三個方法:

      // 判斷該適配器是否支持這個HandlerMethod
      boolean supports(Object handler);
      // 用來執(zhí)行控制器處理函數(shù),獲取ModelAndView 。就是根據(jù)該適配器調(diào)用規(guī)則執(zhí)行handler方法。
      ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
      long getLastModified(HttpServletRequest request, Object handler);

      問流程如上圖,用戶訪問一個請求,首先經(jīng)過DispatcherServlet轉(zhuǎn)發(fā)。利用HandlerMapping得到想要的HandlerExecutionChain(里面包含handler和一堆攔截器)。然后利用handler,得到HandlerAdapter,遍歷所有注入的HandlerAdapter,依次使用supports方法尋找適合這個handler的適配器子類。最后通過這個獲取的適配器子類運用handle方法調(diào)用控制器函數(shù),返回ModelAndView。

      注解映射技巧

      • 支持標準的URL

      • ?和*和**等字符,如/usr/*/creation會匹配/usr/AAA/creation和/usr/BBB/creation等。/usr/**/creation會匹配/usr/creation和/usr/AAA/BBB/creation等URL。帶{xxx}占位符的URL。

      • 如/usr/{userid}匹配/usr/123、/usr/abc等URL.

      請求方法細節(jié)處理

      • 請求參數(shù)綁定

      • 請求方式限制

      • 請求轉(zhuǎn)發(fā)和重定向

      • 數(shù)據(jù)模型賦值

      • 返回json數(shù)據(jù)

      • cookie訪問

      Java中SpringMVC的使用方法

      返回json數(shù)據(jù)

      Java中SpringMVC的使用方法

      cookie訪問:

      Java中SpringMVC的使用方法

      項目整合SpringMVC

      web.xml下配置springmvc需要加載的配置文件:

      <!--?xml version="1.0" encoding="UTF-8"?-->
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://xmlns.jcp.org/xml/ns/javaee
                            http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1" metadata-complete="true">
        <!--修改servlet版本為3.1-->
         <!--配置DispatcherServlet-->
        <servlet>
          <servlet-name>seckill-dispatcher</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <!--配置springmvc需要加載的配置文件
              spring-dao.xml spring-service.xml spring-web.xml-->
          <!--整合:mybatis -> spring -> springmvc-->
          <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/spring-*.xml</param-value>
          </init-param>
        </servlet>
        <servlet-mapping>
          <servlet-name>seckill-dispatcher</servlet-name>
          <url-pattern>/</url-pattern>
        </servlet-mapping>
      </web-app>

      在resources文件夾下的spring文件夾添加spring-web.xml文件:

      <!--?xml version="1.0" encoding="UTF-8"?-->
      <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemalocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
      <!--配置springmvc-->
          <!--1. 開啟springmvc注解模式-->
          <!-- 簡化配置,
              自動注冊handlermapping,handleradapter
              默認提供了一系列功能:數(shù)據(jù)綁定,數(shù)字和日期的format,xml和json的讀寫支持
           -->
          <mvc:annotation-driven>
            <!--servlet-mapping 映射路徑:"/"-->
          <!--2. 靜態(tài)資源默認servlet配置
              靜態(tài)資源處理:js,gif,png..
              允許使用/做整體映射
          -->
          <mvc:default-servlet-handler>
           <!--3. jsp的顯示viewResolver-->
          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <property name="viewClass" value="org.springframework.web.servlet.view.JstlView">
              <property name="prefix" value="/WEB-INF/jsp">
              <property name="suffix" value=".jsp">
          </property></property></property></bean>
           <!--4. 掃描web相關(guān)的bean-->
          <context:component-scan base-package="cn.orzlinux.web">
      </context:component-scan></mvc:default-servlet-handler></mvc:annotation-driven></beans>

      使用SpringMVC實現(xiàn)Restful接口

      新建文件:

      Java中SpringMVC的使用方法

      首先是SeckillResult.java,這個保存controller的返回結(jié)果,做一個封裝。

      // 所有ajax請求返回類型,封裝json結(jié)果
      public class SeckillResult<t> {
          private boolean success; //是否執(zhí)行成功
          private T data; // 攜帶數(shù)據(jù)
          private String error; // 錯誤信息
          // getter setter contructor
      }

      在Seckillcontroller.java中,實現(xiàn)了我們之前定義的幾個URL:

      GET /seckill/list 秒殺列表
      GET /seckill/{id}/detail 詳情頁
      GET /seckill/time/now 系統(tǒng)時間
      POST /seckill/{id}/exposer 暴露秒殺
      POST /seckill/{id}/{md5}/execution 執(zhí)行秒殺

      具體代碼如下:

      @Controller // @Service @Component放入spring容器
      @RequestMapping("/seckill") // url:模塊/資源/{id}/細分
      public class SeckillController {
          private final Logger logger = LoggerFactory.getLogger(this.getClass());
          @Autowired
          private SecKillService secKillService;
          @RequestMapping(value = "/list",method = RequestMethod.GET)
          public String list(Model model) {
              // list.jsp + model = modelandview
              List<seckill> list = secKillService.getSecKillList();
              model.addAttribute("list",list);
              return "list";
          }
           @RequestMapping(value = "/{seckillId}/detail", method = RequestMethod.GET)
          public String detail(@PathVariable("seckillId") Long seckillId, Model model) {
              if (seckillId == null) {
                  // 0. 不存在就重定向到list
                  // 1. 重定向訪問服務(wù)器兩次
                  // 2. 重定向可以重定義到任意資源路徑。
                  // 3. 重定向會產(chǎn)生一個新的request,不能共享request域信息與請求參數(shù)
                  return "redrict:/seckill/list";
               }
              SecKill secKill = secKillService.getById(seckillId);
              if (secKill == null) {
                  // 0. 為了展示效果用forward
                  // 1. 轉(zhuǎn)發(fā)只訪問服務(wù)器一次。
                  // 2. 轉(zhuǎn)發(fā)只能轉(zhuǎn)發(fā)到自己的web應(yīng)用內(nèi)
                  // 3. 轉(zhuǎn)發(fā)相當(dāng)于服務(wù)器跳轉(zhuǎn),相當(dāng)于方法調(diào)用,在執(zhí)行當(dāng)前文件的過程中轉(zhuǎn)向執(zhí)行目標文件,
                  //      兩個文件(當(dāng)前文件和目標文件)屬于同一次請求,前后頁 共用一個request,可以通
                  //      過此來傳遞一些數(shù)據(jù)或者session信息
                  return "forward:/seckill/list";
              }
              model.addAttribute("seckill",secKill);
              return "detail";
          }
           // ajax json
          @RequestMapping(value = "/{seckillId}/exposer",
                  method = RequestMethod.POST,
                  produces = {"application/json;charset=UTF8"})
          @ResponseBody
          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<>(false,e.getMessage());
              }
              return result;
          }
           @RequestMapping(value = "/{seckillId}/{md5}/execution",
              method = RequestMethod.POST,
              produces = {"application/json;charset=UTF8"})
          public SeckillResult<seckillexecution> execute(
                  @PathVariable("seckillId") Long seckillId,
                  // required = false表示cookie邏輯由我們程序處理,springmvc不要報錯
                  @CookieValue(value = "killPhone",required = false) Long userPhone,
                  @PathVariable("md5") String md5) {
              if (userPhone == null) {
                  return new SeckillResult<seckillexecution>(false, "未注冊");
              }
              SeckillResult<seckillexecution> result;
              try {
                  SeckillExecution execution = secKillService.executeSeckill(seckillId, userPhone, md5);
                  result = new SeckillResult<seckillexecution>(true, execution);
                  return result;
              } catch (SeckillCloseException e) { // 秒殺關(guān)閉
                  SeckillExecution execution = new SeckillExecution(seckillId, SecKillStatEnum.END);
                  return new SeckillResult<seckillexecution>(false,execution);
              } catch (RepeatKillException e) { // 重復(fù)秒殺
                  SeckillExecution execution = new SeckillExecution(seckillId, SecKillStatEnum.REPEAT_KILL);
                  return new SeckillResult<seckillexecution>(false,execution);
              } catch (Exception e) {
                  // 不是重復(fù)秒殺或秒殺結(jié)束,就返回內(nèi)部錯誤
                  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)
          @ResponseBody
          public SeckillResult<long> time() {
              Date now = new Date();
              return new SeckillResult<long>(true,now.getTime());
          }
      }

      頁面

      Java中SpringMVC的使用方法

      這里修改數(shù)據(jù)庫為合適的時間來測試我們的代碼。

      點擊后跳轉(zhuǎn)到詳情頁。

      Java中SpringMVC的使用方法

      詳情頁涉及到比較多的交互邏輯,如cookie,秒殺成功失敗等等。放到邏輯交互一節(jié)來說。

      運行時發(fā)現(xiàn)jackson版本出現(xiàn)問題,pom.xml修改為:

      <dependency>
        <groupid>com.fasterxml.jackson.core</groupid>
        <artifactid>jackson-databind</artifactid>
        <version>2.10.2</version>
      </dependency>

      list.jsp代碼為:

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <%--引入jstl--%>
      <%--標簽通用頭,寫在一個具體文件,直接靜態(tài)包含--%>
      <%@include file="common/tag.jsp"%>
       
           <title>Bootstrap 模板</title>
          <%--靜態(tài)包含:會合并過來放到這,和當(dāng)前文件一起作為整個輸出--%>
          <%@include file="common/head.jsp"%>
       
          <%--頁面顯示部分--%>
          <div class="container">
              <div class="panel panel-default">
                  <div class="panel panel-heading text-center">
                      <h2>秒殺列表</h2>
                  </div>
                  <div class="panel-body">
                      <c:foreach var="sk" items="${list}">
                                  </c:foreach><table class="table table-hover">
                          <thead>
                              <tr>
                                  <th>名稱</th>
                                  <th>庫存</th>
                                  <th>開始時間</th>
                                  <th>結(jié)束時間</th>
                                  <th>創(chuàng)建時間</th>
                                  <th>詳情頁</th>
                              </tr>
                          </thead>
                          <tbody>
                              <tr>
                                      <td>${sk.name}</td>
                                      <td>${sk.number}</td>
                                      <td>
                                          <fmt:formatdate value="${sk.startTime}" pattern="yyyy-MM-dd HH:mm:ss">
                                      </fmt:formatdate></td>
                                      <td>
                                          <fmt:formatdate value="${sk.endTime}" pattern="yyyy-MM-dd HH:mm:ss">
                                      </fmt:formatdate></td>
                                      <td>
                                          <fmt:formatdate value="${sk.createTime}" pattern="yyyy-MM-dd HH:mm:ss">
                                      </fmt:formatdate></td>
                                      <td>
                                          <a class="btn btn-info" href="/seckill/${sk.seckillId}/detail" target="_blank">
                                              link
                                          </a>
                                      </td>
                                  </tr>
                           </tbody>
                      </table>
                  </div>
              </div>
          </div>
       <!-- jQuery (Bootstrap 的 JavaScript 插件需要引入 jQuery) -->
      <script src="https://code.jquery.com/jquery.js"></script>
      <!-- 包括所有已編譯的插件 -->
      <script src="js/bootstrap.min.js"></script>

      Java中SpringMVC的使用方法

      邏輯交互

      身份認證

      cookie中沒有手機號要彈窗,手機號不正確(11位數(shù)字)要提示錯誤:

      Java中SpringMVC的使用方法

      選擇提交之后要能夠在cookie中看到:

      Java中SpringMVC的使用方法

      目前為止detail.jsp:

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
       
           <title>秒殺詳情頁</title>
          <%--靜態(tài)包含:會合并過來放到這,和當(dāng)前文件一起作為整個輸出--%>
          <%@include file="common/head.jsp"%>
          <link href="https://cdn.bootcdn.net/ajax/libs/jquery-countdown/2.1.0/css/jquery.countdown.css" rel="stylesheet">
       
          <%--<input type="hidden" id="basePath" value="${basePath}">--%>
          <div class="container">
              <div class="panel panel-default text-center">
                  <h2>
                      <div class="panel-heading">${seckill.name}</div>
                  </h2>
               </div>
              <div class="panel-body">
                  <h3 class="text-danger">
                      <!-- 顯示time圖標 -->
                      <span class="glyphicon glyphicon-time"></span>
                      <!-- 展示倒計時 -->
                      <span class="glyphicon" id="seckillBox"></span>
                  </h3>
              </div>
          </div>
          <!-- 登錄彈出層,輸入電話 bootstrap里面的-->
          <div id="killPhoneModal" class="modal fade bs-example-modal-lg">
              <div class="modal-dialog">
                  <div class="modal-content">
                      <div class="modal-header">
                          <h4 class="modal-title text-center">
                              <span class="glyphicon glyphicon-phone"></span>秒殺電話:
                          </h4>
                      </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="填手機號^O^" class="form-control">
                              </div>
                          </div>
                      </div>
                      <div class="modal-footer">
                          <span id="killphoneMessage" class="glyphicon"></span>
                          <button type="button" id="killPhoneBtn" class="btn btn-success">
                              <span class="glyphicon glyphicon-phone"></span> Submit
                          </button>
                      </div>
                  </div>
              </div>
          </div>
       
          <!-- jQuery文件。務(wù)必在bootstrap.min.js 之前引入 -->
          <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
          <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
          <script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
          <!-- jQuery cookie操作插件 -->
          <script src="//cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
          <!-- jQery countDonw倒計時插件  -->
          <script src="//cdn.bootcss.com/jquery.countdown/2.1.0/jquery.countdown.min.js"></script>
       <%--開始寫交互邏輯--%>
      <script src="/resources/script/seckill.js" type="text/javascript"></script>
      <script type="text/javascript">
          $(function () {
              seckill.detail.init({
                  seckillId: ${seckill.seckillId},
                  startTime: ${seckill.startTime.time}, // 轉(zhuǎn)化為毫秒,方便比較
                  endTime: ${seckill.endTime.time},
              });
          });
      </script>

      我們的邏輯主要寫在另外的js文件中:

      seckill.js

      // 存放主要交互邏輯js
      // javascript 模塊化
      var seckill={
          // 封裝秒殺相關(guān)ajax的URL
          URL:{
           },
          // 驗證手機號
          validatePhone: function (phone) {
              if(phone && phone.length==11 && !isNaN(phone)) {
                  return true;
              } else {
                  return false;
              }
          },
          // 詳情頁秒殺邏輯
          detail: {
              // 詳情頁初始化
              init: function (params) {
                  // 手機驗證和登錄,計時交互
                  // 規(guī)劃交互流程
                  // 在cookie中查找手機號
                  var killPhone = $.cookie('killPhone');
                  var startTime = params['startTime'];
                  var endTime = params['endTime'];
                  var seckillId = params['seckillId'];
                  // 驗證手機號
                  if(!seckill.validatePhone(killPhone)) {
                      // 綁定手機號,獲取彈窗輸入手機號的div id
                      var killPhoneModal = $('#killPhoneModal');
                      killPhoneModal.modal({
                          show: true, //顯示彈出層
                          backdrop: 'static',//禁止位置關(guān)閉
                          keyboard: false, //關(guān)閉鍵盤事件
                      });
                      $('#killPhoneBtn').click(function () {
                          var inputPhone = $('#killphoneKey').val();
                          // 輸入格式什么的ok了就刷新頁面
                          if(seckill.validatePhone(inputPhone)) {
                              // 將電話寫入cookie
                              $.cookie('killPhone',inputPhone,{expires:7,path:'/seckill'});
                              window.location.reload();
                          } else {
                              // 更好的方式是把字符串寫入字典再用
                              $('#killphoneMessage').hide().html('<label class="label label-danger">手機號格式錯誤</label>').show(500);
                          }
                      });
                  }
                  // 已經(jīng)登錄
               }
          }
      }

      計時面板

      在登錄完成后,處理計時操作:

      // 已經(jīng)登錄
      // 計時交互
      $.get(seckill.URL.now(),{},function (result) {
          if(result && result['success']) {
              var nowTime = result['data'];
              // 寫到函數(shù)里處理
              seckill.countdown(seckillId,nowTime,startTime,endTime);
          } else {
              console.log('result: '+result);
          }
      });

      在countdown函數(shù)里,有三個判斷,未開始、已經(jīng)開始、結(jié)束。

      URL:{
          now: function () {
              return '/seckill/time/now';
          }
      },
       handleSeckill: function () {
          // 處理秒殺邏輯
      },
       countdown: function (seckillId,nowTime,startTime,endTime) {
          var seckillBox = $('#seckillBox');
          if(nowTime>endTime) {
              seckillBox.html('秒殺結(jié)束!');
          } else  if(nowTime<starttime) {="" 秒殺未開始,計時="" var="" killtime="new" date(starttime="" +="" 1000);="" seckillbox.countdown(killtime,function="" (event)="" 控制時間格式="" format="event.strftime('秒殺開始倒計時:%D天" %h時="" %m分="" %s秒');="" seckillbox.html(format);="" 時間完成后回調(diào)事件="" }).on('finish.countdown',="" function="" ()="" 獲取秒殺地址,控制顯示邏輯,執(zhí)行秒殺="" seckill.handleseckill();="" })="" }="" else="" 秒殺開始="" },="" ```="" 總體就是一個顯示操作,用了jquery的countdown倒計時插件。="" <img="" src="https://gitee.com/hqinglau/img/raw/master/img/20211006194407.png" alt="image-20211006194407145" >
       ### 秒殺交互
       
       秒殺之前:
       ![image-20211006202253376](https://img-blog.csdnimg.cn/img_convert/7609c513cb3b64f4e710d879e57c1651.png)
       詳情頁:
       <img src="https://gitee.com/hqinglau/img/raw/master/img/20211006201149.png" alt="image-20211006201149488" >
       點擊開始秒殺:
       <img src="https://gitee.com/hqinglau/img/raw/master/img/20211006202320.png" alt="image-20211006202320137" >
       列表頁刷新:
       ![image-20211006202306300](https://img-blog.csdnimg.cn/img_convert/272dac0d7f6d4a2910614551f4580aac.png)
       
       運行時發(fā)現(xiàn)controller忘了寫`@ResponseBody`了,這里返回的不是jsp是json,需要加上。
       ```java
      @ResponseBody
      public SeckillResult<seckillexecution> execute(
              @PathVariable("seckillId") Long seckillId,
              // required = false表示cookie邏輯由我們程序處理,springmvc不要報錯
              @CookieValue(value = "killPhone",required = false) Long userPhone,
              @PathVariable("md5") String md5)

      在seckill.js中,補全秒殺邏輯:

      // 封裝秒殺相關(guān)ajax的URL
      URL:{
          now: function () {
              return '/seckill/time/now';
          },
          exposer: function(seckillId) {
              return '/seckill/'+seckillId+'/exposer';
          },
           execution: function (seckillId,md5) {
              return '/seckill/'+seckillId+'/'+md5+'/execution';
          }
      },
       
      // id和顯示計時的那個模塊
      handleSeckill: function (seckillId,node) {
          // 處理秒殺邏輯
          // 在計時的地方顯示一個秒殺按鈕
          node.hide()
              .html('<button class="btn btn-primary btn-lg" id="killBtn">開始秒殺</button>');
          // 獲取秒殺地址
          $.post(seckill.URL.exposer(),{seckillId},function (result) {
              if(result && result['success']) {
                  var exposer = result['data'];
                  if(exposer['exposed']) {
                      // 如果開啟了秒殺
                      // 獲取秒殺地址
                      var md5 = exposer['md5'];
                      var killUrl = seckill.URL.execution(seckillId,md5);
                      console.log("killurl: "+killUrl);
                     // click永遠綁定,one只綁定一次
                      $('#killBtn').one('click',function () {
                          // 執(zhí)行秒殺請求操作
                          // 先禁用按鈕
                          $(this).addClass('disabled');
                          // 發(fā)送秒殺請求
                          $.post(killUrl,{},function (result) {
                              if(result) {
                                   var killResult = result['data'];
                                  var state = killResult['state'];
                                  var stateInfo = killResult['stateInfo'];
                                  // 顯示秒殺結(jié)果
                                  if(result['success']) {
                                      node.html('<span class="label label-success">'+stateInfo+'</span>');
                                  } else {
                                      node.html('<span class="label label-danger">'+stateInfo+'</span>');
                                  }
       
                              }
                              console.log(result);
                          })
                      });
                      node.show();
                  } else {
                      // 未開始秒殺,這里是因為本機顯示時間和服務(wù)器時間不一致
                      // 可能瀏覽器認為開始了,服務(wù)器其實還沒開始
                      var now = exposer['now'];
                      var start = exposer['start'];
                      var end = exposer['end'];
                      // 重新進入倒計時邏輯
                      seckill.countdown(seckillId,now,start,end);
                  }
              } else {
                  console.log('result='+result);
              }
          })
      },

      秒殺成功后再次進行秒殺則不成功:

      Java中SpringMVC的使用方法

      輸出:

      Java中SpringMVC的使用方法

      在庫存不夠時也返回秒殺結(jié)束:

      Java中SpringMVC的使用方法

      Java中SpringMVC的使用方法

      至此,功能方面已經(jīng)實現(xiàn)了,后面還剩下優(yōu)化部分。

      看完上述內(nèi)容,你們對Java中SpringMVC的使用方法有進一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

      向AI問一下細節(jié)

      免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

      AI