Vert.x HTTP Server
Jakob Jenkov |
Vert.x makes it easy to create an HTTP server so your application can receive HTTP requests. You can create one or more HTTP servers, depending on your need. In this tutorial I will look at how to create an HTTP server from inside a verticle and how to handle requests.
Creating an HTTP Server
Creating an HTTP server is done using the Vertx
instance method createHttpServer()
.
Here is an example of creating an HTTP server in Vert.x:
HttpServer httpServer = vertx.createHttpServer();
It is common to start an HTTP server from within an verticle. That way all handlers registered on the HTTP server will be executed by the same thread that started the 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(); } }
Starting the HTTP Server
Once you have created the HTTP server, you can start it using its listen()
method.
Here is how starting the HTTP server looks:
public class VertxHttpServerVerticle extends AbstractVerticle { private HttpServer httpServer = null; @Override public void start() throws Exception { httpServer = vertx.createHttpServer(); httpServer.listen(9999); } }
The HttpServer
class has more versions of the listen()
method too, which gives you different
options for starting the HTTP server.
Setting a Request Handler on the HTTP Server
In order to handle incoming HTTP requests you must set a request handler on the HTTP server. This is normally done before starting the server. Here is a Vert.x HTTP server request handler example:
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); } }
Every time an HTTP request arrives at the HTTP server, the handle()
method of the Handler
object is called. Inside the handle()
method you can execute the code needed to handle the
HTTP request.
Request Headers and Parameters
You can access HTTP headers and parameters from the HttpServerRequest
object passed
as parameter to the handle()
method. Here is an example showing how to access a few of the properties
of a HTTP request:
httpServer.requestHandler(new Handler<HttpServerRequest>() { @Override public void handle(HttpServerRequest request) { System.out.println("incoming request!"); request.uri(); request.path(); request.getParam("p1"); } });
Handling POST Requests
If the HTTP request is a HTTP POST request you need to handle it a bit differently. You need to attach a body handler to the HTTP request. The body handler is called whenever data from the request body arrives. Here is how that looks:
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) { } }); } } });
If you want to wait until the full HTTP POST body has arrived you can attach an end handler instead. The end handler is not called until the full HTTP POST body has been received. However, the end handler does not have direct access to the full HTTP POST body. You need to collect that in the request handler. Here is a Vert.x HTTP request end handler example which does all that:
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. } }); } } });
Sending Back an HTTP Response
You can of course send back an HTTP response for an incoming HTTP request. To do so you need to obtain the
HttpServerResponse
instance from the request object. This is how you obtain the HttpServerResponse
object:
HttpServerResponse response = request.response();
Once you have obtained a HttpServerResponse
instance you can set the HTTP response status code and
headers like this:
response.setStatusCode(200); response.headers() .add("Content-Length", String.valueOf(57)) .add("Content-Type", "text/html") ;
After writing the headers back you can write the response body back via the write()
method, like this:
response.write("Vert.x is alive!"); response.end();
You can call write()
multiple times to add more data to the response body. The write()
method also exists in a version that takes a Vert.x Buffer
instance as parameter. This method will
write the contents of the Buffer
to the HTTP response.
The write()
method is asynchronous and returns immediately after queuing up the string or buffer.
Once you have finished writing the HTTP response body you should end the HTTP response. This is done by calling
the end()
method as shown in the previous example. You can also write the HTTP response body and
end the response in a single method call, like this:
response.end("Vert.x is alive!");
The end()
method can take either a String
or Buffer
as parameter. The
parameter will be written to the response body, and the response ended after that.
Closing the HTTP Server
To close an HTTP server you simply call its close()
method like this:
httpServer.close();
The close()
method executes asynchronously, so the HTTP server may not be fully closed by the time
the close()
method returns. You can pass a close handler as parameter to the close()
method, to be notified when the HTTP server is fully closed.
Tweet | |
Jakob Jenkov |