包结构长这个样子:


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. maven 坐标获取方式

    问题:我们在开发时pom.xml文件中的 <dependencies>     <dependency>         <groupId>org.mybatis& ...

  2. [CF434D Div1] Tree

    问题描述 给定一颗 n 个点的树,树边带权,试求一个排列 P,使下式的值最大 \[ \sum_{i=1}^{n-1}maxflow(P_i,P_{i+1}) \] 其中 maxflow(s, t) 表 ...

  3. 系统符号二——正则表达式及三剑客之grep

    一基础正则表达式 (一)^  匹配以什么开头的信息 [root@centos71 ~]# grep "^root" /etc/passwd root:x:0:0:root:/roo ...

  4. vue的生产环境dependencies 和开发环境devDependencies,二者的理解和区别

  5. Java——容器(泛型)

    [泛型]  起因:JDK1.4之前类型不明确  <1>装入集合的类型都被当做Object对待,从而失去自己的实际类型.  <2>从集合中取出时往往需要转型,效率低,且很容易出错 ...

  6. Altera培训SignalTap II的使用--笔记

    培训的内容有点多(啰嗦)(笔记为截图) 听课笔记:Altera培训SignalTap II的使用--笔记

  7. 【bzoj1146】[CTSC2008]网络管理Network

    题目描述: M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条 ...

  8. Python用MyQR生成自定义个性二维码

    MyQR是一个能够生成自定义二维码的python第三方库,根据需要能够生成普通二维码.带背景图片的艺术二维码.动态二维码. 1.MyQR安装 安装非常简单,直接用pip install MyQR,需要 ...

  9. 20181022-JSP 开发环境搭建

    JSP 开发环境搭建 JSP开发环境是您用来开发.测试和运行JSP程序的地方. 本节将会带您搭建JSP开发环境,具体包括以下几个步骤. 配置Java开发工具(JDK) 这一步涉及Java SDK的下载 ...

  10. es之java搜索文档

    1:搜索文档数据(单个索引) @Test public void getSingleDocument(){ GetResponse response = client.prepareGet(" ...