Pengantar JBoss Undertow

1. Ikhtisar

Undertow adalah server web yang sangat ringan dan berkinerja tinggi dari JBoss . Ini mendukung API pemblokiran dan non-pemblokiran dengan NIO .

Karena yang tertulis adalah Java, ini dapat digunakan dalam aplikasi berbasis JVM dalam mode tertanam, bahkan server WilfFly JBoss secara internal menggunakan Undertow untuk meningkatkan kinerja server.

Dalam tutorial ini, kami akan menunjukkan fitur Undertow dan cara menggunakannya.

2. Mengapa Undertow?

  • Ringan: Undertow sangat ringan di bawah 1MB. Dalam mode tertanam, ini hanya menggunakan 4MB ruang heap saat runtime
  • Servlet 3.1: Ini sepenuhnya mendukung Servlet 3.1
  • Web Socket: Mendukung fungsionalitas Web Socket (termasuk JSR-356 )
  • Koneksi Persisten: Secara default, Undertow menyertakan koneksi persisten HTTP dengan menambahkan header respons keep-hidup . Ini membantu klien yang mendukung koneksi persisten untuk mengoptimalkan kinerja dengan menggunakan kembali detail koneksi

3. Menggunakan Undertow

Mari mulai menggunakan Undertow dengan membuat server web sederhana.

3.1. Ketergantungan Maven

Untuk menggunakan Undertow , kita perlu menambahkan dependensi berikut ke pom.xml kita :

 io.undertow undertow-servlet 1.4.18.Final 

Untuk membuat jar yang dapat dijalankan, kita juga perlu menambahkan maven-shade-plugin. Itulah mengapa kita juga perlu menambahkan konfigurasi di bawah ini:

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

Versi terbaru Undertow tersedia di Central Maven Repository.

3.2. Server Sederhana

Dengan potongan kode di bawah ini, kita dapat membuat server web sederhana menggunakan API Builder 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(); } }

Di sini, kami menggunakan Builder API untuk mengikat port 8080 ke server ini. Juga, perhatikan bahwa kami telah menggunakan ekspresi lambda untuk menggunakan penangan.

Kita juga dapat menggunakan potongan kode di bawah ini untuk melakukan hal yang sama tanpa menggunakan ekspresi 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();

Hal penting yang perlu diperhatikan di sini adalah penggunaan API HttpHandler . Ini adalah plugin terpenting untuk menyesuaikan aplikasi Undertow berdasarkan kebutuhan kita.

Dalam kasus ini, kami telah menambahkan penangan yang disesuaikan yang akan menambahkan Content-Type: text / plain response header dengan setiap permintaan.

Dengan cara serupa, jika kita ingin mengembalikan beberapa teks default dengan setiap tanggapan, kita dapat menggunakan cuplikan kode di bawah ini:

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

3.3. Akses Aman

Dalam kebanyakan kasus, kami tidak mengizinkan semua pengguna untuk mengakses server kami. Biasanya, pengguna dengan kredensial yang valid bisa mendapatkan akses. Kita bisa menerapkan mekanisme yang sama dengan Undertow .

Untuk mengimplementasikannya, kita perlu membuat manajer identitas yang akan memeriksa keaslian pengguna untuk setiap permintaan.

Kita dapat menggunakan IdentityManager Undertow untuk ini:

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; } }

Setelah pengelola identitas dibuat, kita perlu membuat ranah yang akan menyimpan kredensial pengguna:

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; }

Di sini, kami telah menggunakan AuthenticationMode sebagai PRO_ACTIVE yang berarti setiap permintaan yang datang ke server ini akan diteruskan ke mekanisme otentikasi yang ditentukan untuk melakukan otentikasi dengan bersemangat.

Jika kita mendefinisikan AuthenticationMode sebagai CONSTRAINT_DRIVEN , maka hanya permintaan tersebut yang akan melalui mekanisme otentikasi yang ditentukan di mana batasan yang memerintahkan otentikasi dipicu.

Sekarang, kita hanya perlu memetakan ranah ini dan pengelola identitas dengan server sebelum dimulai:

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); }

Di sini, kami telah membuat dua contoh pengguna dengan kredensial. Setelah server aktif, untuk mengaksesnya, kita perlu menggunakan salah satu dari dua kredensial ini.

3.4. Soket Web

Sangat mudah untuk membuat saluran pertukaran soket web dengan API WebSocketHttpExchange UnderTow .

Misalnya, kita dapat membuka saluran komunikasi soket di jalur baeldungApp dengan potongan kode di bawah ini:

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); } } }; }

Kita dapat membuat halaman HTML bernama index.html dan menggunakan JavaScript WebSocket API untuk terhubung ke saluran ini.

3.5. File Server

Dengan Undertow , kita juga dapat membuat server file yang dapat menampilkan konten direktori dan langsung menyajikan file dari direktori:

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(); }

Kami tidak perlu membuat konten UI apa pun untuk menampilkan konten direktori. Out-of-the-box Undertow menyediakan halaman untuk fungsionalitas tampilan ini.

4. Plugin Boot Musim Semi

Selain Tomcat dan Jetty, Spring Boot mendukung UnderTow sebagai wadah servlet tertanam. Untuk menggunakan Undertow , kita perlu menambahkan dependensi berikut di pom.xml:

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

Versi terbaru dari plugin Spring Boot Undertow tersedia di Central Maven Repository.

5. Kesimpulan

Pada artikel ini, kami belajar tentang Undertow dan bagaimana kami dapat membuat berbagai jenis server dengannya.

Seperti biasa, kode sumber lengkap tersedia di GitHub.