昨天看了下異步,而後就開始了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信息,結果以下: