Spring 带注释的控制器有效,但 router/handler 方法似乎无法从 *ServerRequest* 检索 *Mono<>*
Spring annotated controller works, but router/handler approach does not appear to retrieve *Mono<>* from *ServerRequest*
仍在玩弄并试图理解 Spring 的 Webflux 和 Reactor 的 "how"。
当使用带注释的控制器时,以下成功地将新的 DemoPOJO 添加到 repo(即 POST 发出在 //localhost:8080/v1/DemoPOJO)。
但是,当使用 router/handler 实现发出相同的 POST 时(即 //localhost:8080/v2/DemoPOJO), request.bodyToMono(DemoPOJO.class) 似乎没有检索到 DemoPOJO 实例来自 ServerRequest(即未调用 DemoPOJO.printme())。
我是 "working on this",但我想看看是否有人可以帮助我 "get there faster"。对于它的价值,router/handler 实现(即 GET)不需要从 DemoPOJO ServerRequest 正在工作。
RESTful 个使用注解的端点...
@RestController
public class DemoPOJOController {
private Logger logger = LoggerFactory.getLogger(DemoPOJOHandler.class);
@Autowired
DemoPOJOService service;
@RequestMapping(method = POST, value = "/v1/DemoPOJO")
public Mono<Boolean> addDemoPOJO(@RequestBody DemoPOJO demoPOJO) {
logger.debug("DemoPOJOController.addDemoPOJO( {} )", demoPOJO.getId());
return service.add(demoPOJO);
}
}
"Router"部分对应router/handler实现...
@Configuration
public class DemoPOJORouter {
private Logger logger = LoggerFactory.getLogger(DemoPOJOHandler.class);
@Bean
public RouterFunction<ServerResponse> route(DemoPOJOHandler requestHandler) {
logger.debug("DemoPOJORouter.route( DemoPOJOHandler )");
return nest(path("/v2"),
nest(accept(APPLICATION_JSON),
RouterFunctions.route(RequestPredicates.POST("/DemoPOJO"), requestHandler::add)));
}
}
"Handler" router/handler 实现的一部分...
@Component
public class DemoPOJOHandler {
public static final String PATH_VAR_ID = "id";
private Logger logger = LoggerFactory.getLogger(DemoPOJOHandler.class);
@Autowired
private DemoPOJOService service;
public Mono<ServerResponse> add(ServerRequest request) {
logger.debug("DemoPOJOHandler.add( ServerRequest )");
request.bodyToMono(DemoPOJO.class).doOnSuccess(DemoPOJO::printMe);
return ServerResponse.ok().build();
}
}
DemoPOJORepo 实现(希望通过避免 "real" 存储库来简化我的学习体验)...
@Component
public class DemoPOJORepo {
private static final int NUM_OBJS = 15;
private Logger logger = LoggerFactory.getLogger(DemoPOJORepo.class);
private static DemoPOJORepo demoRepo = null;
private Map<Integer, DemoPOJO> demoPOJOMap;
private DemoPOJORepo() {
logger.debug("DemoPOJORepo.DemoPOJORepo()");
initMap();
}
public boolean add(DemoPOJO demoPOJO) {
logger.debug("DemoPOJORepo.add( DemoPOJO )");
boolean pojoAdded = false;
if (!demoPOJOMap.containsKey(demoPOJO.getId())) {
logger.debug("DemoPOJORepo.add( DemoPOJO ) -> adding for id {}", demoPOJO.getId());
demoPOJOMap.put(demoPOJO.getId(), demoPOJO);
pojoAdded = true;
}
return pojoAdded;
}
private void initMap() {
logger.debug("DemoPOJORepo.initMap()");
demoPOJOMap = new TreeMap<Integer, DemoPOJO>();
for (int ndx = 1; ndx < (NUM_OBJS + 1); ndx++) {
demoPOJOMap.put(ndx, new DemoPOJO(ndx, "foo_" + ndx, ndx + 100));
}
}
}
正在操作的对象...
public class DemoPOJO {
private Logger logger = LoggerFactory.getLogger(DemoPOJOHandler.class);
public static final String DEF_NAME = "DEFAULT NAME";
public static final int DEF_VALUE = 99;
private int id;
private String name;
private int value;
public DemoPOJO(int id) {
this(id, DEF_NAME, DEF_VALUE);
}
public DemoPOJO(@JsonProperty("id") int id, @JsonProperty("name") String name, @JsonProperty("value") int value) {
logger.debug("DemoPOJO.DemoPOJO( {}, {}, {} )", id, name, value);
this.id = id;
this.name = name;
this.value = value;
}
// getters and setters go here
public void printMe() {
logger.debug("DemoPOJO.printMe()");
System.out.printf("id->%d, name->%s, value->%d%n", id, name, value);
}
}
我是在猜测,因为我是用手机写的。但我认为这是你的问题。
request.bodyToMono(DemoPOJO.class).doOnSuccess(DemoPOJO::printMe);
return ServerResponse.ok().build();
您认为命令式,第一行将被执行,然后是第二行,这在 webflux 中不是这种情况。你必须考虑事件回调。
return request.bodyToMono(DemoPOJO.class)
.doOnSuccess(DemoPOJO::printMe)
.thenReturn(ServerResponse.ok().build());
我想就是这样,但我可能错了。
仍在玩弄并试图理解 Spring 的 Webflux 和 Reactor 的 "how"。
当使用带注释的控制器时,以下成功地将新的 DemoPOJO 添加到 repo(即 POST 发出在 //localhost:8080/v1/DemoPOJO)。
但是,当使用 router/handler 实现发出相同的 POST 时(即 //localhost:8080/v2/DemoPOJO), request.bodyToMono(DemoPOJO.class) 似乎没有检索到 DemoPOJO 实例来自 ServerRequest(即未调用 DemoPOJO.printme())。
我是 "working on this",但我想看看是否有人可以帮助我 "get there faster"。对于它的价值,router/handler 实现(即 GET)不需要从 DemoPOJO ServerRequest 正在工作。
RESTful 个使用注解的端点...
@RestController
public class DemoPOJOController {
private Logger logger = LoggerFactory.getLogger(DemoPOJOHandler.class);
@Autowired
DemoPOJOService service;
@RequestMapping(method = POST, value = "/v1/DemoPOJO")
public Mono<Boolean> addDemoPOJO(@RequestBody DemoPOJO demoPOJO) {
logger.debug("DemoPOJOController.addDemoPOJO( {} )", demoPOJO.getId());
return service.add(demoPOJO);
}
}
"Router"部分对应router/handler实现...
@Configuration
public class DemoPOJORouter {
private Logger logger = LoggerFactory.getLogger(DemoPOJOHandler.class);
@Bean
public RouterFunction<ServerResponse> route(DemoPOJOHandler requestHandler) {
logger.debug("DemoPOJORouter.route( DemoPOJOHandler )");
return nest(path("/v2"),
nest(accept(APPLICATION_JSON),
RouterFunctions.route(RequestPredicates.POST("/DemoPOJO"), requestHandler::add)));
}
}
"Handler" router/handler 实现的一部分...
@Component
public class DemoPOJOHandler {
public static final String PATH_VAR_ID = "id";
private Logger logger = LoggerFactory.getLogger(DemoPOJOHandler.class);
@Autowired
private DemoPOJOService service;
public Mono<ServerResponse> add(ServerRequest request) {
logger.debug("DemoPOJOHandler.add( ServerRequest )");
request.bodyToMono(DemoPOJO.class).doOnSuccess(DemoPOJO::printMe);
return ServerResponse.ok().build();
}
}
DemoPOJORepo 实现(希望通过避免 "real" 存储库来简化我的学习体验)...
@Component
public class DemoPOJORepo {
private static final int NUM_OBJS = 15;
private Logger logger = LoggerFactory.getLogger(DemoPOJORepo.class);
private static DemoPOJORepo demoRepo = null;
private Map<Integer, DemoPOJO> demoPOJOMap;
private DemoPOJORepo() {
logger.debug("DemoPOJORepo.DemoPOJORepo()");
initMap();
}
public boolean add(DemoPOJO demoPOJO) {
logger.debug("DemoPOJORepo.add( DemoPOJO )");
boolean pojoAdded = false;
if (!demoPOJOMap.containsKey(demoPOJO.getId())) {
logger.debug("DemoPOJORepo.add( DemoPOJO ) -> adding for id {}", demoPOJO.getId());
demoPOJOMap.put(demoPOJO.getId(), demoPOJO);
pojoAdded = true;
}
return pojoAdded;
}
private void initMap() {
logger.debug("DemoPOJORepo.initMap()");
demoPOJOMap = new TreeMap<Integer, DemoPOJO>();
for (int ndx = 1; ndx < (NUM_OBJS + 1); ndx++) {
demoPOJOMap.put(ndx, new DemoPOJO(ndx, "foo_" + ndx, ndx + 100));
}
}
}
正在操作的对象...
public class DemoPOJO {
private Logger logger = LoggerFactory.getLogger(DemoPOJOHandler.class);
public static final String DEF_NAME = "DEFAULT NAME";
public static final int DEF_VALUE = 99;
private int id;
private String name;
private int value;
public DemoPOJO(int id) {
this(id, DEF_NAME, DEF_VALUE);
}
public DemoPOJO(@JsonProperty("id") int id, @JsonProperty("name") String name, @JsonProperty("value") int value) {
logger.debug("DemoPOJO.DemoPOJO( {}, {}, {} )", id, name, value);
this.id = id;
this.name = name;
this.value = value;
}
// getters and setters go here
public void printMe() {
logger.debug("DemoPOJO.printMe()");
System.out.printf("id->%d, name->%s, value->%d%n", id, name, value);
}
}
我是在猜测,因为我是用手机写的。但我认为这是你的问题。
request.bodyToMono(DemoPOJO.class).doOnSuccess(DemoPOJO::printMe);
return ServerResponse.ok().build();
您认为命令式,第一行将被执行,然后是第二行,这在 webflux 中不是这种情况。你必须考虑事件回调。
return request.bodyToMono(DemoPOJO.class)
.doOnSuccess(DemoPOJO::printMe)
.thenReturn(ServerResponse.ok().build());
我想就是这样,但我可能错了。