Undertow Web 服务器是一个由Red Hat赞助的开源极简主义Java网络服务器。Undertow被用于JBoss Wildfly应用服务器内部。Undertow提供了基于Java NIO的阻塞和非阻塞API,并有一个组合式的设计,使你能够通过将特殊用途的请求处理程序与你自己的自定义请求处理程序相结合,创建你自己的网络服务器。
Undertow被设计成可嵌入的,这意味着你可以在你自己的Java应用程序中创建和启动Undertow网络服务器。实际上,你可以在你的应用程序中启动多个Undertow网络服务器。
我所说的最小化是指可以将你的定制Java程序与嵌入的Undertow web服务器--包括其JAR文件的依赖关系--编译成一个独立的胖jar,小到5-6MB。
我已经用Undertow运行了好几年的网站,到目前为止,它运行得相当好。
我已经在 GitHub 存储库中发布了本教程中的许多 Undertow 示例,因此您可以查看完整的代码。每个示例都倾向于小而独立,使用最少的外部类——以使代码简单易读。这是 Undertow 示例 GitHub 存储库:
https://github.com/jjenkov/undertow-examples
<dependency> <groupId>io.undertow</groupId> <artifactId>undertow-core</artifactId> <version>2.1.0.Final</version> </dependency>
|
当你使用Undertow时,你创建了一个Undertow服务器。这个服务器在一个TCP端口上监听传入的HTTP请求。所有传入的HTTP请求被转发到你在Undertow服务器上设置的处理程序。下一节将介绍这个处理程序的情况。
import io.undertow.Undertow; import java.io.IOException;
public class UndertowHttpServer {
public static void main(String[] args) throws IOException { System.out.println("Building Undertow server");
WebHandler webHandler = new WebHandler();
Undertow.Builder builder = Undertow.builder(); Undertow undertow = builder .addHttpListener(80, "localhost") .setHandler(webHandler) .build();
System.out.println("Undertow started"); undertow.start(); } }
|
注意Undertow.Builder类,它被用来建立Undertow服务器实例。也注意到WebHandler,它是接收所有进入的HTTP请求的组件。请看下一节关于处理程序实现的例子。
这里是一个简单的Undertow处理程序,它接收一个请求并发送一个简单的、硬编码的响应:
import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange;
public class WebHandler implements HttpHandler {
@Override public void handleRequest(HttpServerExchange httpServerExchange) throws Exception { httpServerExchange .getResponseSender() .send("<!DOCTYPE html<>html<>body<>h1<Hello World from Undertow>/h1<>/body<>/html>"); } }
|
路由Undertow处理程序
如前所述,Undertow需要一个简单的Handler实例,接收所有进入Undertow服务器的HTTP请求。为了根据HTTP请求的URI将传入的请求路由到不同的处理程序实例,你必须自己实现一个路由处理程序。
下面是一个Undertow处理程序的简单例子,它查看传入的HTTP请求的URI,并通过在Map中按URI查找处理程序,将HTTP请求路由到与该URI匹配的处理程序:
import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange;
import java.util.HashMap; import java.util.Map;
public class RoutingHandler implements HttpHandler {
private Map<String, HttpHandler> handlerMap = new HashMap<>();
public void addHandler(String uri, HttpHandler handler) { this.handlerMap.put(uri, handler); }
@Override public void handleRequest(HttpServerExchange httpServerExchange) throws Exception { String uri = httpServerExchange.getRequestURI();
HttpHandler handler = this.handlerMap.get(uri);
if(handler != null) { handler.handleRequest(httpServerExchange); }
// else - send back an HTTP 404. See a later example. } }
|