WebFlux、反应式和处理html" target="_blank">程序的新增功能。我已经让事情“正常”了,但我不明白为什么下面的代码返回“OK”,返回的是空的正文,反之则是“not found”。
澄清:关注的问题在DemoPOJOHandler.getById()的最终返回语句中。“短路”代码按预期工作(即返回“坏请求”状态),但是如果DemoPOJORepo.getById(int)返回Mono.empty(),最终返回语句的“开关”路径似乎不会得到执行。
(注意:我破解了一个基于列表的“repo”,以避免在计算处理程序和http返回类型时处理数据库。)
路由器实现(“/v1”是一组基于注释的RESTfulendpoint)。。。
@Configuration
public class DemoPOJORouter {
@Bean
public RouterFunction<ServerResponse> route(DemoPOJOHandler requestHandler) {
return nest(path("/v2"),
nest(accept(APPLICATION_JSON),
RouterFunctions.route(RequestPredicates.GET("/DemoPOJO"), requestHandler::getAll)
.andRoute(RequestPredicates.GET("/DemoPOJO/{id}"), requestHandler::getById)
.andRoute(RequestPredicates.POST("/DemoPOJO"), requestHandler::add)));
}
}
处理程序实现已经“精简”到只涉及到有问题的代码。我有一种感觉,很多风格“仍然是必要的”,但我试图把反应性的东西放在“最有意义”的地方。
如果我在URI上提供了一个错误的值(即“foo”),那么就会返回http“错误请求”。但是,如果提供了有效格式的int值,似乎永远不会得到“switchIfEmpty”应该生成的“not found”,但它不会映射到repo中的条目。
@Component
public class DemoPOJOHandler {
public static final String PATH_VAR_ID = "id";
private DemoPOJORepo repo = null;
public Mono<ServerResponse> getById(ServerRequest request) {
Mono<DemoPOJO> monoDemoPOJO = null;
Map<String, String> pathVariables = request.pathVariables();
int id = -1;
checkRepoRef(); // part of the list hack
// short-circuit if request doesn't contain id (should never happen)
if ((pathVariables == null)
|| (!pathVariables.containsKey(PATH_VAR_ID))) {
return ServerResponse.badRequest().build();
}
// short-circuit if bad id value
try {
id = Integer.parseInt(pathVariables.get(PATH_VAR_ID));
} catch(NumberFormatException e) {
return ServerResponse.badRequest().build();
}
// get entity by keyValue
monoDemoPOJO = repo.getById(id);
return monoDemoPOJO
.flatMap(demoPOJO -> ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.syncBody(demoPOJO)
.switchIfEmpty(ServerResponse.notFound().build()));
}
}
黑客攻击基于列表的repo,以避免在处理处理程序和http返回类型时处理数据/API。
// local hack to avoid a database for testing
public class DemoPOJORepo {
private static DemoPOJORepo fpRepo = null;
private static int NUM_ROWS = 100;
private Map<Integer, DemoPOJO> fooPOJOMap;
private DemoPOJORepo() {
initMap();
}
public static DemoPOJORepo getInstance() {
if (fpRepo == null) {
fpRepo = new DemoPOJORepo();
}
return fpRepo;
}
public Mono<DemoPOJO> getById(int id) {
Mono<DemoPOJO> monoDP;
if (fooPOJOMap.containsKey(id)) {
monoDP = Mono.just(fooPOJOMap.get(id));
} else {
monoDP = Mono.empty();
}
return monoDP;
}
private Mono<Void> initMap() {
fooPOJOMap = new TreeMap<Integer, DemoPOJO>();
int offset = -1;
for(int ndx=0; ndx<NUM_ROWS; ndx++) {
offset = ndx + 1;
fooPOJOMap.put(offset, new DemoPOJO(offset, "foo_" + offset, offset+100));
}
return Mono.empty();
}
}
我可以看到代码是正确的。响应代码是坏请求,因为您正试图将“foo”转换为整数,当它抛出异常时,您将返回一个坏请求响应,所以我认为它工作得非常好。如果您使用数据库中不存在的整数标识,那么答案必须是找不到的响应
括号位于错误的位置,导致swithIfEmpy应用于服务器响应。ok()
publisher而不是monoDemoPOJO
,用这个替换返回,它应该可以工作:
return monoDemoPOJO
.flatMap(demoPOJO -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).syncBody(demoPOJO))
.switchIfEmpty(ServerResponse.notFound().build());
请原谅稍微不完整的代码,当我遇到这个问题时,我正在重组它。其要点是,在调用中,编译器表示/*Here*/的地方,编译器强制使用类型,但是当返回时,我希望通过返回204来处理,否则我希望返回200。我怎么才能做到? 理想情况下,我可以在map调用中检查它是否是mono.empty(),但如果它是空的mono,它似乎不会输入map。想过使用optionals,但它们似乎不能很好地使用单音。
我有一个用Kotlin写的WebApplication。这是一种有点不和的聊天。我有一个函数,它做几件事。该函数本身用于删除用户的帐户,但是在这样做的同时,它也删除了他从数据库中注销的消息,他将从数据库中的所有组中删除,在他是管理员的组中选择一个新的管理员。 而这个函数看起来确实是这样的: 我的存储库如下所示: 所以我的函数中的最后2个语句返回一个空单声道。问题是先执行哪条语句并不重要,只执行了两
我正在按照一些教程从头开始建立一个spring mvc项目。最初,我将web应用程序配置为在Tomcat中运行。我编写了一个简单的controller类,请求点击“/”。但tomcat总是向我显示“HTTP状态404-找不到”错误。 我看了很多这样的问题,但那些答案对我都不起作用 删除tomcat安装并重新配置。当点击localhost:8080/时,我将获得tomcat主页。 检查了代码的拼写
更新时间:2019-05-30 13:49:05 节点简介 HTTP返回节点是一个对外输出API的结束节点,你可以通过它配置API的返回值 (注意:“HTTP请求”节点与“HTTP返回”节点必须成对出现)。每个API有且仅有一个HTTP返回节点 , 默认返回前置节点输出。 使用场景 如果您需要使用服务开发工作台开发出一个http接口,那么您就需要使用HTTP请求节点作为起始节点,HTTP返回节点作
我正在做一个简单的项目,它使用Spring Boot 2和使用Kotlin的Spring WebFlux。我为我的处理函数编写了测试(在测试中,我使用Mockito模拟依赖项)。 然而,我的路由函数似乎不会触发处理程序,因为我的所有请求都返回HTTP 404 not FOUND(即使路由是正确的)。 我已经查看了各种其他项目,以了解这些测试应该如何编写(这里,这里),但问题仍然存在。 代码如下(也