【问题标题】:How to parse a Spring 5 WebClient response in a non-blocking way?如何以非阻塞方式解析 Spring 5 WebClient 响应?
【发布时间】:2018-11-12 12:48:39
【问题描述】:

我正在使用 Spring WebFlux WebClient 从外部 API 检索数据,如下所示:

public WeatherWebClient() {
    this.weatherWebClient = WebClient.create("http://api.openweathermap.org/data/2.5/weather");
}

public Mono<String> getWeatherByCityName(String cityName) {
    return weatherWebClient
            .get()
            .uri(uriBuilder -> uriBuilder
                                .queryParam("q", cityName)
                                .queryParam("units", "metric")
                                .queryParam("appid", API_KEY)
                                .build())
            .accept(MediaType.APPLICATION_JSON)
            .retrieve()
            .bodyToMono(String.class);
}

这可以正常工作并产生如下响应:

{
    "coord":{
        "lon":-47.06,
        "lat":-22.91
    },
    "weather":[
    {
        "id":800,
        "main":"Clear",
        "description":"clear sky",
        "icon":"01d"
    }
    ],
    "base":"stations",
    "main":{
        "temp":16,
        "pressure":1020,
        "humidity":67,
        "temp_min":16,
        "temp_max":16
    },
    "visibility":10000,
    "wind":{
        "speed":1,
        "deg":90
    },
    "clouds":{
        "all":0
    },
    "dt":1527937200,
    "sys":{
        "type":1,
        "id":4521,
        "message":0.0038,
        "country":"BR",
        "sunrise":1527932532,
        "sunset":1527971422
    },
    "id":3467865,
    "name":"Campinas",
    "cod":200
}

但我只对 "temp" 属性(main -> temp)感兴趣。如何转换响应(例如使用 Jackson 的 ObjectMapper)以反应/非阻塞方式仅返回 "temp" 值?

我知道第一件事是将“.retrieve()”替换为“.exchange()”,但我不知道如何使它工作。

PS:这是我的第一个问题。如果我做错了什么或者您需要更多详细信息,请告诉我。

谢谢!

【问题讨论】:

    标签: functional-programming jackson reactive-programming spring-webflux project-reactor


    【解决方案1】:

    您需要创建一个与服务器发送的响应相对应的类型。一个非常小的例子可能是这样的:

    @JsonIgnoreProperties(ignoreUnknown = true)
    public class WeatherResponse {
        public MainWeatherData main;
    }
    

    MainWeatherData 类可以是:

    @JsonIgnoreProperties(ignoreUnknown = true)
    public class MainWeatherData {
        public String temp;
    }
    

    最后,你可以在bodyToMono 中使用WeatherResponse

    ...
       .retrieve()
       .bodyToMono(WeatherResponse.class);
    

    @JsonIgnoreProperties(ignoreUnknown = true)annotation 指示 Jackson 在遇到您的 POJO 中不存在的 JSON 字符串中的任何值时不要给出任何错误。

    您可以使用链式map 运算符访问WeatherResponseobject:

    getWeatherByCityName(cityName)
         .map(weatherResponse -> weatherResponse.main.temp)  
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-20
    • 2020-11-23
    • 1970-01-01
    • 2023-01-30
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    相关资源
    最近更新 更多