1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono;
import java.math.BigDecimal; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors;
@RestController @RequestMapping("/api/web-client") public class WebClientController {
private static final Logger log = LoggerFactory.getLogger(WebClientController.class);
private final WebClient webClient;
public WebClientController(WebClient.Builder builder) { this.webClient = builder.baseUrl("https://api.open-meteo.com/v1/forecast").build(); }
private CompletableFuture<OpenMeteoResponse> getCMA(BigDecimal lat, BigDecimal lon) { log.error("start cma {}", Thread.currentThread().getName()); long startTime = System.currentTimeMillis(); CompletableFuture<OpenMeteoResponse> cache = this.webClient.get().uri( uriBuilder -> uriBuilder .queryParam("latitude", lat) .queryParam("longitude", lon) .queryParam("hourly", "temperature_2m") .queryParam("timezone", "Asia/Shanghai") .queryParam("models", "cma_grapes_global") .queryParam("forecast_days", "1") .build() ).retrieve().bodyToMono(OpenMeteoResponse.class).toFuture(); long endTime = System.currentTimeMillis(); log.error("end cma {}", endTime - startTime); return cache; }
private CompletableFuture<OpenMeteoResponse> getGFS(BigDecimal lat, BigDecimal lon) { log.error("start gfs {}", Thread.currentThread().getName()); long startTime = System.currentTimeMillis(); CompletableFuture<OpenMeteoResponse> cache = this.webClient.get().uri( uriBuilder -> uriBuilder .queryParam("latitude", lat) .queryParam("longitude", lon) .queryParam("hourly", "temperature_2m") .queryParam("timezone", "Asia/Shanghai") .queryParam("models", "gfs_global") .queryParam("forecast_days", "1") .build() ).retrieve().bodyToMono(OpenMeteoResponse.class).toFuture(); long endTime = System.currentTimeMillis(); log.error("end gfs {}", endTime - startTime); return cache; }
private CompletableFuture<OpenMeteoResponse> getIcon(BigDecimal lat, BigDecimal lon) { log.error("start gfs {}", Thread.currentThread().getName()); long startTime = System.currentTimeMillis(); CompletableFuture<OpenMeteoResponse> cache = this.webClient.get().uri( uriBuilder -> uriBuilder .queryParam("latitude", lat) .queryParam("longitude", lon) .queryParam("hourly", "temperature_2m") .queryParam("timezone", "Asia/Shanghai") .queryParam("models", "icon_global") .queryParam("forecast_days", "1") .build() ).retrieve().bodyToMono(OpenMeteoResponse.class).toFuture(); long endTime = System.currentTimeMillis(); log.error("end gfs {}", endTime - startTime); return cache; }
private CompletableFuture<OpenMeteoResponse> getGraphCast(BigDecimal lat, BigDecimal lon) { log.error("start gfs {}", Thread.currentThread().getName()); long startTime = System.currentTimeMillis(); CompletableFuture<OpenMeteoResponse> cache = this.webClient.get().uri( uriBuilder -> uriBuilder .queryParam("latitude", lat) .queryParam("longitude", lon) .queryParam("hourly", "temperature_2m") .queryParam("timezone", "Asia/Shanghai") .queryParam("models", "gfs_graphcast025") .queryParam("forecast_days", "1") .build() ).retrieve().bodyToMono(OpenMeteoResponse.class).toFuture(); long endTime = System.currentTimeMillis(); log.error("end gfs {}", endTime - startTime); return cache; }
public Mono<List<OpenMeteoResponse>> getMergedData(BigDecimal lat, BigDecimal lon) { List<CompletableFuture<OpenMeteoResponse>> futures = List.of( getCMA(lat, lon), getGFS(lat, lon), getIcon(lat, lon), getGraphCast(lat, lon) );
CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
return Mono.fromFuture(allOf.thenApply(v -> futures.stream() .map(CompletableFuture::join) .collect(Collectors.toList()))); }
@GetMapping private Mono<List<OpenMeteoResponse>> getOpenMeteoResponse(@RequestParam(defaultValue = "52.5625") BigDecimal lat, @RequestParam(defaultValue = "13.375") BigDecimal lon) { return getMergedData(lat, lon); }
}
|