Skip to content
Snippets Groups Projects
Commit c3ce3090 authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Mer dokumentasjon

parent 3b362437
No related branches found
No related tags found
No related merge requests found
Pipeline #50573 passed
......@@ -6,11 +6,17 @@ Brukergrensesnittet er enkelt og består av en liste og et kart. Lista viser inn
Kartet implementeres av ([FxMapControl](https://github.com/ClemensFischer/FX-Map-Control), og siden biblioteket ikke er tilgjengelig i et sentral repository, så har vi bygget og lagt ved jar-filen.
I tillegg kan en lagre og lese inn **LatLongs**-objektet fra **Open...**- og **Save...**-aksjoner i en **File**-meny.
## Arkitektur
Arkitekturen er som de fleste JavaFX-apper som bruker FXML, vi har en oppstartsklasse (**FxApp**) som arver fra **Application** og som stort sett bare laster inn og viser frem (innholdet i) en FXML-fil. FXML-fila angir en kontroller-klasse (med **fx:controller**-attributtet i rot-elementet) hvor UI-logikken ligger.
Det finnes to varianter av applikasjonen, én som bruker lokale data lagret på fil og én som bruker sentrale data håndtert gjennom et REST-API på en server. Derfor har vi også to FXML-filer (**FxApp.fxml** og **FxAppUsingRest.fxml**) og to tilhørende kontroller-klasser (**FxAppController** og **FxAppUsingRestController**). For å gjøre det enklere å ha en del felles kode i en abstrakt kontroller-klasse (**AbstractFxAppController**), så er datatilgangen skilt ut i egne klasser (**LocalLatLongsDataAccess** og **RestLatLongsDataAccess**) som implementerer et felles **LatLongsDataAccess**-grensesnitt.
Det er bare én app-klasse (**FxApp**), og denne velger hvilken variant som brukes, basert på om det oppgis en server-URL som kommandolinjeargument. Hvis en f.eks. kjører 'java FxApp http://localhost:8080/' så kjøres varianten som bruker REST-API-et. Det betyr også at serveren må startes. I tillegg til URL-en så kan en også oppgi initielle LatLongs-data kodet som json. Dette gjør det enklere å sjekke at data leses riktig fra REST-API-et ved oppstart. **build.gradle** er rigget slik at begge disse kommandolinjeargumentene oppgis ved kjøring av **Run**-oppgaven.
```plantuml
class FxAppController
class LatLongs
class AbstractFxAppController
class LatLongsDataAccess
class BorderPane
class "ListView<LatLong>" as ListView
class "fxmapcontrol.MapBase" as MapBase
......@@ -18,7 +24,10 @@ class "fxmapcontrol.MapBase" as MapBase
BorderPane *--> ListView: "left"
BorderPane *--> MapBase: "center"
FxAppController --> LatLongs: "latLongs"
FxAppController --> MapBase: "mapView"
FxAppController --> ListView: "locationListView"
AbstractFxAppController --> LatLongsDataAccess: "dataAccess"
AbstractFxAppController --> MapBase: "mapView"
AbstractFxAppController --> ListView: "locationListView"
FxAppController ..|> AbstractFxAppController
FxAppUsingRestController ..|> AbstractFxAppController
```
# Testkode for brukergrensesnittet
Denne pakken inneholder testkode for JavaFX-app-en. Koden er ikke så grundig...
Det mest spesielle er at det finnes to varianter (subklasser av **AbstractFxAppTest**), én for hver variant av app-en, altså med eller uten bruk av REST-API-et. Varianter som bruker REST-API-et (**FxAppUsingRestTest**) starter opp serveren ifm. rigging av datatilgangsobjektet (instans av **LatLongsDataAccess**) og stopper den i nedriggingsfasen.
# Modul for REST-api
Dette prosjektet inneholder REST-api for [simpleexample2](../README.md).
Dette modulen inneholder REST-api for [simpleexample2](../README.md).
## REST-api-et
## Bygging med gradle
Et REST-API er på en måte et objekt (eller sett med objekter) som leses og/eller kalles ved å bruke HTTP-forespørsler (HTTP-URL-er). Mottak av forespørslen håndteres av en HTTP-server, og så "omformes" forespørslen til et kall på en tilhørende metode i et "REST-tjeneste"-objekt.
Denne modulen inneholder bare logikken til "REST-tjeneste"-objektet (**LatLongsService**), mens oppsettet av serveren ligger i [restserver-modulen](../restserver/README.md). En slik oppdeling gjør løsningen ryddigere (selv om det øker antall moduler).
REST-API-et vårt er programmert iht. [JAX-RS-standarden](https://en.wikipedia.org/wiki/Java_API_for_RESTful_Web_Services), som lar en angi koblingen mellom HTTP og metodene på REST-tjeneste-objektet vha. Java-annotasjoner. F.eks. angir @Path-annotasjonen på **LatLongsService**-klassen at vår tjeneste er knyttet til **latLongs**-prefikset. Altså vil vår tjeneste aktiveres ved å angi **latLongs** først i stien til URL-en (men bak stien til serveren). Anta f.eks. at stien til serveren er "http://min-server:8080/". Da vil stien til vår tjeneste være "http://min-server:8080/latLongs".
Som nevnt er JAX-RS *annotasjonsdrevet*. Det betyr at Java-annotasjoner ved hver metode angir detaljer ved forespørslen som trigger metoden. F.eks. vil en metode annotert med **@GET** bare kalles når HTTP-metoden er "GET". En kan bruke **@Path** for å angi et påkrevd sti-segment og **@PathParam** for å bruke dette sti-segmentet som argument til metoden.
Hvis metoden bruker ekstra data sendt i tillegg til URL-en, så angis formatet med **@Consumes**-annotasjonen. Tilsvarende angis kodingen av resultatet med **@Produces**-annotasjonen. Vi bruker json-kodete data, så derfor bruker vi **MediaType.APPLICATION_JSON** (konstant for "application/json") som argument for begge disse.
Vårt REST-API gir tilgang til *ett* **LatLongs**-objekt og tilbyr fem metoder:
* lese innholdet (alle **LatLong**-objektene) - GET til **tjeneste-URL**
* lese innholdet til et spesifikt **LatLong**-element (angitt med posisjonen **num**) - GET (**@GET**) til **tjeneste-URL/num** (**@Path** og **@PathParam**)
* legge til LatLongs-objekter i spesifikk posisjon - POST (**@POST**) av json-kodet LatLong-array til **tjeneste-URL/num** (**@Path** og **@PathParam**)
* endre LatLong-objekt i spesifikk posisjon - PUT (**@PUT**) av json-kodet LatLong-objekt til **tjeneste-URL/num** (**@Path** og **@PathParam**)
* fjerne LatLong-objekt i spesifikk posisjon - DELETE (**@DELETE**) til **tjeneste-URL/num** (**@Path** og **@PathParam**)
Merk at navnet på implementasjonsmetoden i **LatLongsService**-klassen ikke spiller noen rolle, det er annotasjonene som er viktige.
## JSON-koding av data
Når vi bruker **@Consumes** og **@Produces** med **MediaType.APPLICATION_JSON** som argument, så må vi også konfigurere tjenesten slik at kodingen av json-data bruker vår logikk, altså den som er programmert i [**core**-modulen](../core/README.md). Dette gjøres i **LatLongObjectMapperProvider**-klassen. Det er ikke så mye å si om den klassen, annet enn at den bruker **LatLongsModule**-klassen fra core-modulen.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment