Vert.x HTTP服务器
Vert.x使创建HTTP服务器变得容易,因此应用程序可以接收HTTP请求。我们可以根据需要创建一个或者多个HTTP服务器。在本教程中,我将研究如何从垂直内部创建HTTP服务器以及如何处理请求。
创建一个HTTP服务器
使用Vertx
实例方法createHttpServer()
创建HTTP服务器。这是在Vert.x中创建HTTP服务器的示例:
HttpServer httpServer = vertx.createHttpServer();
通常是从一个Verticle内启动一个HTTP服务器。这样,在HTTP服务器上注册的所有处理程序将由启动verticle的同一线程执行。
import io.vertx.core.AbstractVerticle; import io.vertx.core.http.HttpServer; public class VertxHttpServerVerticle extends AbstractVerticle { private HttpServer httpServer = null; @Override public void start() throws Exception { httpServer = vertx.createHttpServer(); } }
启动HTTP服务器
一旦创建了HTTP服务器,就可以使用它的listen()
方法启动它。这是启动HTTP服务器的外观:
public class VertxHttpServerVerticle extends AbstractVerticle { private HttpServer httpServer = null; @Override public void start() throws Exception { httpServer = vertx.createHttpServer(); httpServer.listen(9999); } }
HttpServer类也具有listen()方法的更多版本,它为启动HTTP服务器提供了不同的选择。
在HTTP服务器上设置请求处理程序
为了处理传入的HTTP请求,我们必须在HTTP服务器上设置一个请求处理程序。通常,这是在启动服务器之前完成的。这是一个Vert.x HTTP服务器请求处理程序示例:
public class VertxHttpServerVerticle extends AbstractVerticle { private HttpServer httpServer = null; @Override public void start() throws Exception { httpServer = vertx.createHttpServer(); httpServer.requestHandler(new Handler<HttpServerRequest>() { @Override public void handle(HttpServerRequest request) { System.out.println("incoming request!"); } }); httpServer.listen(9999); } }
每当HTTP请求到达HTTP服务器时,都会调用Handler对象的handle方法。在handle()
方法内部,我们可以执行处理HTTP请求所需的代码。
请求标头和参数
我们可以从作为参数传递给handle()
方法的HttpServerRequest
对象访问HTTP标头和参数。这是一个示例,显示了如何访问HTTP请求的一些属性:
httpServer.requestHandler(new Handler<HttpServerRequest>() { @Override public void handle(HttpServerRequest request) { System.out.println("incoming request!"); request.uri(); request.path(); request.getParam("p1"); } });
处理POST请求
如果HTTP请求是HTTP POST请求,则需要以不同的方式处理它。我们需要将主体处理程序添加到HTTP请求。每当来自请求主体的数据到达时,就会调用主体处理程序。看起来是这样的:
httpServer.requestHandler(new Handler<HttpServerRequest>() { @Override public void handle(HttpServerRequest request) { System.out.println("incoming request!"); if(request.method() == HttpMethod.POST){ request.handler(new Handler<Buffer>() { @Override public void handle(Buffer buffer) { } }); } } });
如果我们要等到完整的HTTP POST正文到达时,可以添加一个结束处理程序。在接收到完整的HTTP POST主体之前,不会调用结束处理程序。但是,结束处理程序无法直接访问完整的HTTP POST主体。我们需要在请求处理程序中收集它。这是一个Vert.x HTTP请求结束处理程序示例,该示例执行所有操作:
httpServer.requestHandler(new Handler<HttpServerRequest>() { @Override public void handle(HttpServerRequest request) { System.out.println("incoming request!"); Buffer fullRequestBody = Buffer.buffer(); if(request.method() == HttpMethod.POST){ request.handler(new Handler<Buffer>() { @Override public void handle(Buffer buffer) { fullRequestBody.appendBuffer(buffer); } } request.endHandler(new Handler<Buffer>() { @Override public void handle(Buffer buffer) { // here you can access the // fullRequestBody Buffer instance. } }); } } });
传回HTTP回应
我们当然可以为传入的HTTP请求发回HTTP响应。为此,我们需要从请求对象获取HttpServerResponse
实例。这是获取HttpServerResponse
对象的方式:
HttpServerResponse response = request.response();
获得HttpServerResponse
实例后,我们可以设置HTTP响应状态代码和标头,如下所示:
response.setStatusCode(200); response.headers() .add("Content-Length", String.valueOf(57)) .add("Content-Type", "text/html") ;
回写头之后,我们可以通过write()方法回写响应主体,如下所示:
response.write("<!DOCTYPE html>Vert.x is alive!"); response.end();
我们可以多次调用write(),以将更多数据添加到响应正文中。在以Vert.xBuffer
实例为参数的版本中也存在write()
方法。此方法会将Buffer
的内容写入HTTP响应。
write()方法是异步的,在将字符串或者缓冲区排队后立即返回。
一旦完成了HTTP响应主体的编写,就应该结束HTTP响应。如上例所示,这是通过调用end()方法来完成的。我们还可以编写HTTP响应正文,并在单个方法调用中结束响应,如下所示:
response.end("<!DOCTYPE html>Vert.x is alive!");
end()方法可以采用String或者Buffer作为参数。该参数将被写入响应主体,然后响应结束。
关闭HTTP服务器
要关闭HTTP服务器,我们只需调用它的close()
方法,如下所示:
httpServer.close();
close()方法异步执行,因此,在close()方法返回时,HTTP服务器可能尚未完全关闭。我们可以将close处理函数作为参数传递给close()
方法,以便在HTTP服务器完全关闭时得到通知。