vert.x笔记:3.使用vert.x发布restful接口

vert.x重要概念介绍:

在第2偏笔记中,我们写了第一个vert.x的hello world代码,这里,我们把代码中用到的几个重要概念解释下。

Vertx基类:

Vertx类,是所有vert.x代码的入口,官方代码注释为:

The entry point into the Vert.x Core API.

即该类是所有vert.x core包API的总入口,简单理解就是,所有核心功能的API,都需要该类去调用,所有的核心功能也都需要该类提供环境上下文。

HttpServer:

官方注释:

An HTTP and WebSockets server

http/https/websockets服务器,vert.x发布restful服务,不需要tomcat提供servlet容器,它自己就是一台性能强大的web服务器,并且原生支持负载均衡,后面我们会讲到。

Router类:

先看官方代码注释:

A router receives request from an HttpServer and routes it to the first matching Route that it contains. A router can contain many routes.

Router类可以理解为一个路由器,他接收httpserver带来的请求,并将不同的请求分发到不同的路由中,如果简单对比一下spring mvc的话,可以将router理解为spring mvc中的dispatcher。

route:

route代表一条路由,同样,对比spring mvc,相当于spring中的@RequestMapping,他指定了restful api的请求接口路径,并将其交给handler来处理该条路由。

Handler:

首先来看官方代码注释:

Specify a request handler for the route. The router routes requests to handlers depending on whether the various criteria such as method, path, etc match. There can be only one request handler for a route. If you set this more than once it will overwrite the previous handler.

handler处理具体的路由请求,字面上讲就是处理某个具体的restful api。他与httpserver,router,route的关系可以用如下流程表示:

来自httpserver的request请求-->交由路由器做分发处理-->路由器匹配到具体的路由规则-->路由到最终的handler去处理请求

vert.x默认提供了很多处理器,包括但不局限于以下:

AuthHandler 处理权限校验支持
BodyHandler 提供所有请求上下文
CookieHandler 提供cookie支持
SessionHandler 提供session支持

RoutingContext:

官方代码注释:

Represents the context for the handling of a request in Vert.x-Web.

很简单,请求上下文,可以理解为servlet中的httprequest和httpresponse
####Verticle:

A verticle is a piece of code that can be deployed by Vert.x.

verticle是vert.x中,可被部署运行的最小代码块,可以理解为一个verticle就是一个最小化的业务处理引擎。
verticle被发布部署后,会调用其内部的start方法,开始业务逻辑处理,完成后会调用stop方法,对该代码块执行销毁动作

vert.x发布restufl api

新建类:RestServer,代码如下

package com.heartlifes.vertx.demo.simple;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;

public class RestServer extends AbstractVerticle {

    public static void main(String[] args) {
        // 获取vertx基类
        Vertx vertx = Vertx.vertx();
        // 部署发布rest服务
        vertx.deployVerticle(new RestServer());
    }

    // 重写start方法,加入我们的rest服务处理逻辑
    @Override
    public void start() throws Exception {
        // 实例化一个路由器出来,用来路由不同的rest接口
        Router router = Router.router(vertx);
        // 增加一个处理器,将请求的上下文信息,放到RoutingContext中
        router.route().handler(BodyHandler.create());
        // 处理一个post方法的rest接口
        router.post("/post/:param1/:param2").handler(this::handlePost);
        // 处理一个get方法的rest接口
        router.get("/get/:param1/:param2").handler(this::handleGet);
        // 创建一个httpserver,监听8080端口,并交由路由器分发处理用户请求
        vertx.createHttpServer().requestHandler(router::accept).listen(8080);
    }

    // 处理post请求的handler
    private void handlePost(RoutingContext context) {
        // 从上下文获取请求参数,类似于从httprequest中获取parameter一样
        String param1 = context.request().getParam("param1");
        String param2 = context.request().getParam("param2");

        if (isBlank(param1) || isBlank(param2)) {
            // 如果参数空,交由httpserver提供默认的400错误界面
            context.response().setStatusCode(400).end();
        }

        JsonObject obj = new JsonObject();
        obj.put("method", "post").put("param1", param1).put("param2", param2);

        // 申明response类型为json格式,结束response并且输出json字符串
        context.response().putHeader("content-type", "application/json")
                .end(obj.encodePrettily());
    }

    // 逻辑同post方法
    private void handleGet(RoutingContext context) {
        String param1 = context.request().getParam("param1");
        String param2 = context.request().getParam("param2");

        if (isBlank(param1) || isBlank(param2)) {
            context.response().setStatusCode(400).end();
        }
        JsonObject obj = new JsonObject();
        obj.put("method", "get").put("param1", param1).put("param2", param2);

        context.response().putHeader("content-type", "application/json")
                .end(obj.encodePrettily());
    }

    private boolean isBlank(String str) {
        if (str == null || "".equals(str))
            return true;
        return false;
    }

}

执行代码,打开浏览器,输入以下接口

http://localhost:8080/get/1/2
http://localhost:8080/post/1/2

处理session代码示例:

package com.heartlifes.vertx.demo.simple;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.Session;
import io.vertx.ext.web.handler.CookieHandler;
import io.vertx.ext.web.handler.SessionHandler;
import io.vertx.ext.web.sstore.LocalSessionStore;

public class SessionServer extends AbstractVerticle {

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(new SessionServer());
    }

    @Override
    public void start() throws Exception {
        Router router = Router.router(vertx);
        // 增加cookies处理器,解码cookies,并将其放到context上下文中
        router.route().handler(CookieHandler.create());
        // 增加session处理器,为每次用户请求,维护一个唯一的session,这里使用内存session,后面会讲分布式的session存储
        router.route().handler(
                SessionHandler.create(LocalSessionStore.create(vertx)));
        router.route().handler(routingContext -> {
            // 从请求上下文获取session
                Session session = routingContext.session();
                Integer count = session.get("count");
                if (count == null)
                    count = 0;
                count++;
                session.put("count", count);

                routingContext.response()
                        .putHeader("content-type", "text/html")
                        .end("total visit count:" + session.get("count"));
            });

        vertx.createHttpServer().requestHandler(router::accept).listen(8080);
    }

}

处理cookies代码示例:

package com.heartlifes.vertx.demo.simple;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.ext.web.Cookie;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.CookieHandler;

public class CookieServer extends AbstractVerticle {

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(new CookieServer());
    }

    @Override
    public void start() throws Exception {
        Router router = Router.router(vertx);
        router.route().handler(CookieHandler.create());
        router.route().handler(
                routingContext -> {
                    Cookie cookie = routingContext.getCookie("testCookie");
                    Integer c = 0;
                    if (cookie != null) {
                        String count = cookie.getValue();
                        try {
                            c = Integer.valueOf(count);
                        } catch (Exception e) {
                            c = 0;
                        }
                        c++;
                    }

                    routingContext.addCookie(Cookie.cookie("testCookie",
                            String.valueOf(c)));
                    routingContext.response()
                            .putHeader("content-type", "text/html")
                            .end("total visit count:" + c);
                });

        vertx.createHttpServer().requestHandler(router::accept).listen(8080);
    }

}

Leave a Reply

Your email address will not be published. Required fields are marked *