写一个 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)