Въведение в JBoss Undertow

1. Общ преглед

Undertow е изключително лек и високопроизводителен уеб сървър от JBoss . Той поддържа както блокиращи, така и неблокиращи API с NIO .

Тъй като е написано, че е Java, той може да се използва във всякакви JVM-базирани приложения във вграден режим, дори сървърът на WilfFly на JBoss използва вътрешно Undertow за подобряване на производителността на сървъра.

В този урок ще покажем характеристиките на Undertow и как да го използваме.

2. Защо Undertow?

  • Лек: Undertow е изключително лек при по-малко от 1MB. Във вграден режим той използва само 4MB пространство на куп по време на изпълнение
  • Servlet 3.1: Той напълно поддържа Servlet 3.1
  • Web Socket: Поддържа функционалността на Web Socket (включително JSR-356 )
  • Постоянна връзка: По подразбиране Undertow включва постоянни HTTP връзки чрез добавяне на заглавие на отговор за поддържане на живот . Той помага на клиентите, които поддържат постоянни връзки, да оптимизират производителността чрез повторно използване на подробностите за връзката

3. Използване на Undertow

Нека започнем да използваме Undertow, като създадем прост уеб сървър.

3.1. Зависимост на Maven

За да използваме Undertow , трябва да добавим следната зависимост към нашия pom.xml :

 io.undertow undertow-servlet 1.4.18.Final 

За да изградим работещ буркан, трябва също да добавим приставка maven-shadow-plugin. Ето защо трябва да добавим и конфигурация по-долу:

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

Най-новата версия на Undertow е достъпна в Централното хранилище на Maven.

3.2. Обикновен сървър

С кодовия фрагмент по-долу можем да създадем прост уеб сървър, използвайки 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(); } }

Тук използвахме API на Builder , за да свържем 8080 порт с този сървър. Също така имайте предвид, че използвахме ламбда израз, за ​​да използваме манипулатора.

Също така можем да използваме по-долу кодов фрагмент, за да направим същото, без да използваме ламбда изрази:

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

Важното, което трябва да се отбележи тук, е използването на API на HttpHandler . Това е най-важният плъгин за персонализиране на приложение Undertow въз основа на нашите нужди.

В този случай сме добавили персонализиран манипулатор, който ще добави заглавка Content-Type: text / plain response при всяка заявка.

По подобен начин, ако искаме да върнем някакъв текст по подразбиране с всеки отговор, можем да използваме по-долу кодов фрагмент:

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

3.3. Сигурен достъп

В повечето случаи не разрешаваме на всички потребители достъп до нашия сървър. Обикновено потребителите с валидни идентификационни данни могат да получат достъп. Можем да приложим същия механизъм с Undertow .

За да го приложим, трябва да създадем диспечер на идентичност, който да проверява автентичността на потребителя за всяка заявка.

За това можем да използваме IdentityManager на Undertow :

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

След като мениджърът на идентичността е създаден, трябва да създадем царство, което да съдържа потребителските идентификационни данни:

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

Тук използвахме AuthenticationMode като PRO_ACTIVE, което означава, че всяка заявка, пристигаща към този сървър, ще бъде предавана на дефинираните механизми за удостоверяване, за да изпълнява усърдно удостоверяване.

Ако дефинираме AuthenticationMode като CONSTRAINT_DRIVEN , тогава само тези заявки ще преминат през дефинираните механизми за удостоверяване, където се задейства ограничението / ите, които налагат удостоверяване.

Сега просто трябва да картографираме това царство и мениджъра на идентичността със сървъра, преди да започне:

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

Тук създадохме два потребителски екземпляра с идентификационни данни. След като сървърът работи, за достъп до него трябва да използваме някоя от тези две идентификационни данни.

3.4. Уеб гнездо

Лесно е да се създаде канал за обмен на уеб гнезда с API на UnderTow WebSocketHttpExchange .

Например можем да отворим канал за комуникация на сокет по пътя baeldungApp с кодов фрагмент по-долу:

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

Можем да създадем HTML страница с име index.html и да използваме WebSocket API на JavaScript, за да се свържем с този канал.

3.5. Файлов сървър

С Undertow можем да създадем и файлов сървър, който да показва съдържанието на директорията и директно да обслужва файлове от директорията:

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

Не е необходимо да създаваме съдържание на потребителски интерфейс, за да покажем съдържанието на директорията. Out-на-на-кутия Undertow осигурява страница за тази функционалност дисплей.

4. Приставка за пролетно стартиране

Освен Tomcat и Jetty, Spring Boot поддържа UnderTow като вграден контейнер за сървлети. За да използваме Undertow , трябва да добавим следната зависимост в pom.xml:

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

Най-новата версия на приставката Spring Boot Undertow е достъпна в Централното хранилище на Maven.

5. Заключение

В тази статия научихме за Undertow и как можем да създаваме различни видове сървъри с него.

Както винаги, пълният изходен код е достъпен в GitHub.