Spring Webclient:illegalargumentexception 没有足够的变量来展开'comment_count'

Spring Webclient : illegalargumentexception not enough variables to expand 'comment_count'

我正在使用 spring webclient 制作一个 Facebook 图 api 请求 url 包含 {comment_count}

但是,得到这个异常

java.lang.IllegalArgumentException: Not enough variable values available to expand reactive spring

代码段:

import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;

import reactor.core.publisher.Mono;

@Component
public class Whosebug {

    WebClient client = WebClient.create();

    public Mono<Post> fetchPost(String url) {
        // Url contains "comments{comment_count}"
        return client.get().uri(url).retrieve()
                .bodyToMono(Post.class);
    }
}

我知道 resttemplate 的解决方案,但我需要使用 spring webclient。

您可以使用 UriComponentsBuilder 创建您的 URL,如下所示

 webClient.get().uri(getFacebookGraphURI(3)).retrieve().bodyToMono(Object.class);

private URI getFacebookGraphURI(int comments){
   return UriComponentsBuilder.fromHttpUrl("https://graph.facebook.com")
        .pathSegment("v3.2", "PAGE_ID", "posts").queryParam("fields", "comments{comment_count}")
        .queryParam("access_token", "acacaaac").build(comments);

  }

int commentsCount = 3; webClient.get().uri(UriComponentsBuilder.fromHttpUrl("https://graph.facebook.com") .pathSegment("v3.2", "PAGE_ID", "posts").queryParam("fields", "comments{comment_count}") .queryParam("access_token", "acacaaac").build().toString(),commentsCount).retrieve().bodyToMono(Object.class);

我使用的解决方案是禁用DefaultUriBuilderFactory中的编码

val urlBuilderFactory = DefaultUriBuilderFactory("https://foo.bar.com").apply {
    encodingMode = EncodingMode.NONE
}

val wc = wcb
    .clone()
    .uriBuilderFactory(urlBuilderFactory)
    .build()

它在 Kotlin 中,在 Java 中你只需要使用 DefaultUriBuilderFactory#setEncodingMode(EncodingMode)NONE 作为参数。

由于这种行为变化,您必须自己对查询参数进行编码。为此,我使用

val query = URLEncoder.encode(query_as_string, StandardCharsets.UTF_8.toString())

我可以这样调用:

wc
                .get()
                .uri { it
                        .path(graphqlEndpoints)
                        .queryParam("variables", query)
                        .build()
                }
                .retrieve()
                .bodyToFlux<String>()
                ...