首页 > 解决方案 > 如何验证/处理 Spring WebClient 响应?

问题描述

所以应用流程是这样的:

  1. Spring 应用收到请求 -> {"id": "UUID"}
  2. 使用 WebClient 调用外部 Web 服务
  3. 验证在步骤 2 中从 WebClient 收到的响应。如果验证通过,则返回 true 或 false。
  4. 执行其他验证操作(通过调用其他进程或 ext 服务)并将响应发送回用户。

这是我正在使用的网络客户端(副本):

public Mono<Details> someRestCall(String name) {
        return this.webClient.get().url("/{id}/details", name)
                        .retrieve().bodyToMono(Details.class);
    }

现在我不想通过控制器将此 Mono 对象直接返回给客户端(如 Angular 应用程序),因为这是一个中间步骤。我想对从 WebClient 收到的响应进行一些验证。

我已经尝试过.block()检索函数的方法,但根据反应式编程,这似乎是一种不好的做法。(阻塞操作)此外,我无法理解如何使用该.subscribe()方法来检索响应对象并对其运行验证/检查并True在验证通过时返回。

简单来说,我不想从我的模块/验证代码返回 Mono 对象,而是想返回一个普通的布尔值/Java 对象。

我是响应式编程的新手,谁能帮我解决这个问题?

标签: javaspringspring-bootreactive-programming

解决方案


稍加努力,您就可以对 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);
  }
}

在实践中,您可能需要格式更好的违规字符串,如果在几个地方完成验证,那么您可以将该逻辑提升到自己的类中。


推荐阅读