`
m635674608
  • 浏览: 5021891 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Vert.x 实现REST

 
阅读更多

开始Vert.x Web

 

如果你看了前面的文章,使用Vert.x Core来处理复杂的HTTP应用还是很麻烦的,所以就有了Vert.x Web,它可以使Vert.x开发一个web应用更加简单,而且不会改变Vert.x的思想。

 

更新pom.xml文件,添加下面的依赖:

 

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-web</artifactId>
  <version>3.0.0</version>
</dependency>

 

这就是使用Vert.x Web的唯一前提。

 

还记得在上一篇文章中,当请求http://localhost:8080时,返回一个Hello World消息,使用Vert.x Web完成同样的事情,打开name.quanke.study.vertx.first.MyFirstVerticle.java 类,修改start方法:

 

@Override
public void start(Future<Void> fut) {
 // Create a router object.
 Router router = Router.router(vertx);

 // Bind "/" to our hello message - so we are still compatible.
 router.route("/").handler(routingContext -> {
   HttpServerResponse response = routingContext.response();
   response
       .putHeader("content-type", "text/html")
       .end("<h1>Hello from my first Vert.x 3 application</h1>");
 });

 // Create the HTTP server and pass the "accept" method to the request handler.
 vertx
     .createHttpServer()
     .requestHandler(router::accept)
     .listen(
         // Retrieve the port from the configuration,
         // default to 8080.
         config().getInteger("http.port", 8080),
         result -> {
           if (result.succeeded()) {
             fut.complete();
           } else {
             fut.fail(result.cause());
           }
         }
     );
}

 

在开始start方法里创建了一个Router对象。router是Vert.x Web的基础,负责分发HTTP请求到handler(处理器),在Vert.x Web中还有两个很重要的概念。

 

  • Routes-定义请求的分发
  • Handlers-这是实际处理请求并且返回结果的地方。Handlers可以被链接起来使用。

 

如果明白了这3个概念(Router、Routes、Handlers),就明白了Vert.x Web的所有了。

 

仔细看看下面这段代码:

 

router.route("/").handler(routingContext -> {
  HttpServerResponse response = routingContext.response();
  response
      .putHeader("content-type", "text/html")
      .end("<h1>Hello from my first Vert.x 3 application</h1>");
});

 

将访问"/"(http://localhost:8080/)的请求“路由”到指定的handler。Handlers接收RoutingContext对象。这个handler的方法和我们之前的代码很像,他们操作的是同一个HttpServerResponse类型的对象。

 

让我们来看看剩下的代码:

 

vertx
    .createHttpServer()
    .requestHandler(router::accept)
    .listen(
        // Retrieve the port from the configuration,
        // default to 8080.
        config().getInteger("http.port", 8080),
        result -> {
          if (result.succeeded()) {
            fut.complete();
          } else {
            fut.fail(result.cause());
          }
        }
    );
}

 

除了改变了request handler,基本和之前的代码一样。传router::accept给handler。你可能对这个符号不太熟悉。它表示引用一个方法(这里是引用routeraccept方法)。换句话说,当接收到一个请求的时候,告诉vert.x从router里调用accept方法。

 

让我们来看下它是怎么工作的:

 

mvn clean package
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

 

浏览器打开http://localhost:8080,你会看到Hello的消息。

 

发布静态资源

 

现在有了第一个使用Vert.x Web开发的应用。先在写增加一个index.html页面(静态资源)。

 

这个HTML页面将会是我们应用的入口。在src/main/resources/assets目录下,index.html文件在github上。此文不涉及这个文件的细节。

 

基本上,就是一个简单的CRUD的UI界面,actions是由通过AJAX调用的REST API执行的。

 

创建完了页面后,编辑name.quanke.study.vertx.first.MyFirstVerticle类,并修改start方法:

 

@Override
public void start(Future<Void> fut) {
 Router router = Router.router(vertx);
 router.route("/").handler(routingContext -> {
   HttpServerResponse response = routingContext.response();
   response
       .putHeader("content-type", "text/html")
       .end("<h1>Hello from my first Vert.x 3 application</h1>");
 });

 // Serve static resources from the /assets directory
 // 将访问“/assets/*”的请求route到“assets”目录下的资源

 router.route("/assets/*").handler(StaticHandler.create("assets"));

 vertx
     .createHttpServer()
     .requestHandler(router::accept)
     .listen(
         // Retrieve the port from the configuration,
         // default to 8080.
         config().getInteger("http.port", 8080),
         result -> {
           if (result.succeeded()) {
             fut.complete();
           } else {
             fut.fail(result.cause());
           }
         }
     );
}

 

就这段代码和前面的不同:

 

router.route("/assets/*").handler(StaticHandler.create("assets"));

 

这一行是什么意思?挺简单的。将访问“/assets/*”的请求route到“assets”目录下的资源。现在可以通过http://localhost:8080/assets/index.html来访问index.html了。

 

测试之前,我们花一些时间来看一下handler的创建。所有的处理请求动作在Vert.x Web里都实现成handler。而创建一个handler需要调用create方法。

 

编译、运行:

 

mvn clean package
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

 

浏览器,输入http://localhost:8080/assets/index.html

 

现在这个table是空的。那是因为我们还没有实现REST的API。现在让我们来开始吧。

 

使用Vert.x Web实现REST API

 

Vert.x Web实现REST API很简单。看下面:

 

  • GET /api/whiskies => 获取所有的威士忌(getAll)
  • GET /api/whiskies/:id => 获取指定id的威士忌(getOne)
  • POST /api/whiskies =>添加一瓶威士忌(addOne)
  • PUT /api/whiskies/:id => 编辑一瓶威士忌(updateOne)
  • DELETE /api/whiskies/id => 删除一瓶威士忌(deleteOne)

 

我们需要一些数据。。。

 

在实现REST API之前,需要创建Whisky的数据模型。使用下面的内容创建src/main/java/quanke/name/study/vertx/first/Whisky.java

 

package name.quanke.study.vertx.first;

import java.util.concurrent.atomic.AtomicInteger;

public class Whisky {

  private static final AtomicInteger COUNTER = new AtomicInteger();

  private final int id;

  private String name;

  private String origin;

  public Whisky(String name, String origin) {
    this.id = COUNTER.getAndIncrement();
    this.name = name;
    this.origin = origin;
  }

  public Whisky() {
    this.id = COUNTER.getAndIncrement();
  }

  public String getName() {
    return name;
  }

  public String getOrigin() {
    return origin;
  }

  public int getId() {
    return id;
  }

  public void setName(String name) {
    this.name = name;
  }

  public void setOrigin(String origin) {
    this.origin = origin;
  }
}

 

这是一个很简单的bean类。因为Vert.x依赖Jackson来处理JSON格式,Jackson能够自动序列化和反序列化bean类,让代码变得更简单,所以选择这样的格式。

 

现在,创建几瓶威士忌。在MyFirstVerticle类中,添加下面的代码:

 

// Store our product
// 存储产品
private Map<Integer, Whisky> products = new LinkedHashMap<>();
// Create some product
// 创建一些产品
private void createSomeData() {
  Whisky bowmore = new Whisky("Bowmore 15 Years Laimrig", "Scotland, Islay");
  products.put(bowmore.getId(), bowmore);
  Whisky talisker = new Whisky("Talisker 57° North", "Scotland, Island");
  products.put(talisker.getId(), talisker);
}

 

然后,在start方法里,调用createSomeData方法:

 

@Override
public void start(Future<Void> fut) {

  createSomeData();

  // Create a router object.
  Router router = Router.router(vertx);

  // Rest of the method
}

 

在这里并没有一个后台数据库。仅使用一个map,将数据存储在内存中。添加后端数据库的介绍我准备放在另一篇文章中讲。

 

获得产品(威士忌)

 

GET /api/whiskies,JSON数组中返回产品列表。

 

start方法里,添加下面这行(static handler):

 

router.get("/api/whiskies").handler(this::getAll);

 

告诉router调用getAll方法来处理"/api/whiskies"的GET请求。代码可以写在handler里,但是为了让代码更加清晰,另外创建一个方法:

 

private void getAll(RoutingContext routingContext) {
  routingContext.response()
      .putHeader("content-type", "application/json; charset=utf-8")
      .end(Json.encodePrettily(products.values()));
}

 

每一个handler(比如:请看上面的代码)都会接受一个RoutingContext参数。通过设置content-type和一些内容来填充response。因为内容可能会碰到特殊的字符,所以强制使用UTF-8的格式。创建内容的时候,并不需要自己去处理JSON格式的字符串。Vert.x有处理Json的API。使用Json.encodePrettily(products.values())处理JSON字符串。本应使用Json.encodePrettily(products),但是为了让JavaScript代码更简单,我们仅返回威士忌(产品)的数据集合,并没有返回包含Id=>Bottle的键值对。

 

打包运行:

 

mvn clean package
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

 

浏览器访问http://localhost:8080/assets/index.html,然后你将会看到下面这个页面。

 


image

 

很好奇,想看一下REST API到底返回了什么。打开浏览器,访问http://localhost:8080/api/whiskies。你会看到下面这样的信息:

 

[ {
  "id" : 0,
  "name" : "Bowmore 15 Years Laimrig",
  "origin" : "Scotland, Islay"
}, {
  "id" : 1,
  "name" : "Talisker 57° North",
  "origin" : "Scotland, Island"
} ]

 

创建一个产品

 

能获取到威士忌(产品)了,现在需要创建一个产品。不像之前的REST API,这一次,需要读取requestbody。因为性能的原因,它应该被显式地启用。不要怕,这也仅仅是一个handler而已。

 

start方法中,添加下面的内容到getAll的后面:

 

router.route("/api/whiskies*").handler(BodyHandler.create());
router.post("/api/whiskies").handler(this::addOne);

 

第一行允许"/api/whiskies"下的所有route读取请求的body。通过使用router.route().handler(BodyHandler.create()),能让它在全局生效。

 

第二行将对/api/whiskies的POST请求映射到addOne方法。让我们来创建这个方法:

 

private void addOne(RoutingContext routingContext) {
  final Whisky whisky = Json.decodeValue(routingContext.getBodyAsString(),
      Whisky.class);
  products.put(whisky.getId(), whisky);
  routingContext.response()
      .setStatusCode(201)
      .putHeader("content-type", "application/json; charset=utf-8")
      .end(Json.encodePrettily(whisky));
}

 

开始从请求的body中取出Whisky对象。只是将body读成一个字符串并将它传入到Json.decodeValue方法里。Whisky这个对象一旦创建好,将被添加到后台的map中,并以JSON的格式返回。

 

重新编译并且运行:

 

mvn clean package
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

 

刷新HTML页面,点击Add a new bottle按钮。输入数据,如:“quanke” 作为名字, “quanke.name” 作为产地 ,就OK了。

 

状态码 201 ?
CREATED和在REST API中创建一个entity时,response的状态码为201。。默认的vert.x web设置一个200的状态码代表OK。

 

删除一个产品

 

start方法里,添加:

 

router.delete("/api/whiskies/:id").handler(this::deleteOne);

 

URL里,参数为::id。在处理一个相匹配的请求的时候,Vert.x提取路径中与这个参数对应的一段,能够在handler中获得。例如,/api/whiskies/0id映射为0

 

看一下在handler方法中这个参数是怎样被使用的。创建一个deleteOne方法。

 

private void deleteOne(RoutingContext routingContext) {
  String id = routingContext.request().getParam("id");
  if (id == null) {
    routingContext.response().setStatusCode(400).end();
  } else {
    Integer idAsInteger = Integer.valueOf(id);
    products.remove(idAsInteger);
  }
  routingContext.response().setStatusCode(204).end();
}

 

状态码 204 ?
状态码为204 - NO CONTENT。HTTP delete动作通常都是无返回内容的。

 

其他方法

 

实现getOne和updateOne很简单,和上面的差不多,此文不再详细介绍。源码在github

 

总结

 

此文介绍了如何用Vert.x web轻松的实现一个REST API,如何访问静态资源。比以前的文章复杂些,但仍然还是很简单。



 

原文链接:http://www.jianshu.com/p/e25234203602

分享到:
评论

相关推荐

    starter_flutter_vertx_

    在`starter`项目中,你可能会找到一个或多个Verticle(Vert.x的核心单元,负责执行特定任务)的实现,这些Verticle可能实现了RESTful API接口,用于与Flutter前端进行通信。此外,Vert.x还提供了一套工具,如Event ...

    vertx-mod-rest-service:Vert.x REST-API 服务示例

    Vert.x JAX-RS 示例模块 当您启动模块时,它接受端口 8080 上的 HTTP 连接。 返回响应字符串“Hello World” 如果您尝试访问 包括 vertx-mod-jersey 和 vertx-mod-hk2。 h4. 构建和运行 ./gradlew clean build ./...

    foodrater:用vert.x3用Java编写的Rest API

    总的来说,"foodrater"项目是一个利用Vert.x 3框架和Java语言构建的REST API服务,用于处理食品相关的评价数据。通过深入研究源代码,可以学习到如何使用Vert.x构建高性能的微服务,以及如何设计和实现RESTful API。

    xjc-1.0.2.zip

    6. **vert.x-run-jersey**:这是一个模块,将Jersey的REST处理能力引入Vert.x生态系统。通过这个模块,开发者可以在Vert.x事件循环中运行Jersey资源,从而利用Vert.x的高并发性和非阻塞I/O特性。 7. **事件驱动编程...

    vertx-mod-jersey-2.4.0-final.zip

    这个模块将 Jersey 的功能整合到 Vert.x 中,使开发者可以方便地在 Vert.x 应用中创建和消费 REST API。 【描述】"liquibase-slf4j.zip" 提供的是 Liquibase SLF4J Logger,Liquibase 是一个数据库版本控制工具,...

    Apache ServiceComb Java Chassis 给开发者提供一个快速构建微服务的JAVA SDK.rar

    Java Chassis 网络层基于 Vert.x 实现, 支持开发者使用响应式编程, 开发者在使用熟悉的REST风格设计业务接口的时候,也能够获取到非常高性能的吞吐量。同时还提供了Highway协议,满足更高性能场景的要求。 原生支持...

    vertx-restclient

    7. **集成测试**:由于vertx-restclient是基于Vert.x构建的,因此它可以轻松地与Vert.x Testkit结合使用,进行单元测试和集成测试,确保REST客户端的正确性和性能。 8. **版本兼容性**:vertx-restclient通常会与...

    example-proj

    该应用程序是一个简单的、有点做作的 Web 应用程序,它在客户端使用 Vert.x 事件总线来接收股票价格更新,并允许用户使用简单的 REST API 下订单。 在服务器端收到订单时,它们会被持久化到 MongoDB 实例中。 我们...

    REST框架简单实现

    REST(Representational State Transfer,表述性状态转移)是一种软件架构风格,主要应用于Web服务的...然而,对于大型复杂的应用,更推荐使用Spring Boot或Vert.x等成熟的REST框架,它们提供了更多的功能和便利性。

    socialauth-4.6.zip

    开发者现在更倾向于使用基于HTTP/HTTPS的API接口,例如通过构建自定义的REST服务来实现Vert.x与Socialauth之间的通信。这种方式不仅简化了集成过程,降低了系统复杂性,而且更易于测试和调试,同时也能够充分利用...

    zipkin-mysql-0.0.4.zip

    【描述】"gateleen.zip" 提到了一个名为Gateleen的中间件库,它是基于Vert.x构建的,用于创建高级JSON/REST通信服务器。Vert.x是一个Java平台上事件驱动的应用程序框架,它设计用于构建反应式、非阻塞I/O的应用,...

    1.微服务架构1

    服务网关作为系统的入口点,对外提供统一的REST API接口,实现了服务路由、负载均衡等功能。此外,服务网关还常常负责身份验证、授权、限流、监控等职责,以保护内部微服务的稳定性和安全性。 Java语言在微服务领域...

    todo:Grails + angularjs

    在这个“Todo”应用中,开发者可能会展示Grails如何创建REST API,AngularJS如何消费这些API并呈现用户界面,以及Vert.x如何协助处理后台任务或提供实时推送功能。 综上所述,这个项目的核心知识点包括: 1. ...

    ServiceComb Java Chassis微服务SDK-其他

    软件特点:高性能Java Chassis 网络层基于 Vert.x 实现, 支持开发者使用响应式编程, 开发者在使用熟悉的REST风格设计业务接口的时候,也能够获取到非常高性能的吞吐量。同时还提供了Highway协议,满足更高性能场景的...

    spring-async-rest-example

    异步休息示例这是spring boot / vert.x / quarkus / helidon中带有rxjava和kotlin的异步rest端点的示例全文:结果刺槐locust --host=http://localhost:8080当前实现的后端顶点夸克直升机停机坪弹簧靴去做微型船野蝇...

    云服务架构的演进过程.pdf

    首先,数据收集部分采用了REST+Kafka的方式,其中DataTransform部分负责数据标准化、过滤、流控等功能,这是通过vert.x实现的。这表明了云服务中对于数据处理的重视,以及对于实时性和批量处理的不同需求。 计算...

    最好的8个Java RESTful框架

    - Vert.x是一个事件驱动的、非阻塞的Java应用平台,适合构建高性能的分布式系统,包括REST服务。 - 它允许开发者编写异步代码,利用多核CPU,提高系统吞吐量。 - Vert.x提供了多种语言支持,并且可以与许多流行的...

    百亿流量的API网关设计-.pptx.pdf

    同时,采用Vert.x构建业务网关,以支持异步非阻塞I/O,提高响应速度和处理效率。 综上所述,设计和实现一个能够处理百亿流量的API网关需要全面考虑流量控制、安全防护、服务质量和系统扩展性。选择合适的开源框架,...

    quarkus:Quarkus示例列表

    10. **反应式编程**:Quarkus支持Reactor或Vert.x等反应式编程模型,用于构建高并发、非阻塞的应用。 以上只是可能包含的一些示例,实际的“quarkus-main”压缩包中可能有更多的内容,覆盖了更广泛的Quarkus特性和...

    你好服务

    Java中有多种服务框架,如Spring Boot、Dropwizard、Vert.x等,它们简化了Java应用程序的开发和部署。特别是Spring Boot,它基于Spring框架,提供了快速构建独立运行的、生产级别的基于Java的应用程序能力。Spring ...

Global site tag (gtag.js) - Google Analytics