97 lines
3.0 KiB
Java
97 lines
3.0 KiB
Java
package de.catmangames.jsonfetcher;
|
|
|
|
import com.fasterxml.jackson.core.type.TypeReference;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
import java.io.IOException;
|
|
import java.net.http.HttpClient;
|
|
import java.net.http.HttpRequest;
|
|
import java.net.http.HttpResponse;
|
|
import java.time.Duration;
|
|
import java.util.Map;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
public class JsonFetcher {
|
|
|
|
private final String baseUrl;
|
|
private final HttpClient client;
|
|
private final ObjectMapper mapper;
|
|
private final long cacheTtlMs;
|
|
|
|
private final Map<String, long[]> cacheTimestamps = new ConcurrentHashMap<>();
|
|
private final Map<String, String> cacheData = new ConcurrentHashMap<>();
|
|
|
|
private JsonFetcher(Builder b) {
|
|
this.baseUrl = b.baseUrl.endsWith("/") ? b.baseUrl : b.baseUrl + "/";
|
|
this.client = HttpClient.newBuilder()
|
|
.connectTimeout(Duration.ofSeconds(b.timeoutSec))
|
|
.build();
|
|
this.mapper = new ObjectMapper();
|
|
this.cacheTtlMs = b.cacheTtlMs;
|
|
}
|
|
|
|
public <T> T fetch(String path, Class<T> type) throws IOException {
|
|
return mapper.readValue(getRaw(path), type);
|
|
}
|
|
|
|
public <T> T fetch(String path, TypeReference<T> type) throws IOException {
|
|
return mapper.readValue(getRaw(path), type);
|
|
}
|
|
|
|
private String getRaw(String path) throws IOException {
|
|
if (cacheTtlMs > 0 && cacheData.containsKey(path)) {
|
|
long age = System.currentTimeMillis() - cacheTimestamps.get(path)[0];
|
|
if (age < cacheTtlMs) return cacheData.get(path);
|
|
}
|
|
|
|
HttpRequest req = HttpRequest.newBuilder()
|
|
.uri(java.net.URI.create(baseUrl + path))
|
|
.GET()
|
|
.build();
|
|
|
|
try {
|
|
HttpResponse<String> res = client.send(req, HttpResponse.BodyHandlers.ofString());
|
|
if (res.statusCode() != 200)
|
|
throw new IOException("HTTP " + res.statusCode() + " für: " + path);
|
|
|
|
String body = res.body();
|
|
if (cacheTtlMs > 0) {
|
|
cacheData.put(path, body);
|
|
cacheTimestamps.put(path, new long[]{System.currentTimeMillis()});
|
|
}
|
|
return body;
|
|
} catch (InterruptedException e) {
|
|
Thread.currentThread().interrupt();
|
|
throw new IOException("Request unterbrochen", e);
|
|
}
|
|
}
|
|
|
|
public static Builder builder(String baseUrl) {
|
|
return new Builder(baseUrl);
|
|
}
|
|
|
|
public static class Builder {
|
|
private final String baseUrl;
|
|
private long timeoutSec = 5;
|
|
private long cacheTtlMs = 0;
|
|
|
|
public Builder(String baseUrl) {
|
|
this.baseUrl = baseUrl;
|
|
}
|
|
|
|
public Builder timeout(long seconds) {
|
|
this.timeoutSec = seconds;
|
|
return this;
|
|
}
|
|
|
|
/** TTL in Millisekunden, 0 = Cache deaktiviert */
|
|
public Builder cache(long ttlMs) {
|
|
this.cacheTtlMs = ttlMs;
|
|
return this;
|
|
}
|
|
|
|
public JsonFetcher build() {
|
|
return new JsonFetcher(this);
|
|
}
|
|
}
|
|
} |