首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

DeferredResult的Spring MVC单元测试不调用超时回调

DeferredResult是Spring MVC中的一个类,用于实现异步处理和非阻塞IO。它可以在处理请求时先返回一个DeferredResult对象,然后在后台线程中进行处理,并最终通过设置DeferredResult的结果来完成请求。

在进行Spring MVC的单元测试时,如果使用DeferredResult进行异步处理,可能会遇到不调用超时回调的问题。这是因为在单元测试中,没有真正的容器环境来处理异步请求,导致超时回调无法触发。

为了解决这个问题,可以使用MockMvc进行模拟请求的发送和处理。MockMvc是Spring MVC提供的一个用于测试控制器的工具,可以模拟HTTP请求和响应,并进行断言验证。

下面是一个示例代码,展示了如何使用MockMvc进行DeferredResult的单元测试:

代码语言:java
复制
import org.junit.jupiter.api.Test;
import org.springframework.test.web.servlet.MockMvc;
import import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

@RestController
public class MyController {

    @GetMapping("/async")
    public DeferredResult<String> asyncMethod() {
        DeferredResult<String> deferredResult = new DeferredResult<>();
        // 在后台线程中处理请求
        new Thread(() -> {
            // 模拟耗时操作
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            deferredResult.setResult("Hello, World!");
        }).start();
        return deferredResult;
    }
}

public class MyControllerTest {

    @Test
    public void testAsyncMethod() throws Exception {
        MyController controller = new MyController();
        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller).build();

        mockMvc.perform(MockMvcRequestBuilders.get("/async"))
                .andExpect(MockMvcResultMatchers.request().asyncStarted())
                .andExpect(MockMvcResultMatchers.request().asyncResult("Hello, World!"))
                .andReturn();
    }
}

在上述示例中,我们创建了一个MyController类,其中包含了一个asyncMethod()方法,该方法返回一个DeferredResult对象,并在后台线程中进行处理。在单元测试中,我们使用MockMvc发送GET请求,并通过断言验证异步请求的状态和结果。

需要注意的是,由于单元测试中没有真正的容器环境,所以异步请求的处理是在同一个线程中完成的,不会真正地进行异步处理。因此,在实际的生产环境中,需要使用真正的容器来处理异步请求,以确保超时回调能够正常触发。

推荐的腾讯云相关产品:腾讯云云服务器(ECS)、腾讯云对象存储(COS)、腾讯云数据库(TencentDB)等。你可以通过访问腾讯云官网(https://cloud.tencent.com/)获取更多关于这些产品的详细信息。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【小家Spring】高性能关键技术之---体验Spring MVC异步模式(Callable、WebAsyncTask、DeferredResult) 基础使用篇

如果我们需要超时处理或者错误处理,我们可以使用WebAsyncTask代替Callable 实际使用中,我并不建议直接使用Callable ,而是使用Spring提供WebAsyncTask...() -> "程序[超时]"); // 备注:这个是Spring5新增 webAsyncTask.onError(() -> "程序[出现异常]");...因此页面是会显示“程序[超时]”这几个字。其执行过程同Callback。...Callable timeoutCallback; // 发生错误 private Callable errorCallback; // 完成(不管超时还是错误都会执行)...有些较常见场景, Callable也并不能解决,比如说:我们访问A接口,A接口调用三方服务,服务(注意此处指,不是返回值)B接口,这种情况就没办法使用Callable了,这个时候可以使用DeferredResult

3K52
  • SpringBoot异步接口怎么实现?

    Spring MVC 调用 request.startAsync() 并将 Callable 提交给 AsyncTaskExecutor 以在单独线程中进行处理。...最终 Callable 产生结果,Spring MVC将请求分派Servlet容器以完成处理。再次调用 DispatcherServlet ,并使用 Callable 异步生成返回值继续处理。...基于WebAsyncTask实现Spring提供WebAsyncTask是对Callable包装,提供了更强大功能,比如:处理超时、错误、完成等。...Spring MVC 调用 request.startAsync() 。同时,DispatcherServlet 和��有配置过滤器退出请求处理线程,但响应保持打开状态。...应用程序从某个线程设置 DeferredResultSpring MVC 将请求分派 Servlet 容器。再次调用 DispatcherServlet ,并使用异步生成返回值继续处理。

    7210

    大部分程序员还不知道 Servelt3 异步请求,原来这么简单?

    另外我们可以设置默认超时时间: # 异步请求超时时间 spring.mvc.async.request-timeout=2000 如果异步程序执行完成,可以调用 DeferredResult#setResult...此时若有设置 DeferredResult#onCompletion 方法,将会触发该回方法。...Go to implementation(s) 最后 DeferredResult 还提供其他异常方法 onError,起初小黑哥以为只要异步线程内发生异常,就会触发该回方法。...这是因为默认情况使用 SimpleAsyncTaskExecutor 执行异步请求,每次调用执行都将会新建线程。由于这种方式不复用线程,生产推荐使用这种方式,所以我们需要使用线程池代替。...spring.mvc.async.request-timeout=10000 如果需要为单独请求配置特定超时时间,我们需要使用 WebAsyncTask 包装 Callable 。

    61030

    SpringBoot四种异步处理,写这篇文章,我自己先学到了

    最近更新了一系列关于异步和文章,比如《一篇文章,搞明白异步和多线程区别》、《两个经典例子让你彻底理解java机制》、《异步请求和异步调用有区别?》,大家感兴趣的话可温习一下。...通过AsyncContextaddListener还可以添加监听事件,用来处理异步线程开始、完成、异常、超时等事件。...基于WebAsyncTask实现 Spring提供WebAsyncTask是对Callable包装,提供了更强大功能,比如:处理超时、错误、完成等。...调用并不一定在Spring MVC当中,它可以是别的线程。...和DeferredResult是用于Web(Spring MVC,而Callable是用于concurrent(并发)处理

    2K30

    Spring Web MVC框架(三) 异步处理

    return "someView"; } }; } 另外一种方式是返回一个DeferredResult,这时候返回结果线程可以使任何线程,不一定是Spring MVC管理线程...异步请求拦截 HandlerInterceptor可以同时实现AsyncHandlerInterceptorafterConcurrentHandlingStarted,也可以注册CallableProcessingInterceptor...如果使用Callable,也可以将其包装到WebAsyncTask中,同样提供了超时和完成支持。 HTTP流 使用HTTP流可以向一个响应返回多个值。...配置Spring MVC Spring代码配置和XML配置提供了配置异步请求地方,分别是WebMvcConfigurerconfigureAsyncSupport方法和<mvc:annotation-driven...我们可以配置属性有:异步请求超时时间;异步请求执行器(我们最好设置这个,因为Spring只是用了最简单执行器,不一定满足我们需求);以及注册CallableProcessingInterceptor

    57710

    7 种提升 Spring Boot 吞吐量神技!

    而返回CompletableFuture实例就可以作为这次调用契约,在将来任何场合,用于获得最终计算结果。...这两个方法如果在指定线程池情况下,都是在ForkJoinPool.common线程池中执行,而这个线程池中所有线程都是Daemon(守护)线程,所以,当主线程结束时,这些线程无论执行完毕都会退出系统... deferredResult = new DeferredResult(); // 调用长时间执行任务 taskService.execute(deferredResult...controller里面的流程 logger.info(Thread.currentThread().getName() + "从executeSlowTask方法返回"); // 超时方法...; } }); // 处理完成方法,无论是超时还是处理成功,都会进入这个方法 deferredResult.onCompletion

    36020

    提升 Spring Boot 吞吐量 7 个神技,让你项目飞起来!

    这两个方法如果在指定线程池情况下,都是在 ForkJoinPool.common 线程池中执行,而这个线程池中所有线程都是 Daemon(守护)线程,所以,当主线程结束时,这些线程无论执行完毕都会退出系统... deferredResult = new DeferredResult();         // 调用长时间执行任务         taskService.execute(deferredResult...controller里面的流程         logger.info(Thread.currentThread().getName() + "从executeSlowTask方法返回");         // 超时方法...;    }   });         // 处理完成方法,无论是超时还是处理成功,都会进入这个方法         deferredResult.onCompletion(new Runnable...Spring Boot 学习笔记,这个太全了! 23 种设计模式实战(很全) Java 8 排序 10 个姿势,太秀了吧! Spring Boot 保护敏感配置 4 种方法!

    55010

    7 种提升 Spring Boot 吞吐量神技!

    如果您正在学习Spring Boot,那么推荐一个连载多年还在继续更新免费教程:http://blog.didispace.com/spring-boot-learning-2x/ public class...这两个方法如果在指定线程池情况下,都是在ForkJoinPool.common线程池中执行,而这个线程池中所有线程都是Daemon(守护)线程,所以,当主线程结束时,这些线程无论执行完毕都会退出系统... deferredResult = new DeferredResult();         // 调用长时间执行任务         taskService.execute(deferredResult...controller里面的流程         logger.info(Thread.currentThread().getName() + "从executeSlowTask方法返回");         // 超时方法...;    }   });                  // 处理完成方法,无论是超时还是处理成功,都会进入这个方法         deferredResult.onCompletion

    42010

    SpringBoot性能太差,教你几招轻松搞定

    而返回 CompletableFuture 实例就可以作为这次调用契约,在将来任何场合,用于获得最终计算结果。...这两个方法如果在指定线程池情况下,都是在 ForkJoinPool.common 线程池中执行,而这个线程池中所有线程都是 Daemon(守护)线程,所以,当主线程结束时,这些线程无论执行完毕都会退出系统... deferredResult = new DeferredResult();         // 调用长时间执行任务         taskService.execute(deferredResult...controller里面的流程         logger.info(Thread.currentThread().getName() + "从executeSlowTask方法返回");         // 超时方法...;    }   });         // 处理完成方法,无论是超时还是处理成功,都会进入这个方法         deferredResult.onCompletion(new Runnable

    37720

    7 种提升 SpringBoot 吞吐量神技!

    而返回 CompletableFuture 实例就可以作为这次调用契约,在将来任何场合,用于获得最终计算结果。...这两个方法如果在指定线程池情况下,都是在 ForkJoinPool.common 线程池中执行,而这个线程池中所有线程都是 Daemon(守护)线程,所以,当主线程结束时,这些线程无论执行完毕都会退出系统... deferredResult = new DeferredResult(); // 调用长时间执行任务 taskService.execute(deferredResult...controller里面的流程 logger.info(Thread.currentThread().getName() + "从executeSlowTask方法返回"); // 超时方法...; } }); // 处理完成方法,无论是超时还是处理成功,都会进入这个方法 deferredResult.onCompletion(new Runnable

    71620

    【云+社区年度征文】几种SpringMvc 异步编程了解下?

    这样的话线程工作量是超级饱和,需要不停干活,连休息机会都不给了。...下面我们就来看看Spring mvc 几种异步方式吧 https://docs.spring.io/spring-framework/docs/current/reference/html/web.html...Callable对象最终产生一个返回结果,此时Spring MVC会重新把请求分派Servlet容器,恢复处理 DispatcherServlet再次被调用,恢复对Callable异步处理所返回结果处理...deferredResult.setResult(result); } }); // 异步请求超时调用 deferredResult.onTimeout...总结 了解spring mvc 异步编程,对我们后续学习响应式编程、rxjava、webflux等都是有好处。 异步编程可以帮我们高效利用系统资源。

    84260

    DeferredResult解决了什么问题

    ; } 2.接口调用 这样就完成了DeferredResult异步调用,当然我们也可以在DeferredResult设置超时相关逻辑。...接收到请求后,将请求暂存并且释放容器线程,用来接收新请求 容器超时逻辑和业务正常处理逻辑将结果塞到DeferredResult返回 spring对于DeferredResult请求处理 1.请求预处理...当然DeferredResult处理逻辑也脱离不了spring mvc支持,也是要走到DispatcherServlet来处理请求: protected void doDispatch(HttpServletRequest...,此时就会将超时值塞入到请求中,具体是通过之前设置DeferredResult相关拦截器中handleTimeout,比如spring自己提供拦截器: public class TimeoutDeferredResultProcessingInterceptor...超时逻辑处理流程如下: 2.setResult主动返回 业务线程在执行完逻辑,将结果塞回到DeferredResult时也会调用setResultInternal,赋值完成后调用AsyncWebRequest

    1.3K31

    异步编程 - 10 Web Servlet异步非阻塞处理

    正式名称Spring Web MVC来自其源模块(spring-webmvc)名称,但它通常被称为Spring MVC。...Spring MVC内部对request.startAsync()调用返回AsyncContext,可以使用它来进一步控制异步处理。...2)Spring MVC内部在personDeferredResult方法返回后会保存DeferredResult对象到内存队列或者列表,然后会调用request.startAsync()开启异步处理,...并且调用DeferredResult对象setResultHandler方法,设置当异步结果产生后对结果进行重新路由函数(逻辑在WebAsyncManagerstartDeferredResultProcessing...3)最终在业务线程池中执行异步任务会产生一个结果,该结果会被设置到DeferredResult对象,然后设置函数会被调用,接着Spring MVC会分派请求结果回到Servlet容器继续完成处理

    71020

    springMvc DeferredResultlong polling应用

    1.了解servlet以及spring mvc异步? Spring MVC 3.2开始引入了基于Servlet 3异步请求处理。...相比以前,控制器方法已经不一定需要返回一个值,而是可以返回一个java.util.concurrent.Callable对象,并通过Spring MVC所管理线程来产生返回值。...与此同时,Servlet容器主线程则可以退出并释放其资源了,同时也允许容器去处理其他请求。通过一个TaskExecutor,Spring MVC可以在另外线程中调用Callable。...MVC会重新把请求分派Servlet容器,恢复处理 DispatcherServlet再次被调用,恢复对Callable异步处理所返回结果处理 对DeferredResult异步请求处理顺序也非常类似...和所有过滤器都退出Servlet容器线程,但此时方法响应对象仍未返回 由处理该请求线程对 DeferredResult进行设值,然后Spring MVC会重新把请求分派Servlet容器,恢复处理

    18120

    如何提升系统吞吐量?和你理解不一样异步场景

    这种方案spring给我们提供了DeferredResult和Callable方式实现, 官方文档中说DeferredResult和Callable都是为了异步生成返回值提供基本支持。...通过阅读WebAsyncManager源码才发现果真如此,WebAsyncManager是Spring MVC管理async processing中心类。...该类包含以下日常使用相关特性: 超时配置:通过构造函数可以传入超时时间,单位为毫秒;因为需要等待设置结果后才能继续处理并返回客户端,如果一直等待会导致客户端一直无响应,因此必须有相应超时机制来避免这个问题...;实际上就算设置这个超时时间,应用服务器或者Spring也会有一些默认超时机制来处理这个问题。...它执行过程如下所示: 客户端请求服务 SpringMVC调用Controller,Controller返回一个DeferredResult对象 SpringMVC调用ruquest.startAsync

    91620

    【SpringBoot WEB系列】异步请求知识点与使用姿势小结

    异步请求描述 先介绍一下同步与异步: 一个正常调用,吭哧吭哧执行完毕之后直接返回,这个叫同步; 接收到调用,自己不干,新开一个线程来做,主线程自己则去干其他事情,等后台线程吭哧吭哧跑完之后,主线程再返回结果...()获取AsyncContext 添加监听器 asyncContext.addListener(AsyncListener)(这个是可选) 用户请求开始、超时、异常、完成时 设置超时时间 asyncContext.setTimeout...WebAsyncTask callable 方式,非常直观简单,但是我们经常关注超时+异常处理却不太好,这个时候我们可以用WebAsyncTask,实现姿势也很简单,包装一下callable,然后设置各种事件即可...DeferredResult DeferredResult与WebAsyncTask最大区别就是前者不确定什么时候会返回结果, DeferredResult这个特点,可以用来做实现很多有意思东西...那么这个可以设置超时么,如果一直把前端挂住,貌似也不太合适吧 在构造方法中指定超时时间: new DeferredResult(3000L) 设置全局默认超时时间 @Configuration @

    60130

    如何在SpringBoot中异步请求和异步调用

    HttpServletResponse response) { AsyncContext asyncContext = request.startAsync(); //设置监听器:可设置其开始、完成、异常、超时等事件调处理...return new TimeoutCallableProcessingInterceptor(); } } 方式三: 和方式二差不多,在 Callable 外包一层,给 WebAsyncTask 设置一个超时...调用异步方法,不能为同一个类方法(包括同一个类内部类),简单来说,因为 Spring 在启动扫描时会为其创建一个代理类,而同类调用时,还是调用本身代理类,所以和平常调用是一样。...调用同一个类下注有 @Async 异步方法:在 spring 中像 @Async 和 @Transactional、cache 等注解本质使用是动态代理,其实 Spring 容器在初始化时候 Spring...,这个类肯定是被 Spring 管理,其他 Spring 组件需要调用时候肯定会注入进去,这时候实际上注入进去就是代理类了。

    1.6K10

    异步化,高并发大杀器

    同步和异步关注是结果消息通信机制 同步:同步意思就是调用方需要主动等待结果返回 异步:异步意思就是不需要主动等待结果返回,而是通过其他手段比如,状态通知,函数等。...正所谓是物尽其用,既然CPU使用率被IO调用搞得很低,那我们就可以使用异步非阻塞,当发生IO调用时我并不马上关心结果,我只需要把函数写入这次IO调用,我这个时候线程可以继续处理新请求,当IO调用结束结束时...,会调用函数。...AsyncContext ac=req.startAsync(); 用于获取异步上下文,后续我们通过这个异步上下文进行返回数据,有点像我们买衣服时候,给老板一个电话,而这个上下文也是一个电话,当有衣服到时候...System.out.println("异步调用执行超时

    93530
    领券