Introduzione a JBoss Undertow

1. Panoramica

Undertow è un server web estremamente leggero e ad alte prestazioni di JBoss . Supporta API di blocco e non di blocco con NIO .

Poiché è scritto in Java, può essere utilizzato in qualsiasi applicazione basata su JVM in modalità incorporata, anche il server WilfFly di JBoss utilizza internamente Undertow per migliorare le prestazioni del server.

In questo tutorial, mostreremo le caratteristiche di Undertow e come usarlo.

2. Perché risacca?

  • Leggero: Undertow è estremamente leggero a meno di 1 MB. In modalità incorporata, utilizza solo 4 MB di spazio heap in fase di esecuzione
  • Servlet 3.1: supporta completamente Servlet 3.1
  • Web Socket: supporta la funzionalità Web Socket (incluso JSR-356 )
  • Connessione persistente: per impostazione predefinita, Undertow include connessioni persistenti HTTP aggiungendo un'intestazione di risposta keep-alive . Aiuta i client che supportano le connessioni persistenti a ottimizzare le prestazioni riutilizzando i dettagli della connessione

3. Utilizzo di risacca

Cominciamo ad utilizzare Undertow creando un semplice web server.

3.1. Dipendenza da Maven

Per utilizzare Undertow , dobbiamo aggiungere la seguente dipendenza al nostro pom.xml :

 io.undertow undertow-servlet 1.4.18.Final 

Per costruire un jar eseguibile, dobbiamo anche aggiungere maven-shade-plugin. Ecco perché dobbiamo aggiungere anche la configurazione di seguito:

 org.apache.maven.plugins maven-shade-plugin   package  shade    

L'ultima versione di Undertow è disponibile in Central Maven Repository.

3.2. Server semplice

Con lo snippet di codice riportato di seguito, possiamo creare un semplice server web utilizzando l' API Builder di Undertow :

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("Hello Baeldung"); }).build(); server.start(); } }

Qui, abbiamo utilizzato l' API Builder per associare la porta 8080 a questo server. Inoltre, tieni presente che abbiamo usato un'espressione lambda per utilizzare il gestore.

Possiamo anche usare lo snippet di codice seguente per fare la stessa cosa senza usare espressioni lambda:

Undertow server = Undertow.builder().addHttpListener(8080, "localhost") .setHandler(new HttpHandler() { @Override public void handleRequest(HttpServerExchange exchange) throws Exception { exchange.getResponseHeaders().put( Headers.CONTENT_TYPE, "text/plain"); exchange.getResponseSender().send("Hello Baeldung"); } }).build();

La cosa importante da notare qui è l'utilizzo dell'API HttpHandler . È il plugin più importante per personalizzare un'applicazione Undertow in base alle nostre esigenze.

In questo caso, abbiamo aggiunto un gestore personalizzato che aggiungerebbe il Content-Type: text / plain response header con ogni richiesta.

Allo stesso modo, se vogliamo restituire del testo predefinito con ogni risposta, possiamo usare lo snippet di codice seguente:

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

3.3. Accesso sicuro

Nella maggior parte dei casi, non consentiamo a tutti gli utenti di accedere al nostro server. Di solito, gli utenti con credenziali valide possono ottenere l'accesso. Possiamo implementare lo stesso meccanismo con Undertow .

Per implementarlo, dobbiamo creare un gestore di identità che controllerà l'autenticità dell'utente per ogni richiesta.

Possiamo usare IdentityManager di Undertow per questo:

public class CustomIdentityManager implements IdentityManager { private Map users; // standard constructors @Override public Account verify(Account account) { return account; } @Override public Account verify(Credential credential) { return null; } @Override public Account verify(String id, Credential credential) { Account account = getAccount(id); if (account != null && verifyCredential(account, credential)) { return account; } return null; } }

Una volta creato il gestore delle identità, dobbiamo creare un regno che conterrà le credenziali dell'utente:

private static HttpHandler addSecurity( HttpHandler toWrap, IdentityManager identityManager) { HttpHandler handler = toWrap; handler = new AuthenticationCallHandler(handler); handler = new AuthenticationConstraintHandler(handler); List mechanisms = Collections.singletonList( new BasicAuthenticationMechanism("Baeldung_Realm")); handler = new AuthenticationMechanismsHandler(handler, mechanisms); handler = new SecurityInitialHandler( AuthenticationMode.PRO_ACTIVE, identityManager, handler); return handler; }

Qui, abbiamo utilizzato AuthenticationMode come PRO_ACTIVE, il che significa che ogni richiesta in arrivo a questo server verrà passata ai meccanismi di autenticazione definiti per eseguire l'autenticazione con entusiasmo.

Se definiamo AuthenticationMode come CONSTRAINT_DRIVEN , solo quelle richieste passeranno attraverso i meccanismi di autenticazione definiti in cui viene attivato il vincolo / i che impone l'autenticazione.

Ora, dobbiamo solo mappare questo regno e il gestore delle identità con il server prima che inizi:

public static void main(String[] args) { Map users = new HashMap(2); users.put("root", "password".toCharArray()); users.put("admin", "password".toCharArray()); IdentityManager idm = new CustomIdentityManager(users); Undertow server = Undertow.builder().addHttpListener(8080, "localhost") .setHandler(addSecurity(e -> setExchange(e), idm)).build(); server.start(); } private static void setExchange(HttpServerExchange exchange) { SecurityContext context = exchange.getSecurityContext(); exchange.getResponseSender().send("Hello " + context.getAuthenticatedAccount().getPrincipal().getName(), IoCallback.END_EXCHANGE); }

Qui abbiamo creato due istanze utente con credenziali. Una volta che il server è attivo, per accedervi, dobbiamo utilizzare una di queste due credenziali.

3.4. Web Socket

È semplice creare un canale di scambio di socket web con l' API WebSocketHttpExchange di UnderTow .

Ad esempio, possiamo aprire un canale di comunicazione socket sul percorso baeldungApp con lo snippet di codice seguente:

public static void main(String[] args) { Undertow server = Undertow.builder().addHttpListener(8080, "localhost") .setHandler(path().addPrefixPath("/baeldungApp", websocket( (exchange, channel) -> { channel.getReceiveSetter().set(getListener()); channel.resumeReceives(); })).addPrefixPath("/", resource(new ClassPathResourceManager( SocketServer.class.getClassLoader(), SocketServer.class.getPackage())).addWelcomeFiles("index.html"))) .build(); server.start(); } private static AbstractReceiveListener getListener() { return new AbstractReceiveListener() { @Override protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) { String messageData = message.getData(); for (WebSocketChannel session : channel.getPeerConnections()) { WebSockets.sendText(messageData, session, null); } } }; }

Possiamo creare una pagina HTML denominata index.html e utilizzare l' API WebSocket di JavaScript per connetterci a questo canale.

3.5. File server

Con Undertow , possiamo anche creare un file server che può visualizzare il contenuto della directory e serve direttamente i file dalla directory:

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

Non è necessario creare alcun contenuto dell'interfaccia utente per visualizzare il contenuto della directory. Undertow out-of-the-box fornisce una pagina per questa funzionalità di visualizzazione.

4. Plugin Spring Boot

Oltre a Tomcat e Jetty, Spring Boot supporta UnderTow come contenitore servlet incorporato. Per utilizzare Undertow , dobbiamo aggiungere la seguente dipendenza nel pom.xml:

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

L'ultima versione del plug-in Spring Boot Undertow è disponibile in Central Maven Repository.

5. conclusione

In questo articolo abbiamo scoperto Undertow e come possiamo creare diversi tipi di server con esso.

Come sempre, il codice sorgente completo è disponibile su GitHub.