Inleiding tot JBoss Undertow

1. Overzicht

Undertow is een extreem lichtgewicht en krachtige webserver van JBoss. Het ondersteunt zowel blokkerende als niet-blokkerende API's met NIO.

Omdat het in Java is geschreven, kan het in alle JVM-gebaseerde applicaties in embedded modus worden gebruikt, zelfs in JBoss WilfFly server intern gebruikt Undertow om de prestaties van de server te verbeteren.

In deze tutorial laten we de functies van Undertow zien en hoe je deze kunt gebruiken.

2. Waarom Undertow?

  • Lichtgewicht: Undertow is extreem licht met minder dan 1 MB. In embedded modus gebruikt het tijdens runtime slechts 4 MB aan heap-ruimte
  • Servlet 3.1: het ondersteunt volledig Servlet 3.1
  • Web Socket: het ondersteunt Web Socket-functionaliteit (inclusief JSR-356)
  • Permanente verbinding: standaard, Undertow omvat permanente HTTP-verbindingen door in leven houden antwoord header. Het helpt clients die blijvende verbindingen ondersteunen om de prestaties te optimaliseren door verbindingsdetails opnieuw te gebruiken

3. Undertow gebruiken

Laten we beginnen met gebruiken Undertow door een eenvoudige webserver te maken.

3.1. Afhankelijkheid van Maven

Gebruiken Undertow, moeten we de volgende afhankelijkheid toevoegen aan onze pom.xml:

 io.onderstroom-onderstroom-servlet 1.4.18.Finale 

Om een ​​uitvoerbare pot te bouwen, moeten we ook maven-shad-plug-in toevoegen. Daarom moeten we ook onderstaande configuratie toevoegen:

 org.apache.maven.plugins maven-shad-plugin pakketschaduw 

De nieuwste versie van Undertow is beschikbaar in Central Maven Repository.

3.2. Eenvoudige server

Met het onderstaande codefragment kunnen we een eenvoudige webserver maken met behulp van Undertow's Bouwer API:

public class SimpleServer {public static void main (String [] args) {Undertow server = Undertow.builder (). addHttpListener (8080, "localhost"). setHandler (exchange -> {exchange.getResponseHeaders () .put (Headers.CONTENT_TYPE , "text / plain"); exchange.getResponseSender (). send ("Hallo Baeldung");}). build (); server.start (); }}

Hier hebben we de Bouwer API om te binden 8080 poort naar deze server. Merk ook op dat we een lambda-expressie hebben gebruikt om de handler te gebruiken.

We kunnen ook het onderstaande codefragment gebruiken om hetzelfde te doen zonder lambda-expressies te gebruiken:

Undertow server = Undertow.builder (). AddHttpListener (8080, "localhost") .setHandler (nieuwe HttpHandler () {@Override public void handleRequest (HttpServerExchange exchange) gooit Uitzondering {exchange.getResponseHeaders (). Put (Headers.CONTENT_TYPE, " text / plain "); exchange.getResponseSender (). send (" Hallo Baeldung ");}}). build ();

Het belangrijkste om op te merken is het gebruik van de HttpHandler API. Het is de belangrijkste plug-in om een Undertow toepassing op basis van onze behoeften.

In dit geval hebben we een aangepaste handler toegevoegd die de Inhoudstype: tekst / gewoon antwoordheader bij elk verzoek.

Op dezelfde manier, als we bij elk antwoord een standaardtekst willen retourneren, kunnen we het onderstaande codefragment gebruiken:

exchange.getResponseSender () .send ("Hallo Baeldung");

3.3. Beveiligde toegang

In de meeste gevallen geven we niet alle gebruikers toegang tot onze server. Gewoonlijk kunnen gebruikers met geldige inloggegevens toegang krijgen. We kunnen hetzelfde mechanisme implementeren met de Undertow.

Om het te implementeren, moeten we een identiteitsmanager maken die de authenticiteit van de gebruiker voor elk verzoek controleert.

We kunnen Undertow's gebruiken IdentityManager voor deze:

openbare klasse CustomIdentityManager implementeert IdentityManager {privékaartgebruikers; // standaardconstructeurs @Override openbare accountverificatie (accountaccount) {retourneer account; } @Override openbare account verifiëren (inlogreferentie) {retourneer null; } @Override openbare accountverificatie (String-id, referentie-referentie) {Account account = getAccount (id); if (account! = null && verifyCredential (account, credential)) {retourneer account; } retourneer null; }}

Nadat de identiteitsmanager is gemaakt, moeten we een realm maken die de gebruikersreferenties bevat:

privé statische HttpHandler addSecurity (HttpHandler toWrap, IdentityManager identityManager) {HttpHandler handler = toWrap; handler = nieuwe AuthenticationCallHandler (handler); handler = nieuwe AuthenticationConstraintHandler (handler); Lijstmechanismen = Collections.singletonList (nieuw BasicAuthenticationMechanism ("Baeldung_Realm")); handler = nieuwe AuthenticationMechanismsHandler (handler, mechanismen); handler = nieuwe SecurityInitialHandler (AuthenticationMode.PRO_ACTIVE, identityManager, handler); terugkeer afhandelaar; }

Hier hebben we de AuthenticationMode net zo PRO_ACTIVE wat betekent dat elk verzoek dat naar deze server komt, wordt doorgegeven aan de gedefinieerde authenticatiemechanismen om authenticatie gretig uit te voeren.

Als we definiëren AuthenticationMode net zo CONSTRAINT_DRIVEN, dan zullen alleen die verzoeken door de gedefinieerde authenticatiemechanismen gaan waar de beperking (en) die authenticatie verplicht stellen wordt geactiveerd.

Nu hoeven we alleen dit rijk en de identiteitsmanager in kaart te brengen met de server voordat het begint:

public static void main (String [] args) {Map users = new HashMap (2); users.put ("root", "wachtwoord" .toCharArray ()); users.put ("admin", "wachtwoord" .toCharArray ()); IdentityManager idm = nieuwe CustomIdentityManager (gebruikers); Undertow server = Undertow.builder (). AddHttpListener (8080, "localhost") .setHandler (addSecurity (e -> setExchange (e), idm)). Build (); server.start (); } privé statische ongeldige setExchange (HttpServerExchange-uitwisseling) {SecurityContext context = exchange.getSecurityContext (); exchange.getResponseSender (). send ("Hallo" + context.getAuthenticatedAccount (). getPrincipal (). getName (), IoCallback.END_EXCHANGE); }

Hier hebben we twee gebruikersinstanties gemaakt met inloggegevens. Als de server eenmaal is opgestart, moeten we een van deze twee inloggegevens gebruiken om er toegang toe te krijgen.

3.4. Web-aansluiting

Het is eenvoudig om een ​​uitwisselingskanaal voor websockets te maken UnderTow's WebSocketHttpExchange API.

We kunnen bijvoorbeeld een socketcommunicatiekanaal op pad openen baeldungApp met onderstaand codefragment:

public static void main (String [] args) {Undertow server = Undertow.builder (). addHttpListener (8080, "localhost") .setHandler (pad (). addPrefixPath ("/ baeldungApp", websocket ((exchange, channel) - > {channel.getReceiveSetter (). set (getListener ()); channel.resumeReceives ();})). addPrefixPath ("/", resource (nieuwe ClassPathResourceManager (SocketServer.class.getClassLoader (), SocketServer.class.getPackage ( ))). addWelcomeFiles ("index.html"))) .build (); server.start (); } privé statisch AbstractReceiveListener getListener () {retourneer nieuwe AbstractReceiveListener () {@Override beschermde leegte onFullTextMessage (WebSocketChannel-kanaal, BufferedTextMessage-bericht) {String messageData = message.getData (); voor (WebSocketChannel-sessie: channel.getPeerConnections ()) {WebSockets.sendText (messageData, sessie, null); }}}; }

We kunnen een HTML-pagina maken met de naam index.html en gebruik JavaScript's WebSocket API om verbinding te maken met dit kanaal.

3.5. Bestanden server

Met Undertow, kunnen we ook een bestandsserver maken die directory-inhoud kan weergeven en direct bestanden uit de directory kan aanbieden:

public static void main (String [] args) {Undertow server = Undertow.builder (). addHttpListener (8080, "localhost") .setHandler (resource (nieuwe PathResourceManager (Paths.get (System.getProperty ("user.home") ), 100)) .setDirectoryListingEnabled (true)) .build (); server.start (); }

We hoeven geen UI-inhoud te maken om de inhoud van de directory weer te geven. Out-of-the-box Undertow biedt een pagina voor deze weergavefunctie.

4. Spring Boot-plug-in

Losstaand van Kater en Steiger,Spring Boot ondersteunt UnderTow als de embedded servlet-container. Gebruiken Undertow, moeten we de volgende afhankelijkheid toevoegen in het pom.xml:

 org.springframework.boot spring-boot-starter-onderstroom 1.5.6.RELEASE 

De nieuwste versie van Spring Boot Undertow-plug-in is beschikbaar in Central Maven Repository.

5. Conclusie

In dit artikel hebben we geleerd over Undertow en hoe we er verschillende soorten servers mee kunnen maken.

Zoals altijd is de volledige broncode beschikbaar op GitHub.