包结构长这个样子:


server包:(服务器相关配置)

  HttpServer:用ver.x创建了一个http服务器,把接收到的req请求传入RPCRequest中;

  RPCRequest:解析请求body内容,把信息保存为M(类名) A(方法名) P(参数),同时还拥有invoke()方法,根据m、a、p的数据用反射调用方法。

  RPCResponse:没写,用来保存响应信息的。

Manager包:(将所有需要被远程调用的方法保存到内容中,加快调用时遍历查询方法的响应速度)

  MethodManager:里面声明一个HashMap,value是KFunction<*>保存所有被@RPC1注解的方法,同时有addAllMethod()方法,用来保存当前类所有带@RPC1注解的方法。

  ControllerManager:用HashMap保存所有Controller类,value是KClass<*>,init中需要手动put添加controller类。

Service包:(提供业务方法,供调用)

  LoginService:提供业务解决逻辑的方法

Mongo包:(数据持久层,与数据库打交道,应该写成Dao层的)

  UserDao:用户集合的数据库操作。

(2017.7.27更新)

Log包:

  Loggin:封装了日志的信息

controller包:

  LoginController:请求响应被调用的方法


2018.7.27更新:

  原来的版本有几个缺陷:

    ①没有使用vert.x的mongo,而使用了原生mongo的jdbc;

    ②对数据库的查询没有实现异步。

  ①刚开始使用了原生mongodb的jar包和mongoclient对象,但是这种方式没有用到vertx的异步,所以改为 io.vertx.ext.mongo.MongoClient 这个jar包。但是没有删除原来原生的mongodb包,就造成了一个bug。会在执行 val mongoClient = MongoClient.createNonShared(Main.vertx, config) 这条语句的时候报错:clusterListener can not be null。 删除原生mongodb的jar包就可以了。

  ②改成了vertx的mongo方式就是为了查询数据库的时候使用异步来提高查询效率。刚开始还是不理解kotlin中的异步写法。

  异步就是当前程序正在执行,使用回调执行了另外一段代码,如果当前程序执行完了,就会结束,不会得到另一端代码的结果,如:

 /*
* 查找指定用户名和密码的用户
* */
fun findUser(userName:String,pwd:String):String?{
val query=JsonObject().put("name",userName).put("pwd",pwd)
var user?=null
mongoClient.find("jtest",query,{res->
if (res.succeeded()){
val result=res.result()[]
if (!result.isEmpty){
user=User(result.getString("name"),result.getString("pwd"))
}
}
})
return user
}

上面的写法是错误的,因为vertx的mongo的find()方法使用了异步写法,在异步的方法块里面对外面的变量赋值,外面是接收不到的。

正确的写法应该是回调来接收结果。java中想要使用回调onDone需要写一个接口如Active,然后把这个接口作为参数传入方法,重写onDone来对结果进行处理。

而kotlin中的回调不需要重新写一个接口。它可以直接把过程作为对象传入参数,如下:onDone是一个类型为(参数为User,返回值为Void的过程)。可以看到findUser方法的结尾调用了onDone,并把保存后的user作为参数传递进去了。调用findUser方法的时候,我们就可以使用lambda表达式写出对传入onDone的参数user对象的处理。

 /*
* 查找指定用户名和密码的用户
* */
fun findUser(userName:String,pwd:String, onDone:(User?) -> Unit){
val query=JsonObject().put("name",userName).put("pwd",pwd)
mongoClient.find("jtest",query,{res->
var user:User?=null
if (res.succeeded()){
val result=res.result()[]
if (!result.isEmpty){
user=User(result.getString("name"),result.getString("pwd"))
}
}
onDone.invoke(user)
})
}
val userDao = UserDao()
val user = userDao.findUser(userName, pwd) { user ->
if (user == null) {
var resp = "用户名或密码输入错误!!"
println(resp)
} else {
var resp = "登陆成功!"
println(resp)
}
}

2018.7.27的再次更新:

加了注册功能,封装了一些方法,看起来更简洁了一些。对kotlin的异步有了更深的了解,回调函数可以传递,如下:

 fun login(Param:JsonObject,onDone:(JsonObject)->Unit){
LoginService().login(Param, {req->
val request=req
onDone(req)
})
} //可以写成如下: fun login(Param:JsonObject,onDone:(JsonObject)->Unit){
LoginService().login(Param, onDone)
}

此外,如果反射要调用的函数里有回调,那么只需要先声明一个变量保存这个回调函数,再传入参数即可:

//回调函数
val call: (JsonObject) -> Unit = {response->
resp=response
onDone(resp!!)
} //得到类的引用M KClass<*> 类型
var M = Main.ins.controllerManager.controllers.get(actions[0])
//得到方法的引用A KFunction<*> 类型
var A = M?.methods?.get(actions[1])
//反射,这里把回调函数作为参数传入,不能直接把大括号写在里面
A?.javaMethod?.invoke(conIns, JsonObject(),call)

最新文章

  1. select初始化添加option,通过标签给出回显值,由于回显值和初始化值option中有一个值重复,去重等问题!
  2. poj3461 字符串匹配 熟悉kmp算法第一题
  3. 再也不必当心我的密码了,多个SAP 客户端自动输入密码
  4. face mask in opencv
  5. 使用 Team Foundation 版本控制命令
  6. asp.net 实现对xml文件的 读取,添加,删除,修改
  7. SRM 599 DIV1
  8. Ecstore 2.0 报表显示空白
  9. Arcengine 开发,FeatureClass新增feature时“The Geometry has no z-value”或&quot;The Geometry has null z-value&quot;的解决方案
  10. hdu 4712 Hamming Distance bfs
  11. 教你pomeloclient包libpomelo增加cocos2d-x 3.0工程(Windows、Android、IOS平台)
  12. 5次Shift会触发粘滞键的妙用(转)
  13. Linq to Sql:N层应用中的查询(下) : 根据条件进行动态查询
  14. 移动端Bug管理工具——Bugtags
  15. ASP.NET MVC 实现AJAX跨域请求的两种方法
  16. 最近学习java时的记录
  17. 2个域名重定向到https域名
  18. Chart.js 與 ASP.NET MVC 整合應用
  19. docker学习------docker私有仓库的搭建
  20. hive高级数据类型

热门文章

  1. PHP环境安全性能检查
  2. mongodb replica set搭建
  3. ASCII,Unicode,UTF-8
  4. 9 关联管理器(RelatedManager)
  5. Oracle诊断:使用USER_SEGMENTS分配给表的物理空间大小
  6. Matlab 中 函数circshift()的用法
  7. 【zabbix】zabbix 高可用架构的实现
  8. python文件操作错误解决
  9. LinkedBlockingDeque 源码分析
  10. 在window 10查看一下指定命令行工具所在的位置