我正在尝试通过使用Java + Spring + WebFlux来开始响应式编程。
我创建了一个微服务,它通过控制器生成一个Mono<Customer>
。
@RestController
@RequestMapping("/customers")
public class CustomerController {
@GetMapping("/{id}")
public Mono<Customer> customerById(@PathVariable String id){
return customerService.findById(id);
}
}
public class Customer {
public Customer(String id, String fullName) {
this.id = id;
this.fullName = fullName;
}
@Id
private String id;
@NotNull(message = "The name must not be null")
private String fullName;
private String email;
private String document;
}
另一个使用此Mono的微服务是上述类的副本,除了
Spring Validation
批注。在生产者上:
//Service Class
public Mono<Customer> findById(String id){
return Mono.just(new Customer(id, "Joseph"));
}
//Method on Controller
@RestController
@RequestMapping("v1/customers")
public class CustomerController {
@GetMapping("/{id}")
public Mono<Customer> customerById(@PathVariable String id){
return customerService.findById(id);
}
}
在
Customer Producer
端点上打开浏览器时,得到以下信息:{
id: "123",
fullName: "Joseph",
email: null,
document: null
}
当我在
GET
端点上调用Customer Consumer
时,得到一个HTTPCode = 500
以下是
Customer Consumer
上的服务层 private String BASE_URL = "http://localhost:8060/";
public Mono<Customer> findById(String id){
WebClient.Builder builder = WebClient.builder();
return builder
.baseUrl(BASE_URL)
.build()
.get()
.uri("customers/{id}", id)
.retrieve()
.bodyToMono(Customer.class);
}
我也曾尝试删除
.baseUrl(BASE_URL)
并将其隐藏在.uri()
中,但没有成功。我在消费者方面遇到的错误:
2019-12-01 22:21:45.910 ERROR 16788 --- [ctor-http-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [1510eee8] 500 Server Error for HTTP GET "/v1/customers/123"
java.lang.NullPointerException: null at com.poc.controller.CustomerController.findById(CustomerController.java:19) ~[classes/:na]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ? HTTP GET "/v1/customers/123" [ExceptionHandlingWebHandler]
Stack trace:
at com.poc.webportal.controller.CustomerController.findById(CustomerController.java:19) ~[classes/:na]
PS:我知道WebClient应该在
bean
上,但是例如,我只是在使其重构代码之前试图使其正常工作。 最佳答案
这很尴尬,但是我忘了在控制器上注入CustomerService
了。
因此,Autowired
解决了该问题。