我对响应式代码完全陌生,经过大量教程和 youtube 视频后,我正在尝试使用功能端点设置一个小型测试应用程序;一个简单的 RouterFunction、RouterHandler 和 Repository。问题是如何将 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.properties
,logging.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