Java @异步API端点Spring Webflux
我需要编写SpringWebFlux端点(路由器函数),以便向邮件收件人列表发送邮件。 UI将选择邮件收件人列表,并将列表发送到我将要编写的API。我希望在收到请求后立即以这种方式激活端点,我应该向用户界面发送响应,说明电子邮件正在发送。发送响应后,我应该继续异步发送邮件。我不能像在SpringMVC中那样使用@async注释,因为它是被动世界中的反模式 既然我使用SpringWebFlux来开发API,我如何发送报告呢 我的代码中有一个下面的结构 Router.javaJava @异步API端点Spring Webflux,java,spring,asynchronous,spring-webflux,reactor,Java,Spring,Asynchronous,Spring Webflux,Reactor,我需要编写SpringWebFlux端点(路由器函数),以便向邮件收件人列表发送邮件。 UI将选择邮件收件人列表,并将列表发送到我将要编写的API。我希望在收到请求后立即以这种方式激活端点,我应该向用户界面发送响应,说明电子邮件正在发送。发送响应后,我应该继续异步发送邮件。我不能像在SpringMVC中那样使用@async注释,因为它是被动世界中的反模式 既然我使用SpringWebFlux来开发API,我如何发送报告呢 我的代码中有一个下面的结构 Router.java @Bean publi
@Bean
public RouterFunction<ServerResponse> sendEmail() {
return route(POST("/email").and(accept(APPLICATION_JSON)), handler::sendEmail);
}
@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));
});
});
}
@Bean
公共路由函数sendmail(){
返回路线(POST(“/email”)。和(accept(APPLICATION_JSON)),handler::sendmail);
}
Handler.java
@Bean
public RouterFunction<ServerResponse> sendEmail() {
return route(POST("/email").and(accept(APPLICATION_JSON)), handler::sendEmail);
}
@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));
});
});
}
@Autowired
电子邮件服务;
公共Mono sendEmail(服务器请求){
Mono-pojoAMono=request.bodyToMono(PojoA.class);
返回pojoAMono.flatMap(pojoA->{
返回emailService.sendEmail(pojoA).flatMap(mailSent->{
返回服务器响应
.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(“正在发送邮件”,String.class));
});
});
}
您可以直接将响应返回给调用者,在该流完成后,作为副作用运行电子邮件发送。这可以通过流完成后执行的doFinally
完成
因此,您的代码可以如下所示:
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));
}
@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());
}
公共Mono发送电子邮件(服务器请求){
返回请求。bodyToMono(PojoA.class)
.map(此::sendEmailSideEffect)
.flatMap(pojoA->ServerResponse
.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(“正在发送邮件”,String.class));
}
私人单声道副作用(PojoA PojoA){
返回Mono.just(pojoA)
.doFinally(signalType->emailService.sendEmails(pojoA));
}
您应该构建响应,然后处理数据(发送电子邮件)
大概是这样的:
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));
}
@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());
}
@Bean
公共路由函数sendmail(){
返回路由(POST(“/test”)。和(accept(APPLICATION_JSON)),this::someMethod);
}
Mono someMethod(服务器请求服务器请求){
返回ServerResponse.ok().build()
.doOnNext(r->Mono.just(“数据”)//执行一些过程,如发送电子邮件
.delayElement(持续时间秒(2))
.subscribeOn(Schedulers.parallel())
.log()
.subscribe());
}
出于测试目的,我给您设置了一个延迟,让您在发送响应后看到数据处理。我尝试了上述代码,在测试时,它似乎仍将等待sendMailSideEffect完成,然后响应调用者。