Commit 3e70e01d by patryk

Implementacja pobierania walut z serwerów NBP

parent 964cb424
package waluty;
public class BladAplikacji extends Exception {
public BladAplikacji() {
super();
}
public BladAplikacji(String message, Throwable cause) {
super(message, cause);
}
public BladAplikacji(String message) {
super(message);
}
public BladAplikacji(Throwable cause) {
super(cause);
}
}
package waluty;
import java.time.LocalDate;
public abstract class Pobieranie {
protected static final String ADRES_BAZOWY = "http://api.nbp.pl/api/exchangerates/tables";
public abstract TabelaWalut pobierzBiezaceKursy() throws BladAplikacji;
public abstract TabelaWalut pobierzArchiwalneKursy(String data) throws BladAplikacji;
// Jeśli jakaś część implementacji jest wpólna dla wszystkich podklas,
// to można umieścić ja w klasie abstrakcyjnej
public TabelaWalut pobierzArchiwalneKursy(LocalDate data) throws BladAplikacji {
return pobierzArchiwalneKursy(data.toString());
}
// fabryka nowych obiektów
public static Pobieranie utworz(String format) {
return switch(format.toUpperCase()) {
case "XML" -> new PobieranieXML();
case "JSON" -> new PobieranieJSON();
default -> throw new IllegalArgumentException("Nieznany format " + format);
};
}
}
package waluty;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.time.LocalDate;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.json.JsonReader;
import jakarta.json.JsonValue;
public class PobieranieJSON extends Pobieranie {
public TabelaWalut pobierzBiezaceKursy() throws BladAplikacji {
String adres = ADRES_BAZOWY + "/A?format=json";
return pobierzZAdresu(adres);
}
public TabelaWalut pobierzArchiwalneKursy(String data) throws BladAplikacji {
return pobierzZAdresu(ADRES_BAZOWY + "/A/" + data + "?format=json");
}
private TabelaWalut pobierzZAdresu(String adres) throws BladAplikacji {
try {
HttpClient httpClient = HttpClient.newHttpClient();
URI uri = new URI(adres);
HttpRequest request = HttpRequest.newBuilder(uri).build();
HttpResponse<InputStream> response = httpClient.send(request, BodyHandlers.ofInputStream());
if(response.statusCode() != 200) {
throw new BladAplikacji("Zapytanie HTTP zwróciło " + response.statusCode());
}
// dane odebrane z sieci "parsujemy" jako JSON
try(JsonReader reader = Json.createReader(response.body())) {
JsonArray array = reader.readArray();
JsonObject tabela = array.getJsonObject(0);
String no = tabela.getString("no");
LocalDate effectiveDate = LocalDate.parse(tabela.getString("effectiveDate"));
TabelaWalut tabelaWalut = new TabelaWalut(no, effectiveDate);
JsonArray rates = tabela.getJsonArray("rates");
for(JsonValue rate : rates) {
JsonObject rateObj = rate.asJsonObject();
Waluta waluta = new Waluta(rateObj.getString("code"),
rateObj.getString("currency"),
rateObj.getJsonNumber("mid").bigDecimalValue());
tabelaWalut.addRate(waluta);
}
return tabelaWalut;
}
} catch (URISyntaxException | IOException | InterruptedException e) {
throw new BladAplikacji(e);
}
}
}
package waluty;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class PobieranieXML extends Pobieranie {
private HttpClient httpClient = HttpClient.newHttpClient();
private DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
private XPathFactory xpf = XPathFactory.newInstance();
@Override
public TabelaWalut pobierzBiezaceKursy() throws BladAplikacji {
return pobierzZAdresu(ADRES_BAZOWY + "/A" + "?format=xml");
}
@Override
public TabelaWalut pobierzArchiwalneKursy(String data) throws BladAplikacji {
return pobierzZAdresu(ADRES_BAZOWY + "/A/" + data + "?format=xml");
}
private TabelaWalut pobierzZAdresu(String adres) throws BladAplikacji {
try {
URI uri = new URI(adres);
HttpRequest request = HttpRequest.newBuilder(uri).build();
HttpResponse<InputStream> response = httpClient.send(request, BodyHandlers.ofInputStream());
if(response.statusCode() != 200) {
throw new BladAplikacji("Brak danych w odpowiedzi HTTP, kod " + response.statusCode());
}
DocumentBuilder builder = dbf.newDocumentBuilder();
Document document = builder.parse(response.body());
return tabelaZXML(document);
} catch(BladAplikacji e) {
throw e;
} catch(Exception e) {
throw new BladAplikacji("Błąd podczas pobierania XML: " + e.getMessage(), e);
}
}
private TabelaWalut tabelaZXML(Document document) throws XPathExpressionException {
XPath xpath = xpf.newXPath();
// String no = xpath.evaluate("/ArrayOfExchangeRatesTable/ExchangeRatesTable/No", document);
// String date = xpath.evaluate("/ArrayOfExchangeRatesTable/ExchangeRatesTable/EffectiveDate", document);
String no = xpath.evaluate("//No", document);
String date = xpath.evaluate("//EffectiveDate", document);
TabelaWalut tabela = new TabelaWalut(no, date);
NodeList rates = (NodeList) xpath.evaluate("//Rate", document, XPathConstants.NODESET);
final int length = rates.getLength();
for(int i = 0; i < length; i++) {
Node rate = rates.item(i);
String currency = xpath.evaluate("Currency", rate);
String code = xpath.evaluate("Code", rate);
BigDecimal mid = new BigDecimal(xpath.evaluate("Mid", rate));
Waluta waluta = new Waluta(code, currency, mid);
tabela.addRate(waluta);
}
return tabela;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment