Blade - Een compleet handboek

1. Overzicht

Blade is een klein Java 8+ MVC-framework, helemaal opnieuw opgebouwd met een aantal duidelijke doelen voor ogen: op zichzelf staand, productief, elegant, intuïtief en supersnel zijn.

Veel verschillende frameworks inspireerden het ontwerp: Node's Express, Python's Flask en Golang's Macaron / Martini.

Blade maakt ook deel uit van een ambitieus groter project, Let's Blade. Het bevat een heterogene verzameling andere kleine bibliotheken, van het genereren van captcha tot JSON-conversie, van sjablonen tot een eenvoudige databaseverbinding.

In deze zelfstudie concentreren we ons echter alleen op de MVC.

2. Aan de slag

Laten we eerst een leeg Maven-project maken en de nieuwste Blade MVC-afhankelijkheid toevoegen in het pom.xml:

 com.bladejava blade-mvc 2.0.14.RELEASE 

2.1. Bundelen van een Blade-applicatie

Aangezien onze app wordt gemaakt als een JAR, heeft deze geen / lib map, zoals in een WAR. Als gevolg hiervan leidt dit ons naar het probleem hoe we het blade-mvc JAR, samen met elke andere JAR die we nodig hebben, naar onze app.

De verschillende manieren om dit te doen, elk met voor- en nadelen, worden uitgelegd in de tutorial How to Create an Executable JAR with Maven.

Voor de eenvoud, we zullen de Maven Assembly-plug-in techniek, waarmee elke JAR die in het pom.xml en bundelt vervolgens alle klassen in één uber-JAR.

2.2. Een Blade-applicatie uitvoeren

Blade is gebaseerd op Netty, een verbazingwekkend asynchroon, gebeurtenisgestuurd netwerkapplicatieframework. Daarom hebben we geen externe toepassingsserver of Servlet-container nodig om onze Blade-gebaseerde applicatie uit te voeren; de JRE is voldoende:

java -jar target / sample-blade-app.jar 

Daarna is de applicatie toegankelijk op het // localhost: 9000 URL.

3. Inzicht in de architectuur

De architectuur van Blade is heel eenvoudig:

Het volgt altijd dezelfde levenscyclus:

  1. Netty krijgt een verzoek
  2. Middlewares worden uitgevoerd (optioneel)
  3. WebHooks worden uitgevoerd (optioneel)
  4. Routing wordt uitgevoerd
  5. Het antwoord wordt naar de klant gestuurd
  6. Schoonmaken

We zullen de bovenstaande functies in de volgende secties onderzoeken.

4. Routing

Kort gezegd, routing in MVC is het mechanisme dat wordt gebruikt om een ​​binding tussen een URL en een controller te creëren.

Blade biedt twee soorten routes: een eenvoudige en een geannoteerde.

4.1. Basisroutes

Basisroutes zijn bedoeld voor zeer kleine software, zoals microservices of minimale webapplicaties:

Blade.of () .get ("/ basic-routes-example", ctx -> ctx.text ("GET called")) .post ("/ basic-routes-example", ctx -> ctx.text (" POST genaamd ")) .put (" / basic-routes-example ", ctx -> ctx.text (" PUT genaamd ")) .delete (" / basic-routes-example ", ctx -> ctx.text (" DELETE genaamd ")) .start (App.class, args); 

De naam van de methode die wordt gebruikt om een ​​route te registreren, komt overeen met het HTTP-werkwoord dat zal worden gebruikt om het verzoek door te sturen. Zo simpel is het.

In dit geval retourneren we een tekst, maar we kunnen ook pagina's renderen, zoals we later in deze tutorial zullen zien.

4.2. Geannoteerde routes

Zeker, voor meer realistische gebruiksscenario's kunnen we alle routes definiëren die we nodig hebben met behulp van annotaties. Daarvoor zouden we aparte klassen moeten gebruiken.

Allereerst moeten we een controller maken via de @Pad annotatie, die tijdens het opstarten door Blade wordt gescand.

We moeten dan de routeannotatie gebruiken die gerelateerd is aan de HTTP-methode die we willen onderscheppen:

@Path openbare klasse RouteExampleController {@GetRoute ("/ routes-example") openbare String get () {return "get.html"; } @PostRoute ("/ routes-example") public String post () {return "post.html"; } @PutRoute ("/ routes-example") public String put () {return "put.html"; } @DeleteRoute ("/ routes-example") public String delete () {return "delete.html"; }} 

We kunnen ook de simple gebruiken @Route annotatie en specificeer de HTTP-methode als een parameter:

@Route (value = "/ another-route-example", method = HttpMethod.GET) public String anotherGet () {return "get.html"; } 

Aan de andere kant, als we geen methodeparameter plaatsen, onderschept de route elke HTTP-aanroep naar die URL, ongeacht het werkwoord.

4.3. Parameter injectie

Er zijn verschillende manieren om parameters aan onze routes door te geven. Laten we ze onderzoeken met enkele voorbeelden uit de documentatie.

  • Formulierparameter:
@GetRoute ("/ home") public void formParam (@Param String naam) {System.out.println ("naam:" + naam); } 
  • Rustgevende parameter:
@GetRoute ("/ gebruikers /: uid") public void restfulParam (@PathParam Geheel getal uid) {System.out.println ("uid:" + uid); } 
  • Parameter voor uploaden van bestanden:
@PostRoute ("/ upload") openbare ongeldige fileParam (@MultipartParam FileItem fileItem) {byte [] file = fileItem.getData (); } 
  • Header parameter:
@GetRoute ("/ header") public void headerParam (@HeaderParam String referer) {System.out.println ("Referer:" + referer); } 
  • Cookie-parameter:
@GetRoute ("/ cookie") openbare ongeldige cookieParam (@CookieParam String myCookie) {System.out.println ("myCookie:" + myCookie); } 
  • Lichaamsparameter:
@PostRoute ("/ bodyParam") openbare ongeldige bodyParam (@BodyParam Gebruiker gebruiker) {System.out.println ("gebruiker:" + user.toString ()); } 
  • Waardeobjectparameter, aangeroepen door zijn attributen naar de route te sturen:
@PostRoute ("/ voParam") public void voParam (@Param Gebruiker gebruiker) {System.out.println ("gebruiker:" + user.toString ()); } 

5. Statische bronnen

Blade kan indien nodig ook statische bronnen bedienen door ze eenvoudig in de / resources / static map.

Bijvoorbeeld de src / main / resources / static / app.css zal beschikbaar zijn op //localhost:9000/static/app.css.

5.1. De paden aanpassen

We kunnen dit gedrag afstemmen door een of meer statische paden programmatisch toe te voegen:

blade.addStatics ("/ custom-static"); 

Hetzelfde resultaat kan worden verkregen door middel van configuratie, door het bestand te bewerken src / main / resources / application.properties:

mvc.statics = / custom-static 

5.2. De lijst met bronnen inschakelen

We kunnen toestaan ​​dat de inhoud van een statische map wordt weergegeven, een functie die om veiligheidsredenen standaard is uitgeschakeld:

blade.showFileList (waar); 

Of in de configuratie:

mvc.statics.show-list = waar 

We kunnen nu het // localhost: 9000 / custom-static / om de inhoud van de map weer te geven.

5.3. Met behulp van WebJars

Zoals te zien is in de Inleiding tot WebJars-zelfstudie, zijn statische bronnen die zijn verpakt als JAR ook een haalbare optie.

Blade stelt ze automatisch bloot onder de / webjars / pad.

Laten we bijvoorbeeld Bootstrap importeren in het pom.xml:

 org.webjars bootstrap 4.2.1 

Als gevolg hiervan is het beschikbaar onder //localhost:9000/webjars/bootstrap/4.2.1/css/bootstrap.css

6. HTTP-verzoek

Sinds Blade is niet gebaseerd op de Servlet-specificatie, objecten zoals de interface Verzoek en zijn klasse HttpRequest zijn iets anders dan degene die we gewend zijn.

6.1. Formulierparameters

Bij het lezen van formulierparameters maakt Blade veel gebruik van Java's Optioneel in de resultaten van de zoekmethoden (alle onderstaande methoden retourneren een Optioneel voorwerp):

  • query (String naam)
  • queryInt (String naam)
  • queryLong (String naam)
  • queryDouble (String naam)

Ze zijn ook verkrijgbaar met een terugvalwaarde:

  • Stringquery (Stringnaam, String defaultValue)
  • int queryInt (String naam, int defaultValue)
  • long queryLong (String naam, lange defaultValue)
  • double queryDouble (String naam, dubbele defaultValue)

We kunnen een formulierparameter lezen via de eigenschap automapped:

@PostRoute ("/ save") public void formParams (@Param String gebruikersnaam) {// ...} 

Of uit de Verzoek voorwerp:

@PostRoute ("/ save") public void formParams (Verzoekverzoek) {String gebruikersnaam = request.query ("gebruikersnaam", "Baeldung"); } 

6.2. JSON-gegevens

Laten we nu eens kijken hoe een JSON-object kan worden toegewezen aan een POJO:

curl -X POST // localhost: 9000 / gebruikers -H 'Content-Type: application / json' \ -d '{"name": "Baeldung", "site": "baeldung.com"}' 

POJO (geannoteerd met Lombok voor leesbaarheid):

openbare klasse Gebruiker {@Getter @Setter privé Stringnaam; @Getter @Setter privé String-site; } 

Nogmaals, de waarde is beschikbaar als de geïnjecteerde eigenschap:

@PostRoute ("/ gebruikers") public void bodyParams (@BodyParam Gebruiker gebruiker) {// ...} 

En van de Verzoek:

@PostRoute ("/ gebruikers") public void bodyParams (Verzoekverzoek) {String bodyString = request.bodyToString (); } 

6.3. RESTful-parameters

RESTFul-parameters in mooie URL's zoals localhost: 9000 / gebruiker / 42 zijn ook eersteklas burgers:

@GetRoute ("/ user /: id") openbare ongeldige gebruiker (@PathParam Integer-id) {// ...} 

Zoals gewoonlijk kunnen we vertrouwen op de Verzoek bezwaar indien nodig:

@GetRoute ("/ user") openbare ongeldige gebruiker (verzoekverzoek) {Integer id = request.pathInt ("id"); } 

Uiteraard is dezelfde methode beschikbaar voor Lang en Draad typen ook.

6.4. Dataverbinding

Blade ondersteunt zowel JSON- als Form-bindingparameters en voegt deze automatisch aan het modelobject toe:

@PostRoute ("/ users") public void bodyParams (gebruiker gebruiker) {} 

6.5. Verzoek- en sessiekenmerken

De API voor het lezen en schrijven van objecten in een Verzoek en een Sessie zijn glashelder.

De methoden met twee parameters, die sleutel en waarde vertegenwoordigen, zijn de mutatoren die we kunnen gebruiken om onze waarden in de verschillende contexten op te slaan:

Sessie sessie = request.session (); request.attribute ("request-val", "Some Request value"); session.attribute ("session-val", 1337); 

Aan de andere kant zijn dezelfde methoden die alleen de belangrijkste parameter accepteren de accessors:

String requestVal = request.attribute ("request-val"); String sessionVal = session.attribute ("session-val"); // Het is een geheel getal 

Een interessant kenmerk is hun Generic return type T, waardoor we het resultaat niet hoeven te casten.

6.6. Headers

Aanvraagheaders kunnen daarentegen alleen worden gelezen vanuit het verzoek:

String header1 = request.header ("a-header"); String header2 = request.header ("a-safe-header", "met een standaardwaarde"); Kaart allHeaders = request.headers (); 

6.7. Gereedschap

De volgende hulpprogramma-methoden zijn ook standaard beschikbaar, en ze zijn zo duidelijk dat er geen verdere uitleg nodig is:

  • boolean isIE ()
  • boolean isAjax ()
  • Tekenreeks contentType ()
  • Tekenreeks userAgent ()

6.8. Cookies lezen

Laten we eens kijken hoe de Verzoek object helpt ons om te gaan met cookies, met name bij het lezen van het Optioneel:

Optioneel cookieRaw (String naam); 

We kunnen het ook krijgen als een Draad door een standaardwaarde op te geven die moet worden toegepast als er geen cookie bestaat:

String-cookie (String-naam, String defaultValue); 

Ten slotte is dit hoe we alle cookies tegelijk kunnen lezen (sleutels zijn de namen van cookies, waarden zijn de waarden van cookies):

Kaartcookies = request.cookies (); 

7. HTTP-reactie

Analoog aan wat er is gedaan met de Verzoekkunnen we een verwijzing naar de Reactie object door het simpelweg te declareren als een parameter van de routeringsmethode:

@GetRoute ("/") public void home (antwoordantwoord) {} 

7.1. Eenvoudige uitvoer

We kunnen eenvoudig een eenvoudige uitvoer naar de beller sturen via een van de handige uitvoermethoden, samen met een 200 HTTP-code en het juiste inhoudstype.

Ten eerste kunnen we een platte tekst verzenden:

response.text ("Hallo wereld!");

Ten tweede kunnen we een HTML maken:

response.html ("");

Ten derde kunnen we op dezelfde manier een XML genereren:

response.xml ("Hallo wereld!");

Ten slotte kunnen we JSON uitvoeren met behulp van een Draad:

response.json ("{\" The Answer \ ": 42}"); 

En zelfs vanuit een POJO, gebruikmakend van de automatische JSON-conversie:

Gebruiker gebruiker = nieuwe gebruiker ("Baeldung", "baeldung.com"); response.json (gebruiker); 

7.2. Bestandsuitvoer

Het downloaden van een bestand van de server kan niet slanker zijn:

response.download ("the-file.txt", "/path/to/the/file.txt"); 

De eerste parameter stelt de naam in van het bestand dat zal worden gedownload, terwijl de tweede (a het dossier object, hier geconstrueerd met een Draad) staat voor het pad naar het daadwerkelijke bestand op de server.

7.3. Sjabloonweergave

Blade kan ook pagina's weergeven via een sjabloonengine:

response.render ("admin / gebruikers.html"); 

De standaardmap van de sjablonen is src / main / resources / templates /, vandaar dat de vorige oneliner naar het bestand zal zoeken src / main / resources / templates / admin / users.html.

We zullen hier later meer over te weten komen, in het Templating sectie.

7.4. Omleiden

Een omleiding betekent het verzenden van een 302 HTTP-code naar de browser, samen met een URL die gevolgd moet worden met een tweede GET.

We kunnen omleiden naar een andere route, of ook naar een externe URL:

response.redirect ("/ target-route"); 

7.5. Cookies schrijven

We zouden op dit punt gewend moeten zijn aan de eenvoud van Blade. Laten we dus eens kijken hoe we een niet-aflopende cookie in een enkele regel code kunnen schrijven:

response.cookie ("cookienaam", "Een waarde hier"); 

Het verwijderen van een cookie is inderdaad net zo eenvoudig:

response.removeCookie ("cookienaam"); 

7.6. Andere bewerkingen

eindelijk, de Reactie object biedt ons verschillende andere methoden om bewerkingen uit te voeren, zoals het schrijven van kopteksten, het instellen van het inhoudstype, het instellen van de statuscode, enzovoort.

Laten we er snel een paar bekijken:

  • Antwoordstatus (int-status)
  • Kaartkoppen ()
  • Reactie notFound ()
  • Kaart cookies ()
  • Reactie contentType (String contentType)
  • leegte body (@NonNull byte [] gegevens)
  • Antwoordheader (tekenreeksnaam, tekenreekswaarde)

8. WebHooks

Een WebHook is een interceptor waardoor we dat kunnen voer code uit voor en na de uitvoering van een routeringsmethode.

We kunnen een WebHook maken door simpelweg het WebHook functionele interface en het overschrijven van de voordat() methode:

@FunctionalInterface openbare interface WebHook {boolean voor (RouteContext ctx); standaard boolean na (RouteContext ctx) {return true; }} 

Zoals we kunnen zien, na() is een standaardmethode, daarom zullen we deze alleen overschrijven als dat nodig is.

8.1. Elk verzoek onderscheppen

De @Boon annotatie vertelt het framework om de klasse te scannen met de IoC-container.

Een WebHook die ermee is geannoteerd, zal bijgevolg wereldwijd werken en verzoeken naar elke URL onderscheppen:

@Bean openbare klasse BaeldungHook implementeert WebHook {@Override openbare boolean vóór (RouteContext ctx) {System.out.println ("[BaeldungHook] aangeroepen vóór Routemethode"); terugkeer waar; }} 

8.2. Beperking tot een URL

We kunnen ook specifieke URL's onderscheppen, om alleen code rond die routemethoden uit te voeren:

Blade.of () .before ("/ user / *", ctx -> System.out.println ("Before:" + ctx.uri ())); .start (App.class, args); 

8.3. Middlewares

Middlewares hebben voorrang op WebHooks, die worden uitgevoerd vóór elke standaard WebHook:

openbare klasse BaeldungMiddleware implementeert WebHook {@Override openbare boolean vóór (RouteContext-context) {System.out.println ("[BaeldungMiddleware] aangeroepen vóór Routemethode en andere WebHooks"); terugkeer waar; }} 

Ze hoeven alleen maar te worden gedefinieerd zonder de @Boon annotatie en vervolgens declaratief geregistreerd via gebruik():

Blade.of () .use (nieuwe BaeldungMiddleware ()) .start (App.class, args); 

Bovendien wordt Blade geleverd met de volgende beveiligingsgerelateerde ingebouwde Middlewares, waarvan de namen voor zichzelf moeten spreken:

  • BasicAuthMiddleware
  • CorsMiddleware
  • XssMiddleware
  • CsrfMiddleware

9. Configuratie

In Blade is de configuratie volledig optioneel, omdat alles volgens afspraak out-of-the-box werkt. We kunnen echter de standaardinstellingen aanpassen en nieuwe attributen introduceren in het src / main / resources / application.properties het dossier.

9.1. De configuratie lezen

We kunnen de configuratie op verschillende manieren lezen, met of zonder een standaardwaarde op te geven voor het geval de instelling niet beschikbaar is.

  • Tijdens het opstarten:
Blade.of () .on (EventType.SERVER_STARTED, e -> {Optionele versie = WebContext.blade (). Env ("app.version");}) .start (App.class, args); 
  • Binnen een route:
@GetRoute ("/ some-route") public void someRoute () {String auteurs = WebContext.blade (). Env ("app.authors", "Onbekende auteurs"); } 
  • In een aangepaste lader, door het BladeLoader interface, waarbij de laden() methode, en de klasse annoteren met @Boon:
@Bean public class LoadConfig implementeert BladeLoader {@Override public void load (Blade blade) {Optionele versie = WebContext.blade (). Env ("app.version"); Tekenreeksauteurs = WebContext.blade (). Env ("app.authors", "Onbekende auteurs"); }} 

9.2. Configuratiekenmerken

De verschillende instellingen die al zijn geconfigureerd, maar klaar om te worden aangepast, zijn gegroepeerd op type en op dit adres vermeld in tabellen met drie kolommen (naam, beschrijving, standaardwaarde). We kunnen ook verwijzen naar de vertaalde pagina, waarbij we erop letten dat de vertaling ten onrechte een hoofdletter geeft aan de namen van de instellingen. De echte instellingen zijn volledig in kleine letters.

Door configuratie-instellingen op voorvoegsel te groeperen, zijn ze allemaal tegelijk leesbaar op een kaart, wat handig is als er veel zijn:

Omgeving environment = blade.environment (); Map map = environment.getPrefix ("app"); String version = map.get ("versie"). ToString (); String auteurs = map.get ("auteurs", "Onbekende auteurs"). ToString (); 

9.3. Omgaan met meerdere omgevingen

Bij het implementeren van onze app in een andere omgeving, moeten we mogelijk andere instellingen specificeren, bijvoorbeeld degene die betrekking hebben op de databaseverbinding. In plaats van handmatig de application.properties bestand biedt Blade ons een manier om de app voor verschillende omgevingen te configureren. We kunnen gewoon houden application.properties met alle ontwikkelingsinstellingen, en dan maak andere bestanden in dezelfde map, zoals application-prod.properties, met alleen de instellingen die verschillen.

Tijdens het opstarten kunnen we vervolgens de omgeving specificeren die we willen gebruiken, en het framework zal de bestanden samenvoegen met behulp van de meest specifieke instellingen van application-prod.properties, en alle andere standaardinstellingen application.properties het dossier:

java -jar doel / sample-blade-app.jar --app.env = prod 

10. Sjablonen

Templating in Blade is een modulair aspect. Hoewel het een zeer eenvoudige sjabloonengine integreert, moeten we voor elk professioneel gebruik van de weergaven vertrouwen op een externe sjabloonengine. We kunnen dan kies een motor uit de beschikbare motoren in de blade-template-engines repository op GitHub, die FreeMarker, Jetbrick, Kiezelsteen, en Snelheid, of zelfs het maken van een wrapper om een ​​andere sjabloon te importeren die we leuk vinden.

De auteur van Blade suggereert Jetbrick, een ander slim Chinees project.

10.1. Met behulp van de standaardengine

De standaardsjabloon werkt door variabelen uit verschillende contexten te ontleden via het ${} notatie:

10.2. Een externe engine aansluiten

Overschakelen naar een andere sjabloonengine is een fluitje van een cent! We importeren simpelweg de afhankelijkheid van (de Blade-wrapper van) de engine:

 com.bladejava blade-sjabloon-jetbrick 0.1.3 

Op dit punt is het voldoende om een ​​eenvoudige configuratie te schrijven om het framework te instrueren om die bibliotheek te gebruiken:

@Bean public class TemplateConfig implementeert BladeLoader {@Override public void load (Blade blade) {blade.templateEngine (new JetbrickTemplateEngine ()); }} 

Als gevolg hiervan staat nu elk bestand onder src / main / resources / templates / zal worden geparseerd met de nieuwe engine, waarvan de syntaxis buiten het bestek van deze tutorial valt.

10.3. Een nieuwe motor inpakken

Om een ​​nieuwe sjabloonengine in te pakken, moet u een enkele klasse maken, die de TemplateEngine interface en overschrijf de render () methode:

void render (ModelAndView modelAndView, Writer-schrijver) gooit TemplateException; 

Voor dit doel kunnen we de code van de daadwerkelijke Jetbrick-wrapper bekijken om een ​​idee te krijgen van wat dat betekent.

11. Logboekregistratie

Blade gebruikt slf4j-api als logboekregistratie-interface.

Het bevat ook een reeds geconfigureerde implementatie voor logboekregistratie, genaamd blade-log. Daarom hoeven we niets te importeren; het werkt zoals het is, door simpelweg een Logger:

privé statisch laatste org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger (LogExample.class); 

11.1. De geïntegreerde logger aanpassen

Als we de standaardconfiguratie willen wijzigen, moeten we de volgende parameters afstemmen als Systeemeigenschappen:

  • Logboekregistratieniveaus (kan "traceren", "debuggen", "info", "waarschuwen" of "fout" zijn):
# Root Logger com.blade.logger.rootLevel = info # Pakket Aangepast logboekniveau com.blade.logger.somepackage = debug # Klasse Aangepast logboekniveau com.blade.logger.com.baeldung.sample.SomeClass = trace 
  • Weergegeven informatie:
# Datum en tijd com.blade.logger.showDate = false # Datum- en tijdpatroon com.blade.logger.datePattern = jjjj-MM-dd HH: mm: ss: SSS Z # Discussie-naam com.blade.logger.showThread = true # Naam loggerinstantie com.blade.logger.showLogName = true # Alleen het laatste deel van FQCN com.blade.logger.shortName = true 
  • Logger:
# Pad com.blade.logger.dir =. / Logs # Naam (standaard de huidige app.name) com.blade.logger.name = voorbeeld 

11.2. Exclusief de geïntegreerde logger

Hoewel een reeds geconfigureerde geïntegreerde logger erg handig is om ons kleine project te starten, kunnen we gemakkelijk in het geval terechtkomen waarin andere bibliotheken hun eigen logging-implementatie importeren. En in dat geval kunnen we de geïntegreerde verwijderen om conflicten te voorkomen:

 com.bladejava blade-mvc $ {blade.version} com.bladejava blade-log 

12. Aanpassingen

12.1. Aangepaste afhandeling van uitzonderingen

Een Exception Handler is ook standaard ingebouwd in het framework. Het drukt de uitzondering af op de console, en als app.devMode is waaris de stacktracering ook zichtbaar op de webpagina.

We kunnen een uitzondering echter op een specifieke manier behandelen door een @Boon uitbreiding van de DefaultExceptionHandler klasse:

@Bean public class GlobalExceptionHandler breidt DefaultExceptionHandler uit {@Override public void handle (uitzondering e) {if (e instanceof BaeldungException) {BaeldungException baeldungException = (BaeldungException) e; String msg = baeldungException.getMessage (); WebContext.response (). Json (RestResponse.fail (msg)); } else {super.handle (e); }}} 

12.2. Aangepaste foutpagina's

Evenzo zijn de fouten 404 Niet Gevonden en 500 Interne server fout worden afgehandeld via magere standaardpagina's.

We kunnen het framework dwingen onze eigen pagina's te gebruiken door ze in het application.properties bestand met de volgende instellingen:

mvc.view.404 = mijn-404.html mvc.view.500 = mijn-500.html 

Die HTML-pagina's moeten zeker onder de src / main / resources / templates map.

Binnen de 500 kunnen we bovendien de uitzondering terughalen bericht en de stackTrace via hun speciale variabelen:

    500 Interne server fout 

De volgende fout is opgetreden: "$ {bericht}"

 $ {stackTrace} 

13. Geplande taken

Een ander interessant kenmerk van het raamwerk is de mogelijkheid om de uitvoering van een methode te plannen.

Dat kan door de methode van een @Boon klasse met de @Schema annotatie:

@Bean public class ScheduleExample {@Schedule (name = "baeldungTask", cron = "0 * / 1 * * *?") Public void runScheduledTask () {System.out.println ("Dit is een geplande taak die één keer per minuut wordt uitgevoerd . "); }} 

Het gebruikt inderdaad de klassieke cron-expressies om de Datum Tijd coördinaten. We kunnen daar meer over lezen in A Guide to Cron Expressions.

Later zouden we de statische methoden van het Taakbeheer klasse om bewerkingen uit te voeren op de geplande taken.

  • Haal alle geplande taken op:
Lijst allScheduledTasks = TaskManager.getTasks (); 
  • Krijg een taak op naam:
Taak myTask = TaskManager.getTask ("baeldungTask"); 
  • Stop een taak op naam:
boolean closed = TaskManager.stopTask ("baeldungTask"); 

14. Evenementen

Zoals we al hebben gezien in sectie 9.1, is het mogelijk om naar een gespecificeerde gebeurtenis te luisteren voordat je een aangepaste code uitvoert.

Blade biedt de volgende evenementen uit de doos:

openbare opsomming EventType {SERVER_STARTING, SERVER_STARTED, SERVER_STOPPING, SERVER_STOPPED, SESSION_CREATED, SESSION_DESTROY, SOURCE_CHANGED, ENVIRONMENT_CHANGED} 

Hoewel de eerste zes gemakkelijk te raden zijn, hebben de laatste twee enkele hints nodig: ENVIRONMENT_CHANGED stelt ons in staat om een ​​actie uit te voeren als een configuratiebestand verandert wanneer de server is opgestart. SOURCE_CHANGEDin plaats daarvan is nog niet geïmplementeerd en is er alleen voor toekomstig gebruik.

Laten we eens kijken hoe we een waarde in de sessie kunnen plaatsen wanneer deze is gemaakt:

Blade.of () .on (EventType.SESSION_CREATED, e -> {Session session = (Session) e.attribute ("session"); session.attribute ("name", "Baeldung");}) .start (App .class, args); 

15. Sessie-implementatie

Over de sessie gesproken, de standaardimplementatie slaat sessiewaarden op in het geheugen.

We zouden daarom kunnen overschakelen naar een andere implementatie om cache, persistentie of iets anders te bieden. Laten we bijvoorbeeld Redis nemen. We zouden eerst onze Herdisessie wrapper door het implementeren van het Sessie interface, zoals getoond in de documenten voor de HttpSession.

Dan is het alleen een kwestie van het framework laten weten dat we het willen gebruiken. We kunnen dit op dezelfde manier doen als voor de aangepaste sjabloonengine, met het enige verschil dat we de sessionType () methode:

@Bean openbare klasse SessionConfig implementeert BladeLoader {@Override openbare leegte belasting (Blade blade) {blade.sessionType (nieuwe RedisSession ()); }} 

16. Opdrachtregelargumenten

Wanneer Blade vanaf de opdrachtregel wordt uitgevoerd, zijn er drie instellingen die we kunnen specificeren om het gedrag ervan te wijzigen.

Ten eerste kunnen we het IP-adres wijzigen, dat standaard het lokale is 0.0.0.0 loopback:

java -jar doel / sample-blade-app.jar --server.address = 192.168.1.100 

Ten tweede kunnen we ook de poort wijzigen, wat standaard is 9000:

java -jar doel / sample-blade-app.jar --server.port = 8080 

Tot slot, zoals te zien is in paragraaf 9.3, kunnen we de omgeving veranderen om een ​​andere te laten application-XXX.properties bestand dat moet worden gelezen over het standaardbestand, dat is application.properties:

java -jar doel / sample-blade-app.jar --app.env = prod 

17. Rennen in de IDE

Elke moderne Java-IDE kan een Blade-project afspelen zonder zelfs maar de Maven-plug-ins nodig te hebben. Blade uitvoeren in een IDE is vooral handig bij het uitvoeren van de Blade-demo's, voorbeelden die uitdrukkelijk zijn geschreven om de functionaliteiten van het framework te demonstreren. Ze erven allemaal een ouder pom, dus het is gemakkelijker om de IDE het werk te laten doen, in plaats van ze handmatig aan te passen om als zelfstandige apps te worden uitgevoerd.

17.1. Verduistering

In Eclipse is het voldoende om met de rechtermuisknop op het project te klikken en het te starten Uitvoeren als Java-applicatie, selecteer onze App klas en druk op OK.

De console van Eclipse zal de ANSI-kleuren echter niet correct weergeven en in plaats daarvan hun codes uitgieten:

Gelukkig lost het installeren van de ANSI Escape in Console-extensie het probleem voorgoed op:

17.2. IntelliJ IDEE

IntelliJ IDEA werkt standaard met ANSI-kleuren. Daarom is het voldoende om het project te maken, klik met de rechtermuisknop op het App bestand en start Voer ‘App.main () 'uit (wat gelijk staat aan persen Ctrl + Shift + F10):

17,3. Visual Studio Code

Het is ook mogelijk om VSCode, een populaire niet-Java-centrische IDE, te gebruiken door vooraf het Java Extension Pack te installeren.

Drukken Ctrl + F5 zal dan het project uitvoeren:

18. Conclusie

We hebben gezien hoe we Blade kunnen gebruiken om een ​​kleine MVC-applicatie te maken.

De volledige documentatie is alleen beschikbaar in de Chinese taal. Ondanks dat het vooral in China wijdverbreid is, heeft de auteur, dankzij zijn Chinese oorsprong, onlangs de API vertaald en de kernfunctionaliteiten van het project in het Engels gedocumenteerd op GitHub.

Zoals altijd kunnen we de broncode van het voorbeeld vinden op GitHub.