英文:
How to extract data from a Mono object in Spring Webflux without blocking?
问题
以下是您提供的内容的翻译部分:
发送 POST 请求到我的 Spring 应用程序,使用 Postman。请求具有类似以下结构的 JSON 主体:
{
    "documents": [
        {
            "id": "1",
            "text": "Piece of text 1",
            "lang": "en"
        },
        {
            "id": "2",
            "text": "Piece of text 2",
            "lang": "en"
        }
    ],
    "domain": "hr",
    "text_key": "text"
}
我已经设置了一个方法来处理这些 POST 请求,我需要能够从请求体中提取上述 JSON 数据,而不阻塞。我现在的方法大致如下:
public void requestBody(ServerRequest request) {
    Mono<String> bodyData = request.bodyToMono(String.class);
    System.out.println("\nsubscribing to the Mono.....");
    bodyData.subscribeOn(Schedulers.newParallel("requestBody")).subscribe(value -> {
        log.debug(String.format("%n value consumed: %s", value));
    });
}
但是,这什么也没有做。我尝试查看了 https://stackoverflow.com/questions/52870517/spring-reactive-get-body-jsonobject-using-serverrequest 和 https://stackoverflow.com/questions/54531407/getting-string-body-from-spring-serverrequest/54531866 中的答案,但没有成功。请帮忙解决。
感谢 https://stackoverflow.com/users/1189885/chrylis-cautiouslyoptimistic
根据您的答案,这是我尝试的内容:
request.bodyToMono(String.class).map(
    (String rqBody) -> {
        setRequestBody(rqBody);
        return ServerResponse.status(HttpStatus.CREATED).contentType(APPLICATION_JSON).body(rqBody, Object.class);
    }
);
setRequestBody() 是将全局字符串变量设置为请求体。像这样:
public void setRequestBody(String rqBody){
    System.out.println("\nset request body called with: " + rqBody);
    request_body = rqBody;
}
然而,全局变量 request_body 仍然是空的。
根据您最新的评论,这是我尝试的内容:
RedissonClient redisson = Redisson.create();
RBucket<Object> bucket = redisson.getBucket("requestKey");
request.bodyToMono(String.class).doOnNext(
    (String rqBody) -> {
        bucket.set(rqBody);
    }
);
当我进入 Redis-cli 并尝试 get requestKey 时,它会返回 nil。
英文:
I am sending a POST request to my Spring application using Postman. The request has a JSON body that looks something like this:
{
        "documents": [
            {
                "id": "1",
                "text": "Piece of text 1",
                "lang": "en"
            },
            {
                "id": "2",
                "text": "Piece of text 2",
                "lang": "en"
            }
        ],
        "domain": "hr",
        "text_key": "text"
    }
I have a method set up to handle these POST requests and I need to be able to extract the above JSON data from the request body WITHOUT BLOCKING. The method I have now looks something like this:
public void requestBody(ServerRequest request) {
      Mono<String> bodyData = request.bodyToMono(String.class);
      System.out.println("\nsubscribing to the Mono.....");
      bodyData.subscribeOn(Schedulers.newParallel("requestBody")).subscribe(value -> {
        log.debug(String.format("%n value consumed: %s" ,value));
      });
}
However, this does nothing. I tried looking at the answers in https://stackoverflow.com/questions/52870517/spring-reactive-get-body-jsonobject-using-serverrequest
AND
https://stackoverflow.com/questions/54531407/getting-string-body-from-spring-serverrequest/54531866  but to no avail. Please help out.
thanks https://stackoverflow.com/users/1189885/chrylis-cautiouslyoptimistic
According to your answer, this is what I'm trying:
    request.bodyToMono(String.class).map(
        (String rqBody) -> {
          setRequestBody(rqBody);
          return ServerResponse.status(HttpStatus.CREATED).contentType(APPLICATION_JSON).body(rqBody, Object.class);
        }
      );
setRequestBody() is setting a global string variable to be the request body. Like this:
  public void setRequestBody (String rqBody){
    System.out.println("\nset request body called with: " + rqBody);
    request_body=rqBody;
  }
However, the global request_body variable is still null.
This is what I'm trying to do as per your latest comment:
    RedissonClient redisson = Redisson.create();
    RBucket<Object> bucket = redisson.getBucket("requestKey");
      request.bodyToMono(String.class).doOnNext(
        (String rqBody) -> {
          bucket.set(rqBody);
        }
      );
When I go into Redis-cli and try to get requestKey, it gives me nil
答案1
得分: 3
你 不能 这样做;这正是响应式模型的完整含义。相反,通常应使用诸如 map(通过应用函数来修改值)或 doOnNext(执行某些操作但不返回结果)之类的操作。
如果使用类似于 Spring WebFlux 的响应式执行模型,你可以直接从控制器方法返回一个 Mono<Whatever>,Spring 会为你“提取”数据。
英文:
You can't; that's the entire meaning of the reactive model. Instead, you should usually use operations like map (to modify the value by applying a function) or doOnNext (to take some action but not return a result).
If using a reactive execution model, such as Spring WebFlux, you directly return a Mono<Whatever> from your controller method, and Spring takes care of "extracting" the data for you.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论