Spring Webclient:非法参数异常没有足够的变量来扩展'comment_count'

时间:2019-10-01 06:05:48

标签: spring-boot facebook-graph-api spring-webflux illegalargumentexception spring-webclient

我正在使用Spring Webclient发出带有包含{comment_count}的URL的Facebook图形api请求

但是,出现此异常

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 Stackoverflow {

    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。

2 个答案:

答案 0 :(得分:5)

您可以使用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);

  }

OR

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

答案 1 :(得分:0)

我使用的解决方案是禁用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>()
                ...