Initialize project with JsonFetcher implementation, Gradle setup, and IntelliJ configuration.
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user