最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot如何實現(xiàn)一個實時更新的進(jìn)度條的示例代碼

 更新時間:2020年05月28日 09:09:19   作者:聽風(fēng)聽雨聽世界  
本文詳細(xì)的介紹了SpringBoot如何實現(xiàn)一個實時更新的進(jìn)度條,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

博主近期接到一個任務(wù),大概內(nèi)容是:導(dǎo)入excel表格批量修改狀態(tài),期間如果發(fā)生錯誤則所有數(shù)據(jù)不成功,為了防止重復(fù)提交,做一個類似進(jìn)度條的東東。

那么下面我會結(jié)合實際業(yè)務(wù)對這個功能進(jìn)行分析和記錄。

正文

思路

前端使用bootstrap,后端使用SpringBoot分布式到注冊中心,原先的想法是導(dǎo)入表格后異步調(diào)用修改數(shù)據(jù)狀態(tài)的方法,然后每次計算修改的進(jìn)度然后存放在session中,前臺jquery寫定時任務(wù)訪問獲取session中的進(jìn)度,更新進(jìn)度條進(jìn)度和百分比。但是這存在session在服務(wù)間不共享,跨域問題。那么換一個方式存放,存放在redis中,前臺定時任務(wù)直接操作獲取redis的數(shù)據(jù)。

實施

進(jìn)度條

先來看一下bootstrap的進(jìn)度條

<div class="progress progress-striped active">
  <div class="progress-bar progress-bar-success" role="progressbar"
     aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"
     style="width: 40%;">
    40%
  </div>
</div>

 進(jìn)度條更新主要更新style="width: 40%;"的值即可,div里面的40%可以省略,無非時看著明確。

可以考慮將進(jìn)度條放入彈出層。

定時任務(wù)

//點擊確認(rèn)導(dǎo)入執(zhí)行此方法
function bulkImportChanges() {
  //獲取批量操作狀態(tài)文件
  var files = $("#importChanges").prop("files");
  var changesFile = files[0];
  var formData = new FormData();
  formData.append("importFile",changesFile);
  $.ajax({
    type : 'post',
    url : "/risk/bulk***es",
    data : formData,
    processData : false,   //文件ajax上傳要加這兩個的,要不然上傳不了
    contentType : false,   //
    success : function(obj) {
      //導(dǎo)入成功
      if (obj.rspCode == "00") {
        //定時任務(wù)獲取redis導(dǎo)入修改進(jìn)度
        var progress = "";
        var timingTask = setInterval(function(){
          $.ajax({
            type: 'post',
            url: "/risk/t***k",
            dataType : 'json',
            success: function(result) {
              progress = result.value;
              if (progress != "error"){
                var date = progress.substring(0,6);
                //這里更新進(jìn)度條的進(jìn)度和數(shù)據(jù)
                $(".progress-bar").width(parseFloat(date)+"%");
                $(".progress-bar").text(parseFloat(date)+"%");
              }
            }
          });
          //導(dǎo)入修改完成或異常(停止定時任務(wù))
          if (parseInt(progress)==100 || progress == "error") {
            //清除定時執(zhí)行
            clearInterval(timingTask);
            $.ajax({
              type: 'post',
              url: "/risk/de***ess",
              dataType : 'json',
              success: function(result) {
                $("#bulkImportChangesProcessor").hide();
                if (parseInt(progress) == 100) {
                  alert("批量導(dǎo)入修改狀態(tài)成功");
                }
                if (progress == "error") {
                  alert("批量導(dǎo)入修改狀態(tài)失敗");
                }
                //獲取最新數(shù)據(jù)
                window.location.href="/risk/re***ByParam" rel="external nofollow" rel="external nofollow" ;
              }
            });
          }
        }, 1000)
      }else {
        $("#bulkImportChangesProcessor").hide();
        alert(obj.rspMsg);
        window.location.href="/risk/re***ByParam" rel="external nofollow" rel="external nofollow" ;
      }
    }
  });
}

解釋:點擊確認(rèn)導(dǎo)入文件后成功后開啟定時任務(wù)每一秒(一千毫秒)訪問一次后臺獲取redis存放的進(jìn)度,返回更新進(jìn)度條,如果更新完成或者更新失?。ǜ鶕?jù)后臺返回的數(shù)據(jù)決定)則停止定時任務(wù)顯示相應(yīng)的信息并刷新頁面。獲取最新數(shù)據(jù)。

后臺控制層

/**
 * 退單管理批量修改狀態(tài)導(dǎo)入文件
 * @param importFile
 * @return
 */
 @ResponseBody
 @RequestMapping("/bulk***es")
 public Map<String,Object> bulk***es(MultipartFile importFile){
   log.info("退單管理批量修改狀態(tài)導(dǎo)入文件,傳入?yún)?shù):"+importFile);
 Map<String,Object> map = new HashMap<>();
 List<Bulk***esEntity> fromExcel = null;
 try{
      //使用工具類導(dǎo)入轉(zhuǎn)成list
  String[] header = {"sy***um","t***mt","ha***ult","re***nd","sy***nd","r**k"};
  fromExcel = importExcelUtil.importDataFromExcel(importFile, header, BulkImportChangesEntity.class);
  if (fromExcel.size()==0){
  map.put("rspCode","99");
  map.put("rspMsg","導(dǎo)入數(shù)據(jù)不能為空");
  return map;
  }
 }catch (Exception e){
  map.put("rspCode","99");
  map.put("rspMsg","導(dǎo)入操作表失敗,請注意數(shù)據(jù)列格式");
  return map;
 }
 try {
  //這里會對list集合中的數(shù)據(jù)進(jìn)行處理

  log.info("調(diào)用服務(wù)開始,參數(shù):"+JSON.toJSONString(fromExcel));
  //String url = p4_zuul_url+"/***/ri***eat/bu***nges";
  String url = p4_zuul_url+"/***-surpass/ri***eat/bu***nges";
  String result = HttpClientUtil.doPost(url,JSON.toJSONString(fromExcel));
  log.info("調(diào)用服務(wù)結(jié)束,返回數(shù)據(jù):"+result);
  if (result != null){
  map = JSONObject.parseObject(result, Map.class);
  log.info("批量修改狀態(tài)導(dǎo)入:"+JSON.toJSONString(map));
  }
 }catch (Exception e){
  map.put("rspCode","99");
  map.put("rspMsg","導(dǎo)入操作表失敗");
  log.info("bu***es exception",e);
  return map;
 }
 return map;
 }

 /**
 * 獲取退單管理批量修改狀態(tài)導(dǎo)入文件進(jìn)度條進(jìn)度
 * @return
 */
 @ResponseBody
 @RequestMapping("/t***sk")
 public Map<String,Object> t***sk(){
 Map<String,Object> map = new HashMap<>();
    //獲取redis值
 String progress = HttpClientUtil.doGet(
  p4_zuul_url + "/" + p4_redis + "/redis***ler/get?key=progressSchedule");
 if (progress != null){
  map = JSONObject.parseObject(progress, Map.class);
  log.info("進(jìn)度條進(jìn)度:"+JSON.toJSONString(map));
  map.put("progressSchedule",progress);
 }else {
  HttpClientUtil.doGet(
   p4_zuul_url + "/" + p4_redis + "/redis***ler/del?key=progressSchedule");
 }
 return map;
 }

 /**
 * 清除redis進(jìn)度條進(jìn)度
 * @return
 */
 @ResponseBody
 @RequestMapping("/de***ess")
 public Map<String,Object> de***ess(){
 Map<String,Object> map = new HashMap<>();
 String progress = HttpClientUtil.doGet(
  p4_zuul_url + "/" + p4_redis + "/redis***ler/del?key=progressSchedule");
 if (progress != null){
  map = JSONObject.parseObject(progress, Map.class);
  log.info("返回數(shù)據(jù):"+JSON.toJSONString(map));
 }
 return map;
 }

導(dǎo)入時調(diào)用第一個bulk***es方法,定時任務(wù)調(diào)用t***sk方法,導(dǎo)入完成或發(fā)生錯誤調(diào)用de***ess方法刪除redis數(shù)據(jù),避免占用資源。

服務(wù)層

@Async//開啟異步
 @Transactional(rollbackFor = Exception.class)//事務(wù)回滾級別
 @Override
 public void bulkImportChanges(List<BulkImportChangesParam> list) {
 //初始化進(jìn)度
 Double progressBarSchedule = 0.0;
 redisClient.set("progressSchedule", progressBarSchedule + "");//存redis
 try {
  for (int i = 1; i <= list.size(); i++) {
  RiskRetreatEntity entity = riskRetreatMapper.selectRetreatListBySysRefNum(list.get(i-1).getSysRefNum());
  if (entity == null){
   //查詢結(jié)果為空直接進(jìn)行下次循環(huán)不拋出
   continue;
  }
  //實體封裝
        ···
        //更新
  riskRetreatMapper.updateRetreatByImport(entity);
  //計算修改進(jìn)度并存放redis保存(1.0 / list.size())為一條數(shù)據(jù)進(jìn)度
  progressBarSchedule = (1.0 / list.size()) * i*100;
  redisClient.set("progressSchedule", progressBarSchedule+"");
  if (i==list.size()){
   redisClient.set("progressSchedule", "100");
  }
  }
 }catch (Exception e){
  //當(dāng)發(fā)生錯誤則清除緩存直接拋出回滾
  redisClient.set("progressSchedule","error");
  log.info("導(dǎo)入更新錯誤,回滾");
  log.info("bulkImportChanges exception:",e);
  throw e;
 }
 }

每更新一條數(shù)據(jù)存放進(jìn)度,當(dāng)發(fā)生錯誤則進(jìn)行回滾。如果開啟異步則需要在啟動類添加注解@EnableAsync。

@EnableAsync
···//其他注解
public class Application {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

結(jié)果樣式

結(jié)尾

這次結(jié)合了前端的定時任務(wù),后臺事務(wù)以及異步,總的來說還是一次🙅‍不錯的體驗。

到此這篇關(guān)于SpringBoot如何實現(xiàn)一個實時更新的進(jìn)度條的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot實時更新進(jìn)度條內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 如何通過Magic 魔數(shù)獲取文件類型

    Java 如何通過Magic 魔數(shù)獲取文件類型

    魔數(shù)有很多種定義,這里我們討論的主要是在編程領(lǐng)域的定義,文件的起始幾個字節(jié)的內(nèi)容是固定的,本文給大家介紹Java Magic 魔數(shù)獲取文件類型的相關(guān)知識,感興趣的朋友一起看看吧
    2023-11-11
  • java整合SSM框架的圖文教程

    java整合SSM框架的圖文教程

    下面筆者就為大家分享一篇java整合SSM框架的圖文教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨筆者過來看看吧
    2017-11-11
  • 靈活控制任務(wù)執(zhí)行時間的Cron表達(dá)式范例

    靈活控制任務(wù)執(zhí)行時間的Cron表達(dá)式范例

    這篇文章主要為大家介紹了靈活控制任務(wù)執(zhí)行時間的Cron表達(dá)式范例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • springboot實現(xiàn)對注解的切面案例

    springboot實現(xiàn)對注解的切面案例

    這篇文章主要介紹了springboot實現(xiàn)對注解的切面過程,首先定義一個注解、再編寫對注解的切面只是記錄的執(zhí)行時間和打印方法,可以實現(xiàn)其他邏輯,需要的朋友可以參考一下
    2022-01-01
  • 一文帶你掌握SpringBoot中常見定時任務(wù)的實現(xiàn)

    一文帶你掌握SpringBoot中常見定時任務(wù)的實現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了Spring?Boot中定時任務(wù)的基本用法、高級特性以及最佳實踐,幫助開發(fā)人員更好地理解和應(yīng)用定時任務(wù),提高系統(tǒng)的穩(wěn)定性和可靠性,需要的可以參考下
    2024-03-03
  • JavaWeb監(jiān)聽器Listener實例解析

    JavaWeb監(jiān)聽器Listener實例解析

    這篇文章主要為大家詳細(xì)介紹了JavaWeb監(jiān)聽器Listener實例,針對監(jiān)聽器進(jìn)行進(jìn)行細(xì)致分析,感興趣的小伙伴們可以參考一下
    2016-08-08
  • maven中springboot-maven-plugin的5種打包方式

    maven中springboot-maven-plugin的5種打包方式

    本文主要介紹了maven中springboot-maven-plugin的5種打包方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-09-09
  • 解決使用@RequestParam注解和泛型遇到的問題

    解決使用@RequestParam注解和泛型遇到的問題

    這篇文章主要介紹了解決使用@RequestParam注解和泛型遇到的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java訪問修飾符原理及代碼解析

    Java訪問修飾符原理及代碼解析

    這篇文章主要介紹了Java訪問修飾符原理及代碼解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-06-06
  • java javax.annotation.Resource注解的詳解

    java javax.annotation.Resource注解的詳解

    這篇文章主要介紹了javax.annotation.Resource注解的詳解的相關(guān)資料,需要的朋友可以參考下
    2016-10-10

最新評論

镇赉县| 滕州市| 固安县| 特克斯县| 花莲县| 达州市| 山丹县| 克什克腾旗| 昔阳县| 紫金县| 岳阳市| 钟山县| 台东县| 汉中市| 盐城市| 宜黄县| 辽宁省| 新沂市| 漳州市| 武平县| 凉山| 正镶白旗| 福鼎市| 斗六市| 白河县| 五河县| 灵丘县| 寿阳县| 屯昌县| 新丰县| 庐江县| 黎城县| 株洲县| 澳门| 南雄市| 扎兰屯市| 赤城县| 咸丰县| 北海市| 天津市| 许昌市|