Introduktion til Ninja Framework

1. Oversigt

I dag er der mange JEE-baserede rammer som Spring, Play og Grails tilgængelige til udvikling af webapplikationer.

Vi kan have vores grunde til at vælge en af ​​dem frem for de andre. Vores valg afhænger dog også af brugssagen og det problem, vi prøver at løse.

I denne introduktionsvejledning udforsker vi Ninja-webrammen og opretter en simpel webapplikation. Samtidig vil vi undersøge et par af de grundlæggende funktioner, som det giver.

2. Ninja

Ninja er en full-stack, men alligevel letvægts web-ramme, der bruger eksisterende Java-biblioteker til at få arbejdet gjort.

Med funktioner fra HTML til JSON-gengivelse, vedholdenhed til testning er det en one-stop-løsning til opbygning af skalerbare webapplikationer.

Det følger konvention-over-konfiguration paradigme og kategoriserer koden i pakker som modeller, controllere, og tjenester.

Ninja bruger populære Java-biblioteker til nøglefunktioner som f.eks Jackson til JSON / XML-gengivelse, Vejledning til afhængighedsstyring, Dvaletilstand for vedholdenhed og Flyway til databaseoverførsler.

For hurtig udvikling tilbyder den SuperDevMode til varm genindlæsning af koden. Så det giver os mulighed for at se ændringerne med det samme i udviklingsmiljøet.

3. Opsætning

Ninja kræver et standard sæt værktøjer til at oprette en webapplikation:

  • Java 1.8 eller nyere
  • Maven 3 eller senere
  • IDE (Eclipse eller IntelliJ)

Vi bruger en Maven-arketype til hurtigt at oprette Ninja-projektet. Det vil bede os om at angive et gruppe-id, et artefakt-id og et versionsnummer efterfulgt af et projektnavn:

mvn arketype: generer -DarchetypeGroupId = org.ninjaframework \ -DarchetypeArtifactId = ninja-servlet-arketype-enkel

Eller for et eksisterende Maven-projekt kan vi tilføje den nyeste ninja-kerneafhængighed til pom.xml:

 org.ninjaframework ninja-core 6.5.0 

Derefter kører vi kommandoen Maven for at kompilere filerne for første gang:

mvn ren installation

Lad os sidst køre appen ved hjælp af en Maven-kommando fra Ninja:

mvn ninja: løb

Voila! Vores ansøgning er startet og vil være tilgængelig kl lokal vært: 8080:

4. Projektstruktur

Lad os se på den Maven-lignende projektstruktur oprettet af Ninja:

Rammen skaber et par pakker baseret på konventioner.

Java-klasser er kategoriseret under konf, controllere, modellerog tjenester mapper i src / main / java.

Ligeledes, src / test / java holder de tilsvarende enhedstestklasser.

Det synspunkter bibliotek under src / main / java indeholder HTML-filerne. Og src / main / java / aktiver bibliotek indeholder ressourcer som billeder, typografiark og JavaScript-filer.

5. Controller

Vi er alle klar til at diskutere et par grundlæggende funktioner i rammen. En controller er en klasse, der modtager en anmodning og returnerer svaret med specifikke resultater.

Lad os først diskutere et par konventioner, der skal følges:

  • Opret en klasse i controllere pakke og suffiks navnet med Controller
  • En metode, der betjener anmodningen, skal returnere objektet til Resultat klasse

Lad os oprette ApplicationController klasse med en enkel metode til gengivelse af HTML:

@Singleton public class ApplicationController {public Result index () {return Results.html (); }}

Her, den indeks metoden gengiver en HTML ved at kalde html metode til Resultater klasse. Det Resultat objekt indeholder alt, hvad der kræves for at gengive indholdet som svarkode, overskrifter og cookies.

Bemærk: Guice's @Singleton annotering tillader kun en forekomst af controlleren i hele appen.

6. Vis

Til indeks metode, vil Ninja kigge efter HTML-filen - indeks.ftl.html under visninger / ApplicationController vejviser.

Ninja bruger Freemarker-skabelonmotoren til HTML-gengivelse. Så alle filerne under synspunkter skulle have .ftl.html udvidelse.

Lad os oprette jegndex.ftl.html fil til indeks metode:

  Ninja: Indeksbruger Json 

Her har vi brugt Ninja leveret i18n tag for at få hejMsg ejendom fra besked. ejendomme fil. Vi diskuterer dette yderligere i internationaliseringsafsnittet senere.

7. Rute

Dernæst definerer vi ruten for anmodningen om at nå indeks metode.

Ninja bruger Ruter klasse i konf pakke til at kortlægge en URL til en bestemt metode for controlleren.

Lad os tilføje en rute for at få adgang til indeks metode til ApplicationController:

public class Routes implementerer ApplicationRoutes {@Override public void init (Router router) {router.GET (). route ("/ index"). med (ApplicationController :: index); }}

Det er det! Vi er alle klar til at få adgang til indeks side kl localhost: 8080 / indeks:

8. JSON-gengivelse

Som allerede diskuteret bruger Ninja Jackson til JSON-gengivelse. For at gengive JSON-indhold kan vi bruge json metode til Resultater klasse.

Lad os tilføje userJson metode i ApplicationController klasse og gengive indholdet af et simpelt HashMap i JSON:

offentlig resultat brugerJson () {HashMap userMap = ny HashMap (); userMap.put ("navn", "Norman Lewis"); userMap.put ("e-mail", "[email protected]"); returnere Results.json (). gengive (bruger); }

Derefter tilføjer vi den nødvendige routing for at få adgang til userJson:

router.GET (). rute ("/ userJson"). med (ApplicationController :: userJson);

Nu kan vi gengive JSON ved hjælp af localhost: 8080 / userJson:

9. Service

Vi kan oprette en tjeneste for at holde forretningslogikken adskilt fra controlleren og injicere vores service, hvor det er nødvendigt.

Lad os først oprette en simpel UserService interface til at definere abstraktionen:

offentlig grænseflade UserService {HashMap getUserMap (); }

Derefter implementerer vi UserService interface i UserServiceImpl klasse og tilsidesætte getUserMap metode:

offentlig klasse UserServiceImpl implementerer UserService {@Override public HashMap getUserMap () {HashMap userMap = new HashMap (); userMap.put ("navn", "Norman Lewis"); userMap.put ("email", "[email protected]"); returner userMap; }}

Så binder vi UserService grænseflade med UserServiceImpl klasse ved hjælp af Ninjas funktion til afhængighedsinjektion leveret af Guice.

Lad os tilføje bindingen i Modul klasse tilgængelig i konf pakke:

@Singleton public class Module udvider AbstractModule {beskyttet ugyldig konfiguration () {bind (UserService.class) .to (UserServiceImpl.class); }}

Til sidst indsprøjter vi UserService afhængighed i ApplicationController klasse ved hjælp af @Indsprøjte kommentar:

offentlig klasse ApplicationController {@Inject UserService userService; // ...}

Således er vi alle klar til at bruge UserService'S getUserMap metode i ApplicationController:

offentligt resultat userJson () {HashMap userMap = userService.getUserMap (); returnere Results.json (). gengive (userMap); }

10. Flashomfang

Ninja giver en enkel, men effektiv måde at håndtere succes og fejlmeddelelser fra anmodninger gennem sin funktion kaldet Flash Scope.

For at bruge det i controlleren tilføjer vi FlashScope argument til metoden:

offentligt resultat showFlashMsg (FlashScope flashScope) {flashScope.success ("Succesmeddelelse"); flashScope.error ("Fejlmeddelelse"); returnere Results.redirect ("/ home"); }

Bemærk: omdirigere metode til Resultater klasse omdirigerer målet til den angivne URL.

Derefter tilføjer vi en routing /blitz til showFlashMsg metode og ændre visningen for at vise flashmeddelelser:

 $ {flash.error} $ {flash.success} 

Nu kan vi se FlashScope i aktion kl localhost: 8080 / flash:

11. Internationalisering

Ninja leverer en indbygget internationaliseringsfunktion, der er let at konfigurere.

Først definerer vi listen over understøttede sprog i application.conf fil:

application.languages ​​= fr, en

Derefter opretter vi standardegenskabsfilen - beskeder. ejendomme til engelsk - med nøgleværdipar til meddelelser:

header.home = Hjem! helloMsg = Hej, velkommen til Ninja Framework!

På samme måde kan vi tilføje sprogkoden i filnavnet til en sprogspecifik egenskabsfil - for eksempel besked_fr. ejendomme fil til fransk:

header.home = Accueil! helloMsg = Bonjour, bienvenue dans Ninja Framework!

Når konfigurationerne er klar, kan vi let aktivere internationalisering i ApplicationController klasse.

Vi har to måder, enten ved at bruge Lang klasse eller Beskeder klasse:

@Singleton public class ApplicationController {@Inject Lang lang; @Inject Messages msg; // ...}

Brug derefter Lang klasse, kan vi indstille sproget for resultatet:

Resultat resultat = Results.html (); lang.setLanguage ("fr", resultat);

På samme måde bruger du Beskeder klasse, kan vi få en sprogspecifik besked:

Valgfrit sprog = Optional.of ("fr"); String helloMsg = msg.get ("helloMsg", sprog) .get ();

12. Udholdenhed

Ninja understøtter JPA 2.0 og bruger dvale til at muliggøre vedholdenhed i webapplikationen. Det tilbyder også indbygget H2-databaseunderstøttelse til hurtig udvikling.

12.1. Model

Vi kræver en Enhed klasse for at oprette forbindelse til en tabel i databasen. Til dette følger Ninja konventionen om at lede efter enhedsklasser i modeller pakke. Så vi opretter Bruger enhedsklasse der:

@Entity offentlig klasse bruger {@Id @GeneratedValue (strategi = GenerationType.AUTO) Lang id; offentlig streng fornavn; offentlig streng e-mail; }

Derefter konfigurerer vi dvale og indstiller detaljerne til databaseforbindelsen.

12.2. Konfiguration

Ved dvale-konfiguration forventer Ninja, at persistence.xml fil, der skal være i src / main / java / META-INF vejviser:

    org.hibernate.jpa.HibernatePersistenceProvider 

Derefter vil vi tilføje oplysninger om databaseforbindelsen til application.conf:

ninja.jpa.persistence_unit_name = dev_unit db.connection.url = jdbc: h2: ./ devDb db.connection.username = sa db.connection.password =

12.3. EntityManager

Til sidst indsprøjter vi forekomsten af EntityManager i ApplicationController ved hjælp af Guice's Udbyder klasse:

offentlig klasse ApplicationController {@Inject Provider entityManagerProvider; // ...}

Så vi er klar til at bruge EntityManager at fortsætte Bruger objekt:

@Transactional public Resultat insertUser (brugerbruger) {EntityManager entityManager = entityManagerProvider.get (); entityManager.persist (bruger); entityManager.flush (); returnere Results.redirect ("/ home"); }

På samme måde kan vi bruge EntityManager at læse Bruger objekt fra DB:

@UnitOfWork offentlige resultat fetchUsers () {EntityManager entityManager = entityManagerProvider.get (); Forespørgsel q = entityManager.createQuery ("VÆLG x FRA bruger x"); Vis brugere = (Liste) q.getResultList (); returnere Results.json (). gengive (brugere); }

Her, Ninja @UnitOfWork annotation håndterer alt om databaseforbindelser uden at håndtere transaktioner. Derfor kan det vise sig praktisk til skrivebeskyttede forespørgsler, hvor vi normalt ikke kræver transaktioner.

13. Validering

Ninja leverer indbygget support til bønnevalidering ved at følge JSR303-specifikationerne.

Lad os undersøge funktionen ved at kommentere en ejendom i Bruger enhed med @NotNull kommentar:

public class User {// ... @NotNull public String firstName; }

Derefter ændrer vi det allerede diskuterede indsæt Bruger metode i ApplicationController for at aktivere validering:

@Transactional public Result insertUser (FlashScope flashScope, @ JSR303Validation User user, Validation validation) {if (validation.getViolations (). Size ()> 0) {flashScope.error ("Validation Error: User cannot be created"); } andet {EntityManager entityManager = entitiyManagerProvider.get (); entityManager.persist (bruger); entityManager.flush (); flashScope.success ("Bruger '" + bruger + "' er oprettet med succes"); } returnere Results.redirect ("/ home"); }

Vi har brugt Ninja's @ JSR303Validation kommentar for at aktivere validering af Bruger objekt. Så har vi tilføjet Validering argument for at arbejde med valideringer gennem metoder som har overtrædelser, getViolationsog addViolation.

Sidst, den FlashScope objekt bruges til at vise valideringsfejl på skærmen.

Bemærk: Ninja følger JSR303-specifikationerne for validering af bønner. JSR380-specifikationen (Bean Validation 2.0) er dog den nye standard.

14. Konklusion

I denne artikel udforskede vi Ninja-webrammen - en full-stack-ramme, der giver praktiske funktioner ved hjælp af populære Java-biblioteker.

Til at begynde med oprettede vi en simpel webapplikation ved hjælp af controllere, modeller, og tjenester. Derefter aktiverede vi JPA-support i appen for vedholdenhed.

På samme tid så vi et par grundlæggende funktioner som ruter, JSON-gengivelse, internationalisering og flashomfang.

Til sidst undersøgte vi valideringsstøtten leveret af rammen.

Som normalt er alle kodeimplementeringer tilgængelige på GitHub.