Vert.x 4.4 REST 服务

209 阅读1分钟

写一个 WEB、JWT 搭配使用的示例,回忆下异步框架的写法,通透。

ApiVerticle.java

public class ApiVerticle extends AbstractVerticle {

  private final Logger logger = LoggerFactory.getLogger(ApiVerticle.class);

  @Override
  public void start(Promise<Void> startPromise) throws Exception {
    JsonObject config = config();
    Integer port = config.getInteger("port");
    String jwtKey = config.getString("jwtKey");
    String uploadDir = config.getString("uploadDir");

    JWTAuth jwtProvider = JWTAuth.create(vertx, new JWTAuthOptions()
      .addPubSecKey(new PubSecKeyOptions()
        .setAlgorithm("HS256")
        .setBuffer(jwtKey))
      .setJWTOptions(new JWTOptions().setExpiresInMinutes(120)));

    Router router = Router.router(vertx);
    router.route()
      .handler(BodyHandler.create().setUploadsDirectory(uploadDir))
      .failureHandler(ctx -> {
        // 统一处理错误
        int i = ctx.statusCode();
        if (i == 401) {
          fail(ctx, 401, "Unauthorized");
          return;
        }

        String path = ctx.request().path();
        Throwable failure = ctx.failure();
        logger.error("failureHandlerErr:path:" + path, failure);
        fail(ctx, "未知错误");
      });

    // 登录
    router.post("/api/login")
      .handler(ctx -> {
      // 参数是 json 格式
        JsonObject req = ctx.body().asJsonObject();
        logger.debug("login ...: " + req);
        String token = jwtProvider.generateToken(new JsonObject().put("uid", 1).put("name", "zhangsan"));
        ok(ctx, new JsonObject().put("token", token));
      });

    // 公开访问 API
    router.post("/api/query")
      .handler(ctx -> {
        JsonObject reqBody = ctx.body().asJsonObject();
        logger.debug("/api/query Body:" + reqBody);
        ok(ctx, reqBody);
      });

    // jwt 保护私有API
    router.route("/api/private/*").handler(JWTAuthHandler.create(jwtProvider));

    // 私有 API
    // form-data
    // 多个参数且携带文件,在乎文件参数名称是什么用这种
    router.post("/api/private/upload2")
      .handler(ctx -> {
        // token 里的内容
        JsonObject principal = ctx.user().principal();
        logger.debug("uid: " + principal.getInteger("uid") + ", name: " + principal.getString("name"));

        MultiMap params = ctx.request().params();
        String name = params.get("name");
        logger.debug("name:" + name);
        FileUpload fileUpload = ctx.fileUploads().get(0);
        logger.debug("fileParamName: " + fileUpload.name());
        logger.debug("fileName: " + fileUpload.fileName());
        logger.debug("fileName: " + fileUpload.uploadedFileName());
        ok(ctx, new JsonObject());
      });

    // 上传文件, 不在乎参数名称是什么的用这种
    router.post("/api/private/upload")
      .handler(ctx -> {
        List<FileUpload> fileUploads = ctx.fileUploads();
        FileUpload fileUpload = fileUploads.get(0);
        ok(ctx, new JsonObject().put("name", fileUpload.fileName())
          .put("upName", fileUpload.uploadedFileName()));
      });

    vertx.createHttpServer().requestHandler(router).listen(port, http -> {
      if (http.succeeded()) {
        logger.debug("http server Started port: " + port);
        startPromise.complete();
      } else {
        startPromise.fail(http.cause());
      }
    });
  }

  private void ok(RoutingContext ctx, JsonObject obj) {
    ctx.json(new JsonObject().put("code", 0).put("data", obj));
  }

  private void ok(RoutingContext ctx) {
    ctx.json(new JsonObject().put("code", 0).put("data", null));
  }

  private void fail(RoutingContext ctx, String msg) {
    fail(ctx, 1, msg);
  }

  private void fail(RoutingContext ctx, int code, String msg) {
    ctx.json(new JsonObject().put("code", code).put("msg", msg));
  }

  @Override
  public void stop() throws Exception {
    logger.debug("apiServiceStop");
    super.stop();
  }
}

如何运行看上一篇文章 Vert.x 动态切换数据源 - 掘金 (juejin.cn)