当前位置: 首页 > 知识库问答 >
问题:

@异步APIendpointSpring Webflux

罗建弼
2023-03-14

我有一个要求编写Spring的网络流量endpoint(路由器功能)来发送邮件到邮件收件人列表。UI将选择邮件收件人列表并将列表发送到我将编写的API。我希望在收到请求后立即以这种方式引入endpoint,我应该向UI发送响应,说正在发送电子邮件。发送响应后,我应该异步继续邮件发送工作。我不能像我们在Spring MVC中使用的那样使用@async注释,因为它是反应式世界中的反模式。

既然我在使用SpringWebFlux开发API,我该如何发送报告呢。

我的代码中有一个下面的结构。

路由器。JAVA

@Bean
public RouterFunction<ServerResponse> sendEmail() {
 return route(POST("/email").and(accept(APPLICATION_JSON)), handler::sendEmail);
}

处理程序。JAVA

@Autowired
EmailService emailService;

public Mono<ServerResponse> sendEmail(ServerRequest request) {
    Mono<PojoA> pojoAMono = request.bodyToMono(PojoA.class);
    return pojoAMono.flatMap(pojoA -> {
       return emailService.sendEmail(pojoA).flatMap(mailSent -> {
         return  ServerResponse
        .status(HttpStatus.OK)
        .contentType(MediaType.APPLICATION_JSON)
        .body("Mails are being sent", String.class));
       });
    });
    
}

共有2个答案

丁经略
2023-03-14

您应该构建响应,然后处理数据(发送电子邮件)。

像这样的东西:

@Bean
public RouterFunction<ServerResponse> sendEmail() {
    return route(POST("/test").and(accept(APPLICATION_JSON)), this::someMethod);
}

Mono<ServerResponse> someMethod(ServerRequest serverRequest) {
    return ServerResponse.ok().build()
            .doOnNext(r -> Mono.just("data") //doing some process like send email
                    .delayElement(Duration.ofSeconds(2))
                    .subscribeOn(Schedulers.parallel())
                    .log()
                    .subscribe());
}

出于测试目的,我把一个延迟给你看数据处理后的响应发送。

段干德泽
2023-03-14

您可以直接将响应返回给调用者,并在该流完成后运行电子邮件发送作为副作用。这可以使用流完成后执行的doFinal来完成。

因此,您的代码可能如下所示:

public Mono<ServerResponse> sendEmail(ServerRequest request) {
    return request.bodyToMono(PojoA.class)
            .map(this::sendEmailSideEffect)
            .flatMap(pojoA -> ServerResponse
                    .status(HttpStatus.OK)
                    .contentType(MediaType.APPLICATION_JSON)
                    .body("Mails are being sent", String.class));
}

private Mono<PojoA> sendEmailSideEffect(PojoA pojoA) {
    return Mono.just(pojoA)
            .doFinally(signalType -> emailService.sendEmails(pojoA));
}
 类似资料:
  • 异步操作在线程中执行,与主应用程序线程分开。当应用程序调用方法异步执行操作时,应用程序可以在异步方法执行其任务时继续执行。 示例 下面通过一个例子来理解这个概念。在示例程序中使用IO库接受用户输入。 是一种同步方法。它将阻止执行函数调用之后的所有指令,直到方法完成执行。 等待输入。它停止执行并且在收到用户输入之前不再执行任何操作。 以上示例将产生以下输出 - 在计算中,当某个事件在继续之前等待事件

  • 支持Python异步。包括对Core和ORM使用的支持,使用了异步兼容的方言。 1.4 新版功能. 注解 从SQLAlChemy 1.4.3开始的异步扩展现在可以被认为是 测试级 软件。API细节可能会更改,但是在这一点上,不太可能有重大的向后不兼容更改。 参见 对内核和ORM的异步IO支持 -初始功能发布 异步集成 -示例脚本演示了asyncio扩展中核心和ORM使用的工作示例。 Asyncio

  • 问题内容: 同步和异步AJAX调用有什么区别?何时使用同步以及何时异步? 问题答案: 在最基本的级别上,当您希望调用在后台发生时,您可以使用异步模式,而当您希望代码等待直到调用完成时,则可以使用同步模式。 异步模式是AJAX调用的常用方法,因为通常在事件上附加一个回调函数,以便您可以在服务器端数据就绪时进行响应,而不必等待数据到达。

  • 问题内容: 我该如何做这项工作 我试图从异步之一获取同步功能,我需要它来使用FreeTds异步查询作为同步之一 问题答案: 使用deasync-用C ++编写的模块,它将Node.js事件循环暴露给JavaScript。该模块还公开了一个函数,该函数阻止后续代码,但不阻止整个线程,也不引起繁忙的等待。您可以将函数放入循环中:

  • 我对一个异步函数有点拘泥于此。 我要完成的是创建一个batchProcessing函数(batchGetSubs),它将循环访问一组文件,读取一个ID,然后发出一个API请求,等待一个响应(问题),然后用格式化的数据写入一个新文件。 问题--我尝试了异步和等待,以及推送承诺和尝试使用承诺.所有这些都是为了等待承诺的解决,但没有成功。当前的行为是,在API调用实际返回所有数据之前,我获取Promis

  • 异步Log日志 use AsyncLog; yield AsyncLog::info('hello world'); yield AsyncLog::debug('test debug', ['foo' => 'bar']); yield AsyncLog::notice('hello world',[], 'group.com'); yield Async

  • 面试题 20180321面试题 console.log(1); setTimeout(function () { console.log(2); }, 1000); setTimeout(function () { console.log(3); }, 0); console.log(4); 20180321面试

  • 在 基础教程 中,我们创建了一个简单的 todo 应用。它只有同步操作。每当 dispatch action 时,state 会被立即更新。 在本教程中,我们将开发一个不同的,异步的应用。它将使用 Reddit API 来获取并显示指定 subreddit 下的帖子列表。那么 Redux 究竟是如何处理异步数据流的呢? Action 当调用异步 API 时,有两个非常关键的时刻:发起请求的时刻,和