Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
2
20240528-BJava
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Patryk Czarnik
20240528-BJava
Commits
1cf2e1b0
Commit
1cf2e1b0
authored
Jun 26, 2024
by
Patryk Czarnik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Przykład pobieranie kursów walutowych
parent
1ae1f2f0
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
408 additions
and
0 deletions
+408
-0
build.gradle
PC32-Spring/build.gradle
+2
-0
PobieranieJSON.java
...ng/src/main/java/alx/aplikacja/waluty/PobieranieJSON.java
+63
-0
PobieranieWalut.java
...g/src/main/java/alx/aplikacja/waluty/PobieranieWalut.java
+10
-0
PobieranieXML.java
...ing/src/main/java/alx/aplikacja/waluty/PobieranieXML.java
+100
-0
TabelaWalut.java
...pring/src/main/java/alx/aplikacja/waluty/TabelaWalut.java
+62
-0
Waluta.java
PC32-Spring/src/main/java/alx/aplikacja/waluty/Waluta.java
+45
-0
WalutyController.java
.../src/main/java/alx/aplikacja/waluty/WalutyController.java
+41
-0
WalutyRest.java
...Spring/src/main/java/alx/aplikacja/waluty/WalutyRest.java
+27
-0
styl.css
PC32-Spring/src/main/resources/static/styl.css
+17
-0
index.html
PC32-Spring/src/main/resources/templates/index.html
+7
-0
waluty.html
PC32-Spring/src/main/resources/templates/waluty.html
+34
-0
No files found.
PC32-Spring/build.gradle
View file @
1cf2e1b0
...
...
@@ -23,6 +23,8 @@ dependencies {
testImplementation
'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly
'org.junit.platform:junit-platform-launcher'
implementation
'org.apache.commons:commons-lang3'
implementation
'jakarta.json:jakarta.json-api:2.1.2'
runtimeOnly
'org.eclipse.parsson:jakarta.json:1.1.3'
}
tasks
.
named
(
'test'
)
{
...
...
PC32-Spring/src/main/java/alx/aplikacja/waluty/PobieranieJSON.java
0 → 100644
View file @
1cf2e1b0
package
alx
.
aplikacja
.
waluty
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.net.URL
;
import
java.time.LocalDate
;
import
org.springframework.stereotype.Service
;
import
jakarta.json.Json
;
import
jakarta.json.JsonArray
;
import
jakarta.json.JsonObject
;
import
jakarta.json.JsonReader
;
import
jakarta.json.JsonValue
;
@Service
public
class
PobieranieJSON
implements
PobieranieWalut
{
private
static
final
String
ADRES
=
"http://api.nbp.pl/api/exchangerates/tables"
;
public
TabelaWalut
pobierzBiezaceKursy
()
{
return
pobierzJsonZAdresu
(
ADRES
+
"/a/?format=json"
);
}
public
TabelaWalut
pobierzArchiwalneKursy
(
String
data
)
{
return
pobierzJsonZAdresu
(
ADRES
+
"/a/"
+
data
+
"?format=json"
);
}
private
TabelaWalut
pobierzJsonZAdresu
(
String
adres
)
{
try
{
URL
url
=
new
URL
(
adres
);
try
(
InputStream
input
=
url
.
openStream
())
{
return
wczytajStream
(
input
);
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
private
static
TabelaWalut
wczytajStream
(
InputStream
input
)
{
try
(
JsonReader
reader
=
Json
.
createReader
(
input
))
{
// dokument zawiera [tablicę], a ta tablica zawiera {obiekt}
JsonArray
array
=
reader
.
readArray
();
JsonObject
tabela
=
array
.
getJsonObject
(
0
);
String
typ
=
tabela
.
getString
(
"table"
);
String
numer
=
tabela
.
getString
(
"no"
);
LocalDate
data
=
LocalDate
.
parse
(
tabela
.
getString
(
"effectiveDate"
));
JsonArray
waluty
=
tabela
.
getJsonArray
(
"rates"
);
TabelaWalut
wynikowaTabela
=
new
TabelaWalut
(
typ
,
numer
,
data
);
for
(
JsonValue
jsonValue
:
waluty
)
{
JsonObject
jsonObject
=
jsonValue
.
asJsonObject
();
Waluta
waluta
=
new
Waluta
(
jsonObject
.
getString
(
"code"
),
jsonObject
.
getString
(
"currency"
),
jsonObject
.
getJsonNumber
(
"mid"
).
bigDecimalValue
());
wynikowaTabela
.
dodajWalute
(
waluta
);
}
return
wynikowaTabela
;
}
}
}
PC32-Spring/src/main/java/alx/aplikacja/waluty/PobieranieWalut.java
0 → 100644
View file @
1cf2e1b0
package
alx
.
aplikacja
.
waluty
;
public
interface
PobieranieWalut
{
TabelaWalut
pobierzBiezaceKursy
();
TabelaWalut
pobierzArchiwalneKursy
(
String
data
);
}
\ No newline at end of file
PC32-Spring/src/main/java/alx/aplikacja/waluty/PobieranieXML.java
0 → 100644
View file @
1cf2e1b0
package
alx
.
aplikacja
.
waluty
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.math.BigDecimal
;
import
java.net.URL
;
import
java.time.LocalDate
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
javax.xml.parsers.ParserConfigurationException
;
import
javax.xml.xpath.XPath
;
import
javax.xml.xpath.XPathConstants
;
import
javax.xml.xpath.XPathExpressionException
;
import
javax.xml.xpath.XPathFactory
;
import
org.springframework.context.annotation.Primary
;
import
org.springframework.stereotype.Service
;
import
org.w3c.dom.Document
;
import
org.w3c.dom.Node
;
import
org.w3c.dom.NodeList
;
import
org.xml.sax.SAXException
;
/* Adnotacje @Component, @Service, @Repository, a także @Controller i @RestController
* powodują, że:
* 1) podczas startu aplikacji Spring tworzy obiekt tej klasy (pojedynczą sztukę, czyli "singleton")
* 2) ten obiekt będzie dostępny dla innych jako "komponent" ("bean") i będzie go wstrzykiwać
*
* @Primary w tym miejscu oznacza, że w razie występowania innych komponentów implementujących ten sam interfejs,
* Spring będzie preferował tę implementację.
*
*/
@Service
@Primary
public
class
PobieranieXML
implements
PobieranieWalut
{
private
static
final
String
ADRES
=
"http://api.nbp.pl/api/exchangerates/tables"
;
/** Pobiera tabelę z bieżącymi kursami walut.
* Zwraca null w przypadku błędów.
*/
public
TabelaWalut
pobierzBiezaceKursy
()
{
Document
doc
=
wczytajXmlZAdresu
(
ADRES
+
"/a?format=xml"
);
return
tabelaZXml
(
doc
);
}
public
TabelaWalut
pobierzArchiwalneKursy
(
String
data
)
{
Document
doc
=
wczytajXmlZAdresu
(
ADRES
+
"/A/"
+
data
+
"?format=xml"
);
return
tabelaZXml
(
doc
);
}
private
Document
wczytajXmlZAdresu
(
String
adres
)
{
// Document Object Model
try
{
DocumentBuilderFactory
dbf
=
DocumentBuilderFactory
.
newInstance
();
DocumentBuilder
db
=
dbf
.
newDocumentBuilder
();
URL
url
=
new
URL
(
adres
);
try
(
InputStream
in
=
url
.
openStream
())
{
return
db
.
parse
(
in
);
}
}
catch
(
ParserConfigurationException
|
SAXException
|
IOException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
private
TabelaWalut
tabelaZXml
(
Document
doc
)
{
if
(
doc
==
null
)
return
null
;
try
{
XPathFactory
xpf
=
XPathFactory
.
newInstance
();
XPath
xpath
=
xpf
.
newXPath
();
// String numer = xpath.evaluate(
// "/ArrayOfExchangeRatesTable/ExchangeRatesTable/No", doc);
String
nazwaTabeli
=
xpath
.
evaluate
(
"//Table"
,
doc
);
String
numerTabeli
=
xpath
.
evaluate
(
"//No"
,
doc
);
LocalDate
data
=
LocalDate
.
parse
(
xpath
.
evaluate
(
"//EffectiveDate"
,
doc
));
TabelaWalut
tabela
=
new
TabelaWalut
(
nazwaTabeli
,
numerTabeli
,
data
);
NodeList
rates
=
(
NodeList
)
xpath
.
evaluate
(
"//Rate"
,
doc
,
XPathConstants
.
NODESET
);
final
int
n
=
rates
.
getLength
();
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
Node
rate
=
rates
.
item
(
i
);
String
kod
=
xpath
.
evaluate
(
"Code"
,
rate
);
String
nazwa
=
xpath
.
evaluate
(
"Currency"
,
rate
);
BigDecimal
kurs
=
new
BigDecimal
(
xpath
.
evaluate
(
"Mid"
,
rate
));
Waluta
waluta
=
new
Waluta
(
kod
,
nazwa
,
kurs
);
tabela
.
dodajWalute
(
waluta
);
}
return
tabela
;
}
catch
(
XPathExpressionException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
}
PC32-Spring/src/main/java/alx/aplikacja/waluty/TabelaWalut.java
0 → 100644
View file @
1cf2e1b0
package
alx
.
aplikacja
.
waluty
;
import
java.time.LocalDate
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.List
;
public
class
TabelaWalut
{
private
final
String
typ
;
private
final
String
numer
;
private
final
LocalDate
data
;
private
final
List
<
Waluta
>
waluty
=
new
ArrayList
<>();
public
TabelaWalut
(
String
typ
,
String
numer
,
LocalDate
data
)
{
this
.
typ
=
typ
;
this
.
numer
=
numer
;
this
.
data
=
data
;
}
public
String
getTyp
()
{
return
typ
;
}
public
String
getNumer
()
{
return
numer
;
}
public
LocalDate
getData
()
{
return
data
;
}
public
Collection
<
Waluta
>
getWaluty
()
{
return
Collections
.
unmodifiableList
(
waluty
);
}
@Override
public
String
toString
()
{
return
"Tabela nr "
+
numer
+
" z dnia "
+
data
+
", "
+
waluty
.
size
()
+
" walut"
;
}
public
void
dodajWalute
(
Waluta
waluta
)
{
this
.
waluty
.
add
(
waluta
);
}
public
Waluta
wyszukaj
(
String
kod
)
{
for
(
Waluta
waluta
:
waluty
)
{
if
(
waluta
.
getKod
().
equals
(
kod
))
{
return
waluta
;
}
}
return
null
;
}
public
String
[]
getKodyWalut
()
{
return
this
.
waluty
.
stream
()
.
map
(
Waluta:
:
getKod
)
.
sorted
()
.
toArray
(
String
[]::
new
);
}
}
PC32-Spring/src/main/java/alx/aplikacja/waluty/Waluta.java
0 → 100644
View file @
1cf2e1b0
package
alx
.
aplikacja
.
waluty
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
public
class
Waluta
{
private
final
String
kod
;
private
final
String
nazwa
;
private
final
BigDecimal
kurs
;
public
Waluta
(
String
kod
,
String
nazwa
,
BigDecimal
kurs
)
{
this
.
kod
=
kod
;
this
.
nazwa
=
nazwa
;
this
.
kurs
=
kurs
;
}
public
Waluta
(
String
kod
,
String
nazwa
,
String
kurs
)
{
this
(
kod
,
nazwa
,
new
BigDecimal
(
kurs
));
}
public
String
getKod
()
{
return
kod
;
}
public
String
getNazwa
()
{
return
nazwa
;
}
public
BigDecimal
getKurs
()
{
return
kurs
;
}
@Override
public
String
toString
()
{
return
"Waluta [kod="
+
kod
+
", nazwa="
+
nazwa
+
", kurs="
+
kurs
+
"]"
;
}
public
BigDecimal
przeliczNaZlote
(
BigDecimal
kwota
)
{
return
kwota
.
multiply
(
kurs
).
setScale
(
2
,
RoundingMode
.
HALF_EVEN
);
}
public
BigDecimal
przeliczNaWalute
(
BigDecimal
kwota
)
{
return
kwota
.
divide
(
kurs
,
2
,
RoundingMode
.
HALF_EVEN
);
}
}
PC32-Spring/src/main/java/alx/aplikacja/waluty/WalutyController.java
0 → 100644
View file @
1cf2e1b0
package
alx
.
aplikacja
.
waluty
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.ui.Model
;
import
org.springframework.web.bind.annotation.GetMapping
;
@Controller
public
class
WalutyController
{
/* @Autowired oznacza, że Spring wstawi do tej zmiennej referencję do obiektu tego typu.
* Gdyby nie potrafił tego zrobić, to aplikacja się nie uruchomi. Pole nie zostanie pozostawione z nullem.
*
* To się nazywa "wstrzykiwanie zależności" / dependency injection.
* Są 3 sposoby wstrzykiwania , o 2 pozostałych później.
* Wstrzykiwanie zal. działa tylko gdy obiekt tej klasy jest inicjalizowany przez Springa.
*
* Wstrzykiwać można obiekty, które są typu:
* - komponent (bean) istniejący w tej samej aplikacji (tak jest tutaj)
* - klasa o specjalnym znaczeniu, którą Spring "zna", np. ServletContext
*
* W miejscu użycia zmienna może być typu interfejsowego,
* a Spring wstawi "jakąś implementację" tego interfejsu,
* jeśli taka implementacja jest dostępna wśród komponentów (beanów).
*/
@Autowired
private
PobieranieWalut
pobieracz
;
@GetMapping
(
"/waluty"
)
public
String
wyswietlWaluty
(
String
data
,
Model
model
)
{
TabelaWalut
tabela
;
if
(
data
==
null
)
{
tabela
=
pobieracz
.
pobierzBiezaceKursy
();
}
else
{
tabela
=
pobieracz
.
pobierzArchiwalneKursy
(
data
);
}
model
.
addAttribute
(
"tabela"
,
tabela
);
return
"waluty.html"
;
}
}
PC32-Spring/src/main/java/alx/aplikacja/waluty/WalutyRest.java
0 → 100644
View file @
1cf2e1b0
package
alx
.
aplikacja
.
waluty
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
@RequestMapping
(
"/waluty.rest"
)
public
class
WalutyRest
{
@Autowired
private
PobieranieWalut
pobieracz
;
@GetMapping
public
TabelaWalut
wyswietlWaluty
()
{
TabelaWalut
tabela
=
pobieracz
.
pobierzBiezaceKursy
();
return
tabela
;
}
@GetMapping
(
"/{data}"
)
public
TabelaWalut
wyswietlWaluty
(
@PathVariable
String
data
)
{
TabelaWalut
tabela
=
pobieracz
.
pobierzArchiwalneKursy
(
data
);
return
tabela
;
}
}
PC32-Spring/src/main/resources/static/styl.css
View file @
1cf2e1b0
...
...
@@ -35,3 +35,20 @@ form {
font-weight
:
bold
;
}
table
.tabela-walut
{
background-color
:
#FFFFFF
;
border-collapse
:
collapse
;
border
:
3px
solid
black
;
margin
:
0
auto
;
}
table
.tabela-walut
td
,
table
.tabela-walut
th
{
border
:
1px
solid
black
;
padding
:
2px
;
}
table
.tabela-walut
th
{
background-color
:
#FFCCDD
;
border-bottom
:
3px
double
black
;
}
PC32-Spring/src/main/resources/templates/index.html
View file @
1cf2e1b0
...
...
@@ -47,5 +47,12 @@
<li><a
th:href=
"@{/blog}"
>
Formularz
</a>
do wpisywania tekstów
</li>
</ul>
<h2>
Waluty
</h2>
<ul>
<li><a
th:href=
"@{/waluty}"
>
Kursy walut
</a></li>
<li><a
th:href=
"@{/waluty.rest}"
>
Waluty REST
</a>
- bieżące
</li>
<li><a
th:href=
"@{/waluty.rest/2008-08-08}"
>
Waluty REST
</a>
- archiwalne
</li>
</ul>
</body>
</html>
PC32-Spring/src/main/resources/templates/waluty.html
0 → 100644
View file @
1cf2e1b0
<!DOCTYPE html>
<html
lang=
"pl"
xmlns:th=
"http://www.thymeleaf.org"
>
<head>
<meta
charset=
"UTF-8"
>
<title>
Pobieraczka kursów walutowych
</title>
<link
rel=
"stylesheet"
type=
"text/css"
th:href=
"@{/styl.css}"
href=
"../static/styl.css"
>
</head>
<body>
<h1>
Kursy walut
</h1>
<form>
<div><label
for=
"data"
>
Wybierz datę:
</label>
<input
id=
"data"
type=
"date"
name=
"data"
th:value=
"${param.data}"
>
</div>
<button>
Pobierz
</button>
</form>
<div
th:if=
"${tabela != null}"
>
<h3>
Pobrane dane
</h3>
<div>
Numer tabeli:
<span
th:text=
"${tabela.numer}"
>
1234/2023
</span></div>
<div>
Data:
<span
th:text=
"${tabela.data}"
>
2023-05-04
</span></div>
<table
class=
"tabela-walut"
>
<tr><th>
Kod
</th><th>
Nazwa
</th><th>
Kurs
</th></tr>
<tr
th:each=
"w : ${tabela.waluty}"
>
<td
th:text=
"${w.kod}"
>
EUR
</td>
<td
th:text=
"${w.nazwa}"
>
euro
</td>
<td
th:text=
"${w.kurs}"
>
4.5432
</td>
</tr>
</table>
</div>
</body>
</html>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment