包结构长这个样子:


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)

kotlin和vertx和mongo写的一个服务器验证登陆功能(很简陋)的更多相关文章

  1. 用Python写了一个postgresql函数,感觉很爽

    用Python写了一个postgresql函数,感觉很爽 CREATE LANGUAGE plpythonu; postgresql函数 CREATE OR REPLACE FUNCTION myfu ...

  2. 浅谈如何写出一个让(坑)人(王)很(之)难(王)发现的bug

    该文章内容来自脚本之家,原文链接:https://www.jb51.net/news/598404.html 程序员的日常三件事:写bug.改bug.背锅.连程序员都自我调侃道,为什么每天都在加班?因 ...

  3. 简单的一个php验证登陆代码

    <?php/** */ if ( !isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) || $_SERVER ...

  4. 实现一个最简单的VIM文本编辑器(可能有bug,随便写了一个)

    简单的写了一个文本编辑器,功能很简单,但足以把文件IO相关的操作熟悉了,可能功能或者分配的大小还不够完善.请参考参考: #include <stdio.h> #include <co ...

  5. 如何写出一个让人很难发现的bug?

    程序员的日常三件事:写bug.改bug.背锅.连程序员都自我调侃道,为什么每天都在加班?因为我的眼里常含bug. 那么如何写出一个让(坑)人(王)很(之)难(王)发现的bug呢? - 1 -新手开发+ ...

  6. bootstrap 一个简单的登陆页面

    效果如图:用bootstrap 写的一个简单的登陆 一.修改样式 样式可以自己调整,例如换个背景色之类的,修改 background-color属性就可以 #from { background-col ...

  7. 搞了我一下午竟然是web.config少写了一个点

    Safari手机版居然有个这么愚蠢的bug,浪费了我整个下午,使尽浑身解数,国内国外网站搜索解决方案,每一行代码读了又想想了又读如此不知道多少遍,想破脑袋也想不通到底哪里出了问题,结果竟然是web.c ...

  8. 用C3中的animation和transform写的一个模仿加载的时动画效果

    用用C3中的animation和transform写的一个模仿加载的时动画效果! 不多说直接上代码; html标签部分 <div class="wrap"> <h ...

  9. 写了一个常规性生成merge 的小脚本

    现在使用数据库来写存储过程,动不动参数就会用到xml ,当然罗,优势也很明显,参数相对固定,而且灵活,如果要修改或者什么的,中间接口层也不需要做变化,只需要修改封装的存储过程以及程序传参就ok了. 随 ...

随机推荐

  1. os模块 sys模块 json/pickle 模块 logging模块

    目录 模块 1. os模块 2. sys模块 3. json和pickle模块 4. logging模块 (1)日志配置 (2)实际开发中日志的使用 模块 1. os模块 os模块有什么用 与操作系统 ...

  2. android 常用框架总结(转载)

    原文:https://blog.csdn.net/weixin_44702125/article/details/89886948

  3. 判断img的src为空/点击时候两张图片来回替换

    if($('.icon-right img').src==null){ $('.span-gray').addClass('c8'); } <img> ///////////// < ...

  4. Leetcode 16. 3Sum Closest(指针搜索)

    16. 3Sum Closest Medium 131696FavoriteShare Given an array nums of n integers and an integer target, ...

  5. 【PowerOJ1753&网络流24题】分配问题(KM)

    题意: 思路:费用流可做 最好的算法是KM板子 #include<bits/stdc++.h> using namespace std; typedef long long ll; typ ...

  6. HTML5和CSS3兼容清单

    1.CSS3 2.CSS3选择器 3.HTML5 4.HTML5 From  

  7. 获取oracle数据库对象定义

    在oracle中,使用DBMS_METADATA包中的GET_DDL函数来获得对应对象的定义语句.GET_DDL函数的定义如下: DBMS_METADATA.GET_DDL ( object_type ...

  8. ES5 Object.defineProperties / Object.defineProperty 的使用

    临时笔记,稍后整理 var obj = { v: , render: function () { console.log(") } }; // Object.defineProperties ...

  9. 自定义控件 - 流式布局:TagFlowLayout

    在项目中需要用到流式布局的样式,此文学习鸿洋大神的FlowLayout控件,学习使用一下.出自 http://blog.csdn.net/lmj623565791/article/details/38 ...

  10. AtomicIntegerArray 源码分析

    AtomicIntegerArray AtomicIntegerArray 能解决什么问题?什么时候使用 AtomicIntegerArray? 可以用原子方式更新其元素的 int 数组 如何使用 A ...