首页 > 其他分享 >springmvc 使用 DeferredResult

springmvc 使用 DeferredResult

时间:2023-08-16 17:58:25浏览次数:50  
标签:异步 请求 quotes springmvc 使用 deferredResult CacheUtils DeferredResult

背景:

需求:

可以实时获取啄木鸟伍迪的访问数据、排名、积分等数据,可以实时现在在网站后台页面的大屏上;

解决方案:

可以使用异步请求,springmvc默认的请求都是同步的,也就是请求过去,必须得有处理完成,否则就回阻塞;异步请求是当发起一个请求,可以暂时没有响应,请求回被挂起不阻塞;请求过去,就返回一个DeferredResult,该DeferredResult可以在其他线程中返回需要的结果,也就是执行DeferredResult.setResult(),此时,异步请求回被唤醒

DeferredResult的流程:

    1. 浏览器发起异步请求
    2. 请求到达服务端被挂起
    3. 向浏览器进行响应,分为两种情况:
      3.1 调用DeferredResult.setResult(),请求被唤醒,返回结果
      3.2 超时,返回一个你设定的结果
    4. 浏览得到响应,再次重复1,处理此次响应结果

如果定时任务去获取啄木鸟伍迪的访问数据、排名、积分等数据,当前定时任务处理完了,就告诉页面有数据了,马上ajax查询最新数据;页面重新执行ajax 的查询数据的函数即可;

官网给的例子:

@GetMapping("/quotes")
@ResponseBody
public DeferredResult<String> quotes() {
    DeferredResult<String> deferredResult = new DeferredResult<>();
    // 返回一个DeferredResult
    return deferredResult;
}

// 其他线程处理结果;
deferredResult.setResult(result);

 

DeferredResult的使用步骤:

1.spring开启异步请求:

需要在web.xml 的filter 和DispatcherServlet 中配置  :<async-supported>true</async-supported>;

配置方式可以参考https://www.cnblogs.com/lixiuming521125/p/17622238.html

 2.添加异步请求

/**
     * 异步请求
     * @return
     */
    @RequestMapping("/quotes")
    @ResponseBody
    public DeferredResult<String> quotes() {
        //设置了1分钟超时
        DeferredResult<String> deferredResult = new DeferredResult<>(60000L);
    //放入缓存中,可全局调用
        CacheUtils.put(CacheUtils.DEFERRED_CACHE_NAME, ShiroUtils.getUsername(),deferredResult);
        return deferredResult;
    }

3.页面的异步请求:

function updateDashboardData(){ //循环发送异步请求;
    //设置了定时器,防止页面崩溃;
  if(!!timeUpdate.quotesTimeout){
    clearTimeoutFun(timeUpdate.quotesTimeout);
  }
 $.ajax({
         type : 'post',
         url : basePath + '/dashboard/quotes',//异步请求
         contentType : "application/json;charset=utf-8",
         success : function(data) {
             if (!!data && data=="update") {
                updateData();//更新数据;
             }
             timeUpdate.quotesTimeout = setTimeout(updateDashboardData, 5000);
         },
         error:function(){
            timeUpdate.quotesTimeout = setTimeout(updateDashboardData, 5000);

         }
     });
}

4.定时任务调用DeferredResult.setResult(),唤起异步请求;(代码片段)

 /**
     * 添加博客园每日数据
     */
    private void processMain() {
        ...........
    .................
                logger.info("[TASK][CnblogDataDayTask].OTHER.DATA.PROCESS.END");
                // 批量添加
                logger.info("[TASK][CnblogDataDayTask].DELETE.DATA.DAY.EXIST");
                addDayList = resultList.stream().filter(s -> s.getAddDay() != null).map(CnblogDataDay::getAddDay)
                    .collect(Collectors.toList());
                cnblogDataDayService.delete(addDayList);
                logger.info("[TASK][CnblogDataDayTask].INSERT.DATA.DAY");
                if(CollectionUtils.isNotEmpty(resultList)){
                    cnblogDataDayService.insert(resultList);
                    // 更新当前处理过的数据的 修改时间
                    logger.info("[TASK][CnblogDataDayTask].UPDATE.PROCESS.DATA");
                    cnblogDataDayService.updateModifyDate(endDate,DateUtils.toDate(syncTime, DateUtils.DATETIME_FORMAT));
                    updateBigScreem();
                }
            }
          .....................
         ..........................
..................................

    }

 

  private void updateBigScreem() {
        List<Object> cacheKeys = CacheUtils.getKeys(CacheUtils.DEFERRED_CACHE_NAME);
        List<String> keys = getContainKey(cacheKeys, ShiroUtils.getUsername());
        for (String key : keys) {
            Object obj = CacheUtils.get(CacheUtils.DEFERRED_CACHE_NAME, key);
            if (obj instanceof DeferredResult) {
                DeferredResult<String> result = (DeferredResult<String>)obj;
                result.setResult("update");
            }
        }
    }

 效果:

当请发起请求以后,执行了异步请求,且等待响应,如果此时执行了定时任务,如果此时执行了定时任务(在1分钟之内),那么该异步请求就处理完成了。

 


标签:异步,请求,quotes,springmvc,使用,deferredResult,CacheUtils,DeferredResult
From: https://www.cnblogs.com/lixiuming521125/p/15722263.html

相关文章

  • 前端vue使用blob下载流文件
    请求后端接口,发现返回的是这么一堆东西 代码:axios:exportfunctionexportEcoCarAppoint(params){returnHttp({url:'/api/jsis/ecoCarAppoint/exportEcoCarAppoint',method:'POST',data:params,responseType:'blob',//设置响应......
  • 在Typora中使用AutoHotkey 2.0实现使用快捷键设置文本颜色
    使用Typora时不能设置文本颜色,总是觉得不方便,于是在网上搜索,发现有个小工具:AutoHotkey,编写脚本后,通过快捷键的方式可以设置Typora的文本颜色。下载软件到https://www.autohotkey.com/这个网址下载AutoHotkey并安装脚本实现网上很多实现方式都是基于AutoHotkeyv1.0、v1.1的,Au......
  • 使用idea进行开发
    使用idea进行开发使用步骤创建一个新的工程​ 自己的jdk安装目录输入工程名,模块名实际创建的样子其他在工程下创建其他模块创建完成创建一个Java文件注意,这里的前面两个是包名,最后一个.后面实际是.demo01.java的意思建立包快捷键创......
  • Linux系统之mv命令的基本使用
    (Linux系统之mv命令的基本使用)一、MV命令介绍1.mv命令简介mv命令主要是在Linux系统中用来对文件或目录重新命名,或者将文件从一个目录移到另一个目录中。source表示源文件或目录,target表示目标文件或目录。如果将一个文件移到一个已经存在的目标文件中,则目标文件的内容将被覆......
  • 博弈论——博弈软件Gambit使用(七)
    Gambit软件可以用于分析和解决各种类型的博弈论问题,从而帮助研究人员深入理解决策制定者之间的相互影响和策略选择。使用Gambit软件,研究人员可以建立博弈模型,定义不同决策制定者的策略集合和支付函数,然后通过计算来分析各种可能的博弈结果。例如,Gambit软件可以用于计算纳什均......
  • $ jquery 选择器的使用
    一、$()函数【jquery()】用途包装DOM元素,以便于操作(jquery选择器)作为几个通用的实用工具函数的命名空间前缀,例如,删除字符串前后空格的实用函数,其调用方法如:$.trim(str);文档就绪处理程序:包装文档实例,然后调用ready()方法,当文档为操作准备就绪的时候就执行该函数创建DOM元素,通......
  • 使用hutool给excel单元格标黄和添加批注
    packagecom.yc.cloud.excel.util;importcn.hutool.poi.excel.ExcelWriter;importlombok.extern.slf4j.Slf4j;importorg.apache.poi.hssf.usermodel.HSSFClientAnchor;importorg.apache.poi.hssf.usermodel.HSSFRichTextString;importorg.apache.poi.ss.usermodel.......
  • 【8月摸鱼计划】cw32f0有浮点计算单元吗?怎么使用矩阵求逆?
    cw32f0是一款基于中国开源项目的芯片,它并不具备浮点计算单元。因此,无法直接进行浮点数运算。然而,您仍然可以通过一些方法来近似实现浮点数的计算。一种常见的方法是使用定点数表示浮点数,并通过手动实现相应的运算算法来达到类似的效果。这需要根据具体的应用场景设计相应的固定点......
  • 记录一个解决方法- 使用editableProTable表头筛选,无法重置,位置偏移
    问题如图:切换原始告警和收敛告警以后,由于二者用到同一个table,切换之后再点击筛选条件,则筛选框的位置发生偏移解决办法:给table一个key属性,改变table中的数据或者列时,去改变这个唯一的key,key值改变,table就可以重新渲染了!......
  • 为什么MySQL innodb的数据达到亿级别,使用‘select count(*) ’将会特别慢?
    当表的数据达到亿级别时,使用SELECTCOUNT(*)FROMtable会变得特别慢,主要是因为以下几个原因:全表扫描:SELECTCOUNT(*)FROMtable通常会导致全表扫描,除非有一些优化手段被应用(例如使用覆盖索引)。当你执行这样的查询,数据库实际上需要读取表中的每一行以计算总......