Vert.x學習第一天

  昨天看了下異步,而後就開始了Vert.x相關知識的學習。html

  Vert.x是當下很是流行的一套全異步框架,其優點在於輕量級、高效。很是適合做爲移動端後臺或是企業應用。java

  固然對於第一天接觸這個框架的人(沒錯,正是在下)來講,Vert.x一些獨特的特性還不是如今瞭解的時候,對着說明文檔去碼一些demo纔是正道。web

  首先咱們先建一個gradle項目,而後在build.gradle中的dependencies中添加 compile 'io.vertx:vertx-core:3.5.0' (下載jar包),以後在build.gradle文件的最後添加 task copyJars(type: Copy) { from configurations.runtime into 'lib' } (下載到lib文件夾,這個文件夾本身在項目下新建一個)瀏覽器

若是使用的是idea的話,能夠雙擊咱們新添加的copyJar運行(以下圖),這樣jar包就下載好了,或者在cmd中進入到build.gradle所在文件夾中,使用語句 gradle copyJar 也能夠。服務器

 

  添加好jar包以後就能夠寫一個test類了。app

 1 import io.vertx.core.Vertx;
 2 import io.vertx.core.http.HttpServerResponse;
 3 import javafx.application.Application;
 4 import javafx.stage.Stage;
 5 
 6 public class test extends Application{
 7 
 8     @Override
 9     public void start(Stage primaryStage) throws Exception {
10         Vertx.vertx().createHttpServer().requestHandler(req -> {
11             HttpServerResponse response=req.response();
12             System.out.println("lodaing");
13             response.setChunked(true);
14             response.write("aaaa");
15             response.end();
16         }).listen(8889,"localhost");
17 
18     }
19 }

  這是一個最簡單服務器代碼,實現的做用是:每當有對localhost這個主機8889端口的請求,便會響應「aaaa」字符串。框架

  這個test類繼承了Application,而後實現了Application的start()方法。(Application繼承自AbstractVerticle,若是test類繼承AbstractVertical一樣能夠實現這個功能,可是要寫一個main方法調用start方法。AbstractVerticle和Application的區別我尚未具體的看,可是Application的start()方法是會自動調用的)異步

   Vertx.vertx() 返回一個Vertx對象,這個對象能夠使用 createHttpServer() 來建立一個服務器對象,我這裏用鏈式直接寫了,爲了方便理解,咱們能夠把這個服務器對象單獨拿出來 HttpServer server=Vertx.vertx().createHttpServer(); ide

  咱們能夠給這個服務器對象server添加一個監聽 server.listen(8889,"localhost") ,這兩個參數不寫的話,端口默認是80,主機地址默認是0.0.0.0。這樣,每當有對localhost的8889端口的請求,都會被這個服務器監聽到。post

  若是我想在監聽到一個請求以後,讓服務器作出一些響應,那麼咱們就應該使用 server.requestHandler() ,requestHandler()裏面有一個Handler對象,這裏使用lambda表達式來寫這個匿名內部類。總之,咱們傳入了一個HttpRequest類型的req進去,這個req就是被咱們監聽到的請求。 req.response() 建立了一個對當前請求的響應對象,經過這個響應對象,咱們使用write()方法能夠一個響應字符串。這裏要注意的是,使用write()方法以前必須指定要發送的信息的長度。或者用 response.setChunked(true); 來指定要發送的信息是分塊發送。指定分塊發送的信息不須要指定長度,可是須要在write()以後使用 response.end(); 來表示我要寫的信息已經結束啦,這樣服務器纔會把要響應的信息發送回去。還有一種返回字符串的方法能夠省略write(),就是直接在end()裏面添加字符串,可是隻能發送一次,再次response.end("sdasd");就會報錯。

  寫好了以上的代碼以後,咱們運行代碼,而後在瀏覽器中輸入地址「localhost:8889」就能夠看到響應的字符串出如今瀏覽器上了。由於咱們監聽的是8889端口全部的請求,因此「localhost:8889/asda/asdas/fasf」這樣的地址也會返回一樣的結果。

 

以上只是最最簡單的一個例子,上面的代碼並無去分析請求中的信息,只是獲得請求就響應了。下面寫一些從請求中獲得信息的方法:

req.version()  //獲得請求的版本信息,如HTTP1.1
req.method()  //獲得請求的方式,如GET、POST
req.path()  //獲得請求的地址,如「localhost:8080/user/hello.html?id=1&pwd=123」獲得的結果是 「/user/hello.html」部分
req.uri()   //獲得請求的數據部分,獲得的結果是「id=1&pwd=123」部分
req.absoluteURI()  //返回完整地址,「http://「localhost:8080/user/hello.html?id=1&pwd=123」

Vertx由於是異步的,在一個請求到達時,它會先接受請求頭部信息(head),不用等待body到來就能夠處理請求。因此上面的方法只能夠獲得請求頭的數據。若是想要讀取body中的信息(如post方式傳遞的數據),能夠用如下方法:

req.setExpectMultipart(true);  //告訴服務器,我要讀取body信息
req.endHandler(v->{
  MultiMap fa=req.formAttributes();//從req中讀取body全部信息並存儲到MultiMap對象中
   System.out.println(fa.entries().toString()); //entries()方法會返回一個list格式的數據,MultiMap類型的數據具體怎麼讀我還沒仔細研究
});

爲了驗證,我寫了一個web 表單,來驗證功能:(webroot/index2.html)

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 <form action="/user" method="post">
 9     <input type="text" name="name" id="name" value="hellooooo"/>
10     <input type="submit" name="submit" id="submit" value="submit"/>
11 </form>
12 </body>
13 </html>

(SAndC.Servert.java以下:)

 1 package SAndC;
 2 
 3 import io.vertx.core.MultiMap;
 4 import io.vertx.core.Vertx;
 5 import javafx.application.Application;
 6 import javafx.stage.Stage;
 7 
 8 public class Server extends Application{
 9 
10     @Override
11     public void start(Stage primaryStage) throws Exception {
12         Vertx.vertx().createHttpServer().requestHandler(req->{
13             if(!req.path().equals("/webroot/index2.html")){
14                 req.response().end("i get the message!\n"+req.version()+"\n"+req.method()+"\n"+req.path()+"\n");
15                 req.setExpectMultipart(true);
16                 req.endHandler(v->{
17                     MultiMap fa=req.formAttributes();
18                     System.out.println(fa.entries().toString());
19                     System.out.println(req.absoluteURI());
20                 });
21             }else{
22                 req.response().sendFile("webroot/index2.html");
23             }
24         }).listen(8080,"localhost",res->{
25             if(res.succeeded()){
26                 System.out.println("Server is now listening!");
27             }else{
28                 System.out.println("I wangt to listen but failed!");
29             }
30         });
31     }
32 }

  上面的功能是:接收到一個一個請求後,判斷請求路徑是否是/webroot/index2.html,若是是,就返回index2.html這個頁面,這樣咱們就能看到本身的表單了。

  而後,index2.html中表單的action我是隨便填的,反正都會被監聽到,這樣提交的數據就是post方式,請求的body中會包含name和submit的數據。

  點擊提交以後,判斷路徑不是/webroot/index2.html,因此讀取請求的body信息,結果以下:

                   

相關文章
相關標籤/搜索