Undertow · JBoss Community
Undertow
Undertow is a flexible performant web server written in java, providing both blocking and non-blocking API’s based on NIO.
Undertow 是一个用 Java 编写的灵活高性能 Web 服务器,提供基于 NIO 的阻塞和非阻塞 API。
Undertow has a composition based architecture that allows you to build a web server by combining small single purpose handlers. The gives you the flexibility to choose between a full Java EE servlet 4.0 container, or a low level non-blocking handler, to anything in between.
Undertow采用基于组合的架构,允许您通过组合小型单一功能处理器来构建Web服务器。这种架构让您能够灵活选择——无论是完整的Java EE Servlet 4.0容器,还是底层的非阻塞处理器,抑或是介于两者之间的任何方案。(备注: Oracle Java EE 是收订阅费的。)
Undertow is designed to be fully embeddable, with easy to use fluent builder APIs. Undertow’s lifecycle is completely controlled by the embedding application.
Undertow 设计为完全可嵌入式,提供易于使用的流式构建器 API。其生命周期完全由嵌入应用控制。
Undertow is sponsored by JBoss and is the default web server in the Wildfly Application Server.
文档 Online Undertow
There are two main ways that Undertow can be used, either by directly embedding it in your code, or as part of the Wildfly Application Server. This guide mostly focuses on the embedded API’s, although a lot of the content is still relevant if you are using Wildfly, it is just that the relevant functionality will generally be exposed via XML configuration rather than programmatic configuration.
Undertow主要有两种使用方式:一种是直接嵌入到代码中,另一种是作为Wildfly应用服务器的一部分。本指南主要聚焦于嵌入式API,尽管大部分内容对Wildfly用户同样适用,只是相关功能通常通过XML配置而非编程配置来实现。
HTTP/2 Support
Undertow supports HTTP/2 out of the box, no overriding the boot class path required.
Undertow 开箱即支持 HTTP/2,无需覆盖引导类路径。
HTTP Upgrade Support
Support for HTTP upgrade, to allow multiple protocols to be multiplexed over the HTTP port.
支持HTTP升级,允许多种协议在HTTP端口上实现多路复用。
Web Socket Support
Undertow provides full support for Web Sockets, including JSR-356 support.
Undertow 全面支持 Web Sockets,包括对 JSR-356 的支持。
Servlet 4.0
Undertow provides support for Servlet 4.0, including support for embedded servlet. It is also possible to mix both Servlets and native undertow non-blocking handlers in the same deployment.
Undertow 支持 Servlet 4.0,包括对嵌入式 servlet 的支持。在同一部署中也可以混合使用 Servlets 和原生的 undertow 非阻塞处理程序。
Embeddable
Undertow can be embedded in an application or run standalone with just a few lines of code.
Undertow 可以嵌入到应用程序中,也可以仅用几行代码独立运行。
Flexible
An Undertow server is configured by chaining handlers together. It is possible to add as much or as little functionality as you need, so you don’t pay for what you are not using.
Undertow服务器的配置通过将处理器链式连接来实现。您可以根据需求自由增减功能模块,从而避免为未使用的功能付出额外开销。
启动
public class HelloWorldServer {public static void main(final String[] args) {Undertow server = Undertow.builder().addHttpListener(8080, "localhost").setHandler(new HttpHandler() {@Overridepublic void handleRequest(final HttpServerExchange exchange) throws Exception {exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");exchange.getResponseSender().send("Hello World");}}).build();server.start();}
}
处理 500 错误
public class SimpleErrorPageHandler implements HttpHandler {private final HttpHandler next;public SimpleErrorPageHandler(final HttpHandler next) {this.next = next;}@Overridepublic void handleRequest(final HttpServerExchange exchange) throws Exception {exchange.addDefaultResponseListener(new DefaultResponseListener() {@Overridepublic boolean handleDefaultResponse(final HttpServerExchange exchange) {if (!exchange.isResponseChannelAvailable()) {return false;}Set<Integer> codes = responseCodes;if (exchange.getResponseCode() == 500) {final String errorPage = "<html><head><title>Error</title></head><body>Internal Error</body></html>";exchange.getResponseHeaders().put(Headers.CONTENT_LENGTH, "" + errorPage.length());exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/html");Sender sender = exchange.getResponseSender();sender.send(errorPage);return true;}return false;}});next.handleRequest(exchange);}
}
In order to use Undertow in your maven projects just include the following section in your pom.xml, and set the undertow.version property to whatever version of Undertow you wish to use. Only the core artifact is required, if you are not using Servlet or JSR-356 then those artifacts are not required.
要在您的 Maven 项目中使用 Undertow,只需在 pom.xml 文件中包含以下部分,并将 undertow.version 属性设置为您希望使用的 Undertow 版本。仅需核心构件(core artifact),如果您不使用 Servlet 或 JSR-356,则无需包含这些构件。
<dependency><groupId>io.undertow</groupId><artifactId>undertow-core</artifactId><version>${undertow.version}</version>
</dependency>
<dependency><groupId>io.undertow</groupId><artifactId>undertow-servlet</artifactId><version>${undertow.version}</version>
</dependency>
<dependency><groupId>io.undertow</groupId><artifactId>undertow-websockets-jsr</artifactId><version>${undertow.version}</version>
</dependency>
Undertow depends on XNIO and JBoss Logging, which will need to be downloaded as well.
Undertow依赖于XNIO和JBoss Logging,这些也需要下载。
https://github.com/jboss-logging/jboss-logging
XNIO - JBoss Community
Bootstrapping Undertow
There are two ways to bootstrap Undertow. The first and most simple is to use the io.undertow.Undertow builder API. The second is to assemble a server using XNIO and the Undertow listener classes directly. This second approach requires more code, but gives more flexibility. It is anticipated that for most use cases the builder API will be sufficient.
有两种方式来引导Undertow。第一种也是最简单的方式是使用io.undertow.Undertow构建器API。第二种是直接使用XNIO和Undertow监听器类来组装服务器。第二种方法需要编写更多代码,但提供了更大的灵活性。预计对于大多数用例来说,构建器API已经足够。
One thing that it is important to understand about Undertow is that there is not really any concept of an Undertow container. Undertow applications are assembled from multiple handler classes, and it is up to the embedding application to manage the lifecycle of all the these handlers. This was a deliberate design decision in order to give the embedding application as much control as possible. This is generally only an issue if you have handlers that hold resources that need to be cleaned up at server stop.
关于Undertow需要理解的重要一点是,它实际上并不存在"Undertow容器"的概念。Undertow应用程序由多个处理器类组装而成,而这些处理器的生命周期管理完全取决于嵌入应用程序。这是一项经过深思熟虑的设计决策,目的是为了赋予嵌入应用程序最大限度的控制权。通常只有当您使用的处理器持有需要在服务器停止时清理的资源时,这才成为一个需要考虑的问题。
import io.undertow.Undertow;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.Headers;public class HelloWorldServer {public static void main(final String[] args) {Undertow server = Undertow.builder().addHttpListener(8080, "localhost").setHandler(new HttpHandler() {@Overridepublic void handleRequest(final HttpServerExchange exchange) throws Exception {exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");exchange.getResponseSender().send("Hello World");}}).build();server.start();}
}
Why isn’t Undertow based on Mina, Netty, RNIO, Grizzly, or <insert network framework>?
In order to best achieve its goals, Undertow requires very close integration with the underlying I/O infrastructure in the Java platform. The simplicity offered by any abstraction comes from hiding the underlying mechanisms behind it. However, the dilemma is that building an extremely efficient and flexible web server requires customization and control of these mechanisms. Undertow attempts to strike the right balance by reusing a minimalistic I/O library, XNIO, that was created for WildFly’s remote invocation layer.
为了最好地实现其目标,Undertow需要与Java平台中的底层I/O基础设施进行非常紧密的集成。任何抽象所提供的简单性都源于对其背后底层机制的隐藏。然而,难题在于构建一个极其高效且灵活的Web服务器需要对这些机制进行定制和控制。Undertow尝试通过复用为WildFly远程调用层创建的极简I/O库XNIO,来达到恰当的平衡。
XNIO allows us to eliminate some boiler plate, and also allows for direct I/O integration with the operating system, but it does not go further than that. In addition, XNIO offers very strong backwards compatibility which is important since this is also a concern for the Undertow project. Of course, other projects may have different needs, and thus might make different choices.
XNIO 让我们能够减少一些样板代码,并实现与操作系统的直接 I/O 集成,但它的功能也仅限于此。此外,XNIO 提供了极强的向后兼容性,这一点非常重要,因为这也是 Undertow 项目关注的重点。当然,其他项目可能有不同的需求,因此可能会做出不同的选择。