• Vert.x学习第一天


      昨天看了下异步,然后就开始了Vert.x相关知识的学习。

      Vert.x是当下非常流行的一套全异步框架,其优势在于轻量级、高效。非常适合作为移动端后台或是企业应用。

      当然对于第一天接触这个框架的人(没错,正是在下)来说,Vert.x一些独特的特性还不是现在了解的时候,对着说明文档去码一些demo才是正道。

      首先我们先建一个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类了。

     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(); 

      我们可以给这个服务器对象server添加一个监听 server.listen(8889,"localhost") ,这两个参数不写的话,端口默认是80,主机地址默认是0.0.0.0。这样,每当有对localhost的8889端口的请求,都会被这个服务器监听到。

      如果我想在监听到一个请求之后,让服务器做出一些响应,那么我们就应该使用 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!
    "+req.version()+"
    "+req.method()+"
    "+req.path()+"
    ");
    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信息,结果如下:

                       

  • 相关阅读:
    项目中用到的ext及js细节
    《软件调试艺术》读后感六
    同步数据
    数组首地址取地址
    Storm简述及集群安装
    html5之canvas画图 1.写字板功能
    Memcached安装与配置
    WIP完工入库及完工退回的几个重要问题
    赵雅智:service_bindService生命周期
    【Android开发经验】Cannot generate texture from bitmap异常的解决方式
  • 原文地址:https://www.cnblogs.com/liumaowu/p/9300934.html
Copyright © 2020-2023  润新知