英文:
How to validate/process the Spring WebClient response?
问题
应用程序流程如下:
- Spring应用程序接收请求 -> {"id": "UUID"}
- 使用WebClient调用外部网络服务
- 验证从WebClient收到的第2步响应。如果验证通过,则返回true或false。
- 进行其他验证操作(通过调用其他进程或外部服务),然后将响应发送回用户。
这是我使用的WebClient(副本):
public Mono<Details> someRestCall(String name) {
return this.webClient.get().uri("/{id}/details", name)
.retrieve().bodyToMono(Details.class);
}
现在,我不想直接通过控制器将此Mono对象返回给客户端(如Angular应用程序),因为这是一个中间步骤。我想对从WebClient收到的响应运行一些验证。
我尝试过使用.block()
方法来检索函数,但根据响应式编程,这似乎是一种不好的做法(阻塞操作)。
另外,我无法理解如何使用.subscribe()
方法来检索响应对象并在其上运行验证/检查,如果验证通过则返回True
。
简单来说,与其从我的模块/验证代码返回Mono对象,我想返回一个普通的布尔值/Java对象。
我对响应式编程不太熟悉,有人可以帮助我解决这个问题吗?
英文:
So the app flow is like:
- Spring app receives the request -> {"id": "UUID"}
- Calls the external web service using the WebClient
- Validate the response received in step 2 from WebClient. Return true or false if validation passes.
- Do other validations operations(via calling other processes or ext services) and send back the response to the user.
This is the webclient which I am using(replica):
public Mono<Details> someRestCall(String name) {
return this.webClient.get().url("/{id}/details", name)
.retrieve().bodyToMono(Details.class);
}
Now I don't want to return this Mono object directly to the client(like the Angular app) via the controller, since this is an intermediary step. I want to run few validations on the response received from the WebClient.
I have tried the .block()
method to retrieve the function but it seems to be a bad practice as per the reactive programming. (blocking op)
Also, I am unable to understand how to use the .subscribe()
method to retrieve the response object and run validation/checks on it and return True
if the validation passes.
In simple terms, instead of returning a Mono object from my module/validation code, I want to return a normal boolean value/Java object.
I am new to reactive programming, can anyone please help me get this resolved?
答案1
得分: 1
带着一点努力,您可以在WebClient调用返回的POJO上使用基于JSR-303注解的验证。这里是一个最简示例:
@Component
public class MyClass {
final Validator validator;
MyClass(Validator validator) {
this.validator = validator;
}
<T> T validate(T obj) {
Set<ConstraintViolation<T>> violations = this.validator.validate(obj);
if (violations.size() > 0) {
throw new ResponseStatusException(INTERNAL_SERVER_ERROR, violations.toString());
}
return obj;
}
public Mono<Details> someRestCall(String name) {
return this.webClient.get()
.url("/{id}/details", name)
.retrieve()
.bodyToMono(Details.class)
.doOnNext(this::validate);
}
}
在实际应用中,您可能希望获得更好格式化的违规信息字符串,如果在多个地方进行验证,您可以将该逻辑提取到自己的类中。
英文:
With a little effort you can use JSR-303 annotation based validation on the POJOs that are returned by a WebClient call. Here's a minimal example:
@Component
public class MyClass {
final Validator validator;
MyClass(Validator validator) {
this.validator = validator;
}
<T> T validate(T obj) {
Set<ConstraintViolation<T>> violations = this.validator.validate(obj);
if (violations.size() > 0) {
throw new ResponseStatusException(INTERNAL_SERVER_ERROR, violations.toString());
}
return obj;
}
public Mono<Details> someRestCall(String name) {
return this.webClient.get()
.url("/{id}/details", name)
.retrieve()
.bodyToMono(Details.class)
.doOnNext(this::validate);
}
}
In practice you might want a better formatted violations string and if validation is done in a few places then you could lift that logic into its own class.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论