WebFlux 返回 http.okay 副 http.notFound
WebFlux returning http.okay vice http.notFound
WebFlux、反应式和处理程序的新手。我有东西 "working",但我不明白为什么下面的代码是 returning "okay" 空体,副 "not found".
澄清:关注的问题在DemoPOJOHandler.getById()的最后return声明中。 "short-circuit" 代码按预期工作(即 returns "Bad Request" 状态),但最终 return 语句的 "switchIfEmpty" 路径似乎没有得到执行如果 DemoPOJORepo.getById(int) returns Mono.empty().
(注意:我破解了一个基于列表的 "repo" 以避免在确定处理程序和 http return 类型时处理数据库。)
路由器实现(“/v1”是一组基于注释的 RESTful 端点)...
@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)));
}
}
处理程序实现已 "stripped down" 仅针对相关代码。我感觉大部分样式都是 "still imperative",但我试图将反应性内容放在 "makes the most sense".
的位置
如果我在 URI 上提供了错误的值(即 "foo"),那么我会得到 http "bad request" returned。但是,如果提供了有效格式的 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()));
}
}
破解基于列表的回购以避免在处理程序和 http return 类型时处理 data/APIs。
// 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();
}
}
正如我所见,代码是正确的。响应代码是 Bad request,因为您正在尝试将 "foo" 转换为 Integer,当它抛出异常时您将返回 Bad 请求响应,所以我认为它工作得很好。
如果您使用数据库中不存在的整数 ID,则答案必须是未找到的响应
您的括号位置错误,导致 swithIfEmpy 应用于 ServerResponse.ok()
发布者而不是 monoDemoPOJO
,将 return 替换为这个,它应该可以工作:
return monoDemoPOJO
.flatMap(demoPOJO -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).syncBody(demoPOJO))
.switchIfEmpty(ServerResponse.notFound().build());
WebFlux、反应式和处理程序的新手。我有东西 "working",但我不明白为什么下面的代码是 returning "okay" 空体,副 "not found".
澄清:关注的问题在DemoPOJOHandler.getById()的最后return声明中。 "short-circuit" 代码按预期工作(即 returns "Bad Request" 状态),但最终 return 语句的 "switchIfEmpty" 路径似乎没有得到执行如果 DemoPOJORepo.getById(int) returns Mono.empty().
(注意:我破解了一个基于列表的 "repo" 以避免在确定处理程序和 http return 类型时处理数据库。)
路由器实现(“/v1”是一组基于注释的 RESTful 端点)...
@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)));
}
}
处理程序实现已 "stripped down" 仅针对相关代码。我感觉大部分样式都是 "still imperative",但我试图将反应性内容放在 "makes the most sense".
的位置如果我在 URI 上提供了错误的值(即 "foo"),那么我会得到 http "bad request" returned。但是,如果提供了有效格式的 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()));
}
}
破解基于列表的回购以避免在处理程序和 http return 类型时处理 data/APIs。
// 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();
}
}
正如我所见,代码是正确的。响应代码是 Bad request,因为您正在尝试将 "foo" 转换为 Integer,当它抛出异常时您将返回 Bad 请求响应,所以我认为它工作得很好。 如果您使用数据库中不存在的整数 ID,则答案必须是未找到的响应
您的括号位置错误,导致 swithIfEmpy 应用于 ServerResponse.ok()
发布者而不是 monoDemoPOJO
,将 return 替换为这个,它应该可以工作:
return monoDemoPOJO
.flatMap(demoPOJO -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).syncBody(demoPOJO))
.switchIfEmpty(ServerResponse.notFound().build());