WebFlux功能端点,如何返回带有检索到的数据且没有不必要的阻止/等待的ServerResponse?

问题描述

我对反应式代码是完全陌生的,并且在大量教程和youtube视频之后,我试图使用功能端点来建立一个小型测试应用程序;一个简单的RouterFunction,RouterHandler和存储库。问题是如何在ServerResponse中将对象从存储库返回给调用者,而不会引起任何不必要的阻塞?

我正在使用Postman进行测试。这是我的测试应用程序中有趣的部分:

@Configuration
public class BookRouter {
    @Autowired 
    BookRepositoryImpl bookRepository;

    @Bean
    public RouterFunction<ServerResponse> bookRoutes() {
        BookHandler bookHandler = new BookHandler(bookRepository);
        return RouterFunctions
            .nest(path("/api/books"),route(GET("/{group}/{name}").and(accept(ALL)),bookHandler::getBook)
            );
        }
    }

@Repository
public class BookRepositoryImpl implements BookRepository {
    private final ReactiveMongoTemplate mongoTemplate;

    @Autowired
    public BookRepositoryImpl(ReactiveMongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    @Override
    public Mono<Book> findByName(String group,String name) {
        Query query = new Query(Criteria.where("group").is(group).and("name").is(name));
        return mongoTemplate.findOne(query,Book.class);
    }
}

public class BookHandler {
    public Mono<ServerResponse> getBook(ServerRequest request) {
        String group = request.pathVariable("group");
        String name = request.pathVariable("name");

        bookRepository
            .findByName(group,name)
            .subscribe(
                ok -> System.out.println("findByName " + ok),error -> System.err.println("Error: " + error));
        return ServerResponse
            .accepted()
            .contentType(MediaType.TEXT_PLAIN)
            .bodyValue("Request queued");
    }
}

当我具有上面显示代码时,期望的数据会在subscribe(ok -> ...)中打印出来,但是我还没有弄清楚如何在ServerResponse中返回这些数据。

如果我将getBook()中的代码更改为

return setting
    .flatMap(s -> ServerResponse
        .ok()
        .contentType(MediaType.APPLICATION_JSON)
        .bodyValue(s))
    .switchIfEmpty(NOT_FOUND);

返回的bodyValue为空,尽管我看到它是从数据库中检索到的。

任何关于我所缺少的建议都将受到赞赏。

更新

我正在使用 MongoDB Compass 来查看和验证数据库内容

application.propertieslogging.level.root=DEBUG中启用了调试日志记录,因此Spring类在终端窗口中写入了一些信息。部分匿名的日志如下:

2020-09-05 21:37:02.688 DEBUG 32720 --- [ctor-http-nio-3] o.s.w.r.f.s.s.RouterFunctionMapping      : [96ef6152-1] Mapped to com.sample.book.BookRouter$$Lambda$586/0x0000000800540040@3b0bf8e0
2020-09-05 21:37:02.717 DEBUG 32720 --- [ctor-http-nio-3] o.s.d.m.core.ReactiveMongoTemplate       : findOne using query: { "group" : "Thriller","name" : "The Shining"} fields: Document{{}} for class: class com.sample.book.Book in collection: book
2020-09-05 21:37:02.734 DEBUG 32720 --- [ctor-http-nio-3] o.s.d.m.core.ReactiveMongoTemplate       : findOne using query: { "group" : "Thriller","name" : "The Shining"} fields: {} in db.collection: book.book
2020-09-05 21:37:02.751 DEBUG 32720 --- [ctor-http-nio-3] org.mongodb.driver.protocol.command      : Sending command '{"find": "book","filter": {"group": "Thriller","name": "The Shining"},"limit": 1,"singleBatch": true,"$db": "book"}' with request id 7 to database book on connection [connectionId{localValue:2,serverValue:217}] to server localhost:27017
2020-09-05 21:37:02.766 DEBUG 32720 --- [ntLoopGroup-3-2] org.mongodb.driver.protocol.command      : Execution of command with request id 7 completed successfully in 16.24 ms on connection [connectionId{localValue:2,serverValue:217}] to server localhost:27017
2020-09-05 21:37:02.837 DEBUG 32720 --- [ntLoopGroup-3-2] o.s.http.codec.json.Jackson2JsonEncoder  : [96ef6152-1] Encoding [_id=5f53692af0a02d3af8a7fed9,group=Thriller,name=The Shining,value=in]]
2020-09-05 21:37:02.853 DEBUG 32720 --- [ctor-http-nio-3] r.n.http.server.HttpServerOperations     : [id: 0x96ef6152,L:/0:0:0:0:0:0:0:1:8088 - R:/0:0:0:0:0:0:0:1:50248] Decreasing pending responses,Now 0
2020-09-05 21:37:02.879 DEBUG 32720 --- [ctor-http-nio-3] o.s.w.s.adapter.HttpWebHandlerAdapter    : [96ef6152-1] Completed 200 OK
2020-09-05 21:37:02.905 DEBUG 32720 --- [ctor-http-nio-3] r.n.http.server.HttpServerOperations     : [id: 0x96ef6152,L:/0:0:0:0:0:0:0:1:8088 - R:/0:0:0:0:0:0:0:1:50248] Last HTTP response frame
2020-09-05 21:37:02.931 DEBUG 32720 --- [ctor-http-nio-3] r.n.http.server.HttpServerOperations     : [id: 0x96ef6152,L:/0:0:0:0:0:0:0:1:8088 - R:/0:0:0:0:0:0:0:1:50248] Last HTTP packet was sent,terminating the channel

解决方法

我发现了问题。我忘了在拥有Book的{​​{1}}类中实现吸气剂。令我惊讶的是,缺少它们时没有错误消息或警告。

我插入它们后,此代码按预期返回了结果:

@Document

以下是修复后返回给Postman的数据:

return setting
    .flatMap(s -> ServerResponse
        .ok()
        .contentType(MediaType.APPLICATION_JSON)
        .bodyValue(s))
    .switchIfEmpty(NOT_FOUND);

感谢@ caco3帮助我发现问题!

这是我更新的{ "_id": "5f53692af0a02d3af8a7fed9","group": "Thrillers","name": "The Shining","value": "in" }

Book.java