使用 Spring boot webflux reactive 记录未持久保存到 R2DB 中
Record not persisted into R2DB using Spring boot webflux reactive
我正在尝试使用反应式构建应用程序。最初我曾经得到正确的响应,但在修改代码后,记录没有保存到数据库中,但是当我更改逻辑以修改响应主体时,我看到了成功的响应,但在数据库中没有找到记录,也看不到日志错误。
修改前的代码:
public Mono<ServerResponse> createCustomer(ServerRequest serverRequest) {
return serverRequest.bodyToMono(Customer.class).flatMap(customer -> {
ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(customerRepository.save(customer), Customer.class);
});
}
但我想 return 对所有 API 调用的通用 API 响应并修改代码如下:
public Mono<ServerResponse> createCustomer(ServerRequest serverRequest) {
Response response = new Response();
return serverRequest.bodyToMono(Customer.class).flatMap(customer -> {
saveCustomer(customer,apiResponse);
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(apiResponse), Response.class);
}).doOnError(err -> {
log.error("Exception while creating customr record", err);
}).onErrorResume(err -> {
apiResponse.setError(new Error(err.getMessage(),err.getCause()));
return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR)
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(apiResponse), ApiResponse.class);
});
}
public Response saveCustomer(Customer customer,Response apiResponse){
customerRepository.save(customer);
apiResponse.setCode("0");
apiResponse.setMessage("Successfully Created customer");
return apiResponse;
}
如有任何想法,请不胜感激。
您是否使用像 R2DBC 这样的反应式 JDBC 驱动程序,以及反应式存储库?如果不是更好,您应该这样做,因为它会使完整的堆栈具有反应性。
您可以使用 R2DBC 驱动程序 maven 和 Spring Data R2DBC for Reactive Repository
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>dev.miku</groupId>
<artifactId>r2dbc-mysql</artifactId>
<version>0.8.2.RELEASE</version>
</dependency>
然后你将不得不使用 r2dbc 连接而不是 JDBC 这样的连接工厂。
@Bean
public ConnectionFactory connectionFactory() {
ConnectionFactory connectionFactory = ConnectionFactories.get(
"r2dbcs:mysql://localhost:3306/dbname?"+
"zeroDate=use_round&"+
"sslMode=disabled");
return connectionFactory;
}
完成此配置后,您可以从 Spring Data R2DBC 扩展 ReactiveCrudRepository 并创建您自己的存储库,就像这样
public interface UserRepository extends ReactiveCrudRepository<User, Long> {
@Query("SELECT * FROM user WHERE firstname = :firstname")
Flux<User> findByFirstName(String firstname);
}
请查看 this 博客了解更多信息。
我怀疑这段代码 - customerRepository.save(customer);
如果你使用的是R2DBC,save方法不会直接保存。它将 return 一种发布者类型。必须订阅才能使其正常工作。否则不会插入记录。
你需要这样做!
customerRepository.save(customer).subscribe();
然而,像这样直接订阅并不是一个好习惯。相反,你应该做这样的事情。
public Mono<Response> saveCustomer(Customer customer,Response apiResponse){
return customerRepository.save(customer)
.map(c -> {
apiResponse.setCode("0");
apiResponse.setMessage("Successfully Created customer");
return apiResponse;
});
}
然后修改你的
return serverRequest.bodyToMono(Customer.class).flatMap(customer -> {.....
像这样的代码。
return serverRequest.bodyToMono(Customer.class)
.flatMap(customer -> saveCustomer(customer, response))
.flatMap(r -> ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(r), Response.class))
我正在尝试使用反应式构建应用程序。最初我曾经得到正确的响应,但在修改代码后,记录没有保存到数据库中,但是当我更改逻辑以修改响应主体时,我看到了成功的响应,但在数据库中没有找到记录,也看不到日志错误。
修改前的代码:
public Mono<ServerResponse> createCustomer(ServerRequest serverRequest) {
return serverRequest.bodyToMono(Customer.class).flatMap(customer -> {
ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(customerRepository.save(customer), Customer.class);
});
}
但我想 return 对所有 API 调用的通用 API 响应并修改代码如下:
public Mono<ServerResponse> createCustomer(ServerRequest serverRequest) {
Response response = new Response();
return serverRequest.bodyToMono(Customer.class).flatMap(customer -> {
saveCustomer(customer,apiResponse);
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(apiResponse), Response.class);
}).doOnError(err -> {
log.error("Exception while creating customr record", err);
}).onErrorResume(err -> {
apiResponse.setError(new Error(err.getMessage(),err.getCause()));
return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR)
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(apiResponse), ApiResponse.class);
});
}
public Response saveCustomer(Customer customer,Response apiResponse){
customerRepository.save(customer);
apiResponse.setCode("0");
apiResponse.setMessage("Successfully Created customer");
return apiResponse;
}
如有任何想法,请不胜感激。
您是否使用像 R2DBC 这样的反应式 JDBC 驱动程序,以及反应式存储库?如果不是更好,您应该这样做,因为它会使完整的堆栈具有反应性。 您可以使用 R2DBC 驱动程序 maven 和 Spring Data R2DBC for Reactive Repository
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>dev.miku</groupId>
<artifactId>r2dbc-mysql</artifactId>
<version>0.8.2.RELEASE</version>
</dependency>
然后你将不得不使用 r2dbc 连接而不是 JDBC 这样的连接工厂。
@Bean
public ConnectionFactory connectionFactory() {
ConnectionFactory connectionFactory = ConnectionFactories.get(
"r2dbcs:mysql://localhost:3306/dbname?"+
"zeroDate=use_round&"+
"sslMode=disabled");
return connectionFactory;
}
完成此配置后,您可以从 Spring Data R2DBC 扩展 ReactiveCrudRepository 并创建您自己的存储库,就像这样
public interface UserRepository extends ReactiveCrudRepository<User, Long> {
@Query("SELECT * FROM user WHERE firstname = :firstname")
Flux<User> findByFirstName(String firstname);
}
请查看 this 博客了解更多信息。
我怀疑这段代码 - customerRepository.save(customer);
如果你使用的是R2DBC,save方法不会直接保存。它将 return 一种发布者类型。必须订阅才能使其正常工作。否则不会插入记录。
你需要这样做!
customerRepository.save(customer).subscribe();
然而,像这样直接订阅并不是一个好习惯。相反,你应该做这样的事情。
public Mono<Response> saveCustomer(Customer customer,Response apiResponse){
return customerRepository.save(customer)
.map(c -> {
apiResponse.setCode("0");
apiResponse.setMessage("Successfully Created customer");
return apiResponse;
});
}
然后修改你的
return serverRequest.bodyToMono(Customer.class).flatMap(customer -> {.....
像这样的代码。
return serverRequest.bodyToMono(Customer.class)
.flatMap(customer -> saveCustomer(customer, response))
.flatMap(r -> ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(r), Response.class))