Vert.x 3学习笔记---07

Writing HTTP servers and clients
上一章介绍了 tcp服务端和客户端,本章介绍怎么使用vertx创建无阻塞的http服务端和客户端。

Creating an HTTP Server

使用vertx可以很简单的创建一个http的服务端:

HttpServer server = vertx.createHttpServer();

Configuring an HTTP server

可以使用HttpServerOptions对象类配置http 服务端。

HttpServerOptions options = new HttpServerOptions().setMaxWebsocketFrameSize(1000000);
HttpServer server = vertx.createHttpServer(options);

Start the Server Listening

可以使用无参数的listen方法:

HttpServer server = vertx.createHttpServer();
server.listen();

也可以使用有参数的listen方法:

HttpServer server = vertx.createHttpServer();
server.listen(8080, "myhost.com");

默认的地址是0.0.0.0,意味着监听所有可用的一切地址。默认的端口是80.

监听完成后的动作,可以指定handler来响应。

HttpServer server = vertx.createHttpServer();
server.listen(8080, "myhost.com", res -> {
  if (res.succeeded()) {
    System.out.println("Server is now listening!");
  } else {
    System.out.println("Failed to bind!");
  }
});

Getting notified of incoming requests

获取一个进来的请求通知。

HttpServer server = vertx.createHttpServer();
server.requestHandler(request -> {
  // Handle the request in here
});

Handling requests

当一个请求到达时,request handler会被调用,并传入一个httprequest参数。
The handler is called when the headers of the request have been fully read.
If the request contains a body, that body will arrive at the server some time after the request handler has been called.
当request的header全部读取完毕后,就会调用request handler。
如果一个request包含一个比较大的body时,这个body有可能会在调用request handler后才完整的读入到server中。
通过request对象,你可以获取到uri, path, params and headers等。
每一次request都有一个绑定的response对象,可以通过response()方法获取到。

vertx.createHttpServer().requestHandler(request -> {
  request.response().end("Hello world");//获取response对象,并返回hello world字符串
}).listen(8080);

Request version

通过version方法获取。

Request method

通过method方法获取(GET, POST, PUT, DELETE, HEAD, OPTIONS, etc)。

Request URI

Use uri to retrieve the URI of the request.
Note that this is the actual URI as passed in the HTTP request, and it’s almost always a relative URI.
获取相对的URI地址。

Request path

Use path to return the path part of the URI

For example, if the request URI was:
a/b/c/page.html?param1=abc&param2=xyz

Then the path would be
/a/b/c/page.html

Request query

Use query to return the query part of the URI
使用query方法获取请求的uri参数部分
For example, if the request URI was:
a/b/c/page.html?param1=abc&param2=xyz

Then the query would be
param1=abc&param2=xyz

Request headers

使用headers方法获取请求的头部。其将会返回MultiMap的实例。

MultiMap headers = request.headers();

// Get the User-Agent:
System.out.println("User agent is " + headers.get("user-agent"));

// You can also do this and get the same result:
System.out.println("User agent is " + headers.get("User-Agent"));

Request parameters

使用params来获取请求的参数。和headers类似,返回的是MultiMap的实例。
For example if the URI was:
/page.html?param1=abc&param2=xyz

Then the parameters would contain the following:
param1: ‘abc’
param2: ‘xyz

注意:当提交一个multi-part/form-data的form表单时,这种方法是不能获取到参数的。

Remote address

请求的地址可以使用remoteAddress方法获取。

Absolute URI

使用absoluteURI获取绝对地址。

End handler

当整个请求内容(包含body)读取完毕后,会调用endHandler方法。

Reading Data from the Request Body

一般情况下,一个请求都会带有一个body。如前文说讲,request handler可能在body还没有被读取完成之前就被调用。这是因为一个body可能会很大,因此我们在将body交给你之前不会将整个body放到缓冲区中,这样做的话有可能导致内存用尽。
为了接收body,我们可以使用handler方法。body的一个块(a chunk)到达时就会调用这个方法。

request.handler(buffer -> {
  System.out.println("I have received a chunk of the body of length " + buffer.length());
});

此方法会被调用几次,这取决于你的body的大小。
如果你的body不是很大,那么你可以使用下面的代码:

Buffer totalBuffer = Buffer.buffer();

request.handler(buffer -> {
  System.out.println("I have received a chunk of the body of length " + buffer.length());
  totalBuffer.appendBuffer(buffer);
});

request.endHandler(v -> {
  System.out.println("Full body received, length = " + totalBuffer.length());
});

这是一个很普遍的现象。因此,vertx提供了bodyHandler方法,用来达到上面代码的功能。当body读取完成后,就会调用bodyHandler。

Pumping(泵) requests

The request object is a ReadStream so you can pump the request body to any WriteStream instance。
request对象是一个ReadStream (读流),因此可以将request body泵入到任何WriteStream (写流)中。

Handling HTML forms

提交的form的type可以是 application/x-www-form-urlencoded 或者multipart/form-data中的一个。

For url encoded forms, the form attributes are encoded in the url, just like normal query parameters.
对于application/x-www-form-urlencoded这种类型的form表单,form数据将会编码到url中,就像一个普通的查询参数一样。

For multi-part forms they are encoded in the request body, and as such are not available until the entire body has been read from the wire.
Multi-part forms can also contain file uploads.
对于multipart/form-data类型的form表单,form数据会被编码到request body中,并且在整个body没有读完之前是不可用的。
这种类型的表单也包含文件的上传。

If you want to retrieve the attributes of a multi-part form you should tell Vert.x that you expect to receive such a form before any of the body is read by calling setExpectMultipart with true, and then you should retrieve the actual attributes using formAttributes once the entire body has been read:
为了获取 multi-part类型的form数据,你需要,在接收body的任何数据之前通过调用setExpectMultipart 方法(参数为true),告诉vertx,你期望接收这样一个form。当整个body读取完成后,可以使用formAttributes 方法来回去actual attributes。如下代码:

server.requestHandler(request -> {
  request.setExpectMultipart(true);
  request.endHandler(v -> {
    // The body has now been fully read, so retrieve the form attributes
    MultiMap formAttributes = request.formAttributes();
  });
});

Handling form file uploads

为了接收上传的文件,需要设置form type为multi-part 和 设置一个 uploadHandler (request 上)。每次上传到达时,都会调用uploadHandler (参数为HttpServerFileUpload的实例)。

server.requestHandler(request -> {
  request.setExpectMultipart(true);
  request.uploadHandler(upload -> {
    System.out.println("Got a file upload " + upload.name());
  });
});

vertx没有提供完整的buffer包含整个上传内容。相反的,上传的内容只是分段的接收:

request.uploadHandler(upload -> {
  upload.handler(chunk -> {
    System.out.println("Received a chunk of the upload of length " + chunk.length());
  });
});

request对象是一个ReadStream (读流),因此可以将request body泵入到任何WriteStream (写流)中。

如果你想将上传文件写入到磁盘上,你可以调用streamToFileSystem方法:

request.uploadHandler
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值