我已经阅读了vertx.io上的几个教程,但我仍然无法理解如何最大限度地减少重复代码。
例如,我需要实现从DB获取数据的RESTful服务。我为表(Customer,Administrator)和已实现的服务类准备了2个bean类:
AdministratorService.java :
public void getAll(RoutingContext routingContext) {
jdbc.getConnection(ar -> {
SQLConnection connection = ar.result();
connection.query(Queries.SELECT_ALL_ADMINS, result -> {
List<Administrator> admins = result.result().getRows().stream().map(Administrator::new).collect(Collectors.toList());
routingContext.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(Json.encodePrettily(admins));
connection.close();
});
});
}
public void getOneById(RoutingContext routingContext) {
final String id = routingContext.request().getParam("id");
if (id == null) {
routingContext.response().setStatusCode(400).end();
} else {
jdbc.getConnection(ar -> {
// Read the request's content and create an instance of Administrator.
SQLConnection connection = ar.result();
select(id, connection, Queries.SELECT_ONE_ADMIN_BY_ID, result -> {
if (result.succeeded()) {
routingContext.response()
.setStatusCode(200)
.putHeader("content-type", "application/json; charset=utf-8")
.end(Json.encodePrettily(result.result()));
} else {
routingContext.response()
.setStatusCode(404).end();
}
connection.close();
});
});
}
}
CustomerService.java :
public void getAll(RoutingContext routingContext) {
jdbc.getConnection(ar -> {
SQLConnection connection = ar.result();
connection.query(Queries.SELECT_ALL_CUSTOMERS, result -> {
List<Customer> customers = result.result().getRows().stream().map(Customer::new).collect(Collectors.toList());
routingContext.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(Json.encodePrettily(customers));
connection.close();
});
});
}
public void getOneById(RoutingContext routingContext) {
final String id = routingContext.request().getParam("id");
if (id == null) {
routingContext.response().setStatusCode(400).end();
} else {
jdbc.getConnection(ar -> {
// Read the request's content and create an instance of Administrator.
SQLConnection connection = ar.result();
select(id, connection, Queries.SELECT_ONE_CUSTOMER_BY_ID, result -> {
if (result.succeeded()) {
routingContext.response()
.setStatusCode(200)
.putHeader("content-type", "application/json; charset=utf-8")
.end(Json.encodePrettily(result.result()));
} else {
routingContext.response()
.setStatusCode(404).end();
}
connection.close();
});
});
}
}
不难看出那部分
.routingContext.response()
.putHeader("content-type", "application/json; charset=utf-8")
每种方法都重复。一般来说,这些类之间的所有区别都是sql请求和bean类。
您可以分享您的示例或演示如何更改我的方法吗?
答案 0 :(得分:3)
VertX不是一个框架,这使得一些开发人员可以轻松地设计自己的结构,但对于某些人而言,它变成了噩梦。您正在寻找的是一个预先设计的框架,可以使用路由器,控制器和数据库连接。显然,不是vertx,它更像是一个库,可以按照你想要的方式扩展它。
我在您的代码中看到,对于每个Service函数,您都会获得SQL连接。如果您已经使用过Spring之类的其他框架,则可以使用DI进行连接。 您需要实现DI,一些MVC设计,然后您的样板代码将被删除。
我做了类似的事情,但对于MongoDB。
答案 1 :(得分:0)
/**
* deploy verticle
*/
@PostConstruct
public void deployVerticle() {
Vertx vertx = Vertx.vertx();
log.info("deply vertx start...... ");
vertx.deployVerticle(dbVerticle);
DeploymentOptions options = new DeploymentOptions();
options.setInstances(4);
StaticServer.setApplicationContext(context);
vertx.deployVerticle(StaticServer.class.getName(), options);
log.info("deply vertx end...... ");
}
@Override
public void start() throws Exception {
Map<String, Api> apis = applicationContext.getBeansOfType(Api.class);
JavaConfig javaConfig = applicationContext.getBean(JavaConfig.class);
Router router = Router.router(vertx);
apis.forEach((k, v) -> RouterUtils.injectRouter(v, router));
vertx.createHttpServer().requestHandler(router).listen(javaConfig.httpPort());
}
public static void injectRouter(Api api, Router router) {
Map<Method, RequestMapping> annotatedMethods = MethodIntrospector.selectMethods(api.getClass(), (MetadataLookup<RequestMapping>)
method -> AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class));
RequestMapping annotatedClass = api.getClass().getDeclaredAnnotation(RequestMapping.class);
annotatedMethods.forEach((method, request) -> {
Class<?>[] params = method.getParameterTypes();
Assert.isAssignable(RoutingContext.class, params[0]);
router.route(request.method(), annotatedClass.value() + request.path()).handler(context -> {
try {
context.response().putHeader("content-type", "application/json; charset=utf-8");
method.invoke(api, context);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
log.error("e :", e.getCause());
}
});
});
}
@RequestMapping("/")
public void root(RoutingContext context) {
JsonObject query = new JsonObject();
query.put("sql", "select * from user where username = ?");
query.put("params", (new JsonArray()).add("zhengfc"));
context.vertx().eventBus().request("db.query", query, ar -> {
if (ar.succeeded()) {
context.response().end(ar.result().body().toString());
} else {
log.error("db.query failed: {}", ar.cause());
}
});
}