kotlin和vertx和mongo写的一个服务器验证登陆功能(很简陋)
包结构长这个样子:

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写的一个服务器验证登陆功能(很简陋)的更多相关文章
- 用Python写了一个postgresql函数,感觉很爽
用Python写了一个postgresql函数,感觉很爽 CREATE LANGUAGE plpythonu; postgresql函数 CREATE OR REPLACE FUNCTION myfu ...
- 浅谈如何写出一个让(坑)人(王)很(之)难(王)发现的bug
该文章内容来自脚本之家,原文链接:https://www.jb51.net/news/598404.html 程序员的日常三件事:写bug.改bug.背锅.连程序员都自我调侃道,为什么每天都在加班?因 ...
- 简单的一个php验证登陆代码
<?php/** */ if ( !isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) || $_SERVER ...
- 实现一个最简单的VIM文本编辑器(可能有bug,随便写了一个)
简单的写了一个文本编辑器,功能很简单,但足以把文件IO相关的操作熟悉了,可能功能或者分配的大小还不够完善.请参考参考: #include <stdio.h> #include <co ...
- 如何写出一个让人很难发现的bug?
程序员的日常三件事:写bug.改bug.背锅.连程序员都自我调侃道,为什么每天都在加班?因为我的眼里常含bug. 那么如何写出一个让(坑)人(王)很(之)难(王)发现的bug呢? - 1 -新手开发+ ...
- bootstrap 一个简单的登陆页面
效果如图:用bootstrap 写的一个简单的登陆 一.修改样式 样式可以自己调整,例如换个背景色之类的,修改 background-color属性就可以 #from { background-col ...
- 搞了我一下午竟然是web.config少写了一个点
Safari手机版居然有个这么愚蠢的bug,浪费了我整个下午,使尽浑身解数,国内国外网站搜索解决方案,每一行代码读了又想想了又读如此不知道多少遍,想破脑袋也想不通到底哪里出了问题,结果竟然是web.c ...
- 用C3中的animation和transform写的一个模仿加载的时动画效果
用用C3中的animation和transform写的一个模仿加载的时动画效果! 不多说直接上代码; html标签部分 <div class="wrap"> <h ...
- 写了一个常规性生成merge 的小脚本
现在使用数据库来写存储过程,动不动参数就会用到xml ,当然罗,优势也很明显,参数相对固定,而且灵活,如果要修改或者什么的,中间接口层也不需要做变化,只需要修改封装的存储过程以及程序传参就ok了. 随 ...
随机推荐
- hdu 3572 : Task Schedule (网络流)
题目链接 题意: 有M个机器,N个任务 对第i个任务,需要在[Si,Ei]这段时间内恰有Pi天被process 每天最多有M个机器同时工作 每一天,一个任务若被process,那么它恰占用一个机器. ...
- 【leetcode】1175. Prime Arrangements
题目如下: Return the number of permutations of 1 to n so that prime numbers are at prime indices (1-inde ...
- JavaScript输出
JavaScript不提供任何的内建或是打印方式 JavaScript的显示方案主要有以下四种: window.alert() 写入警告框 document.write() 写入 HTML 输出 ...
- 8:Spring Boot中thymeleaf模板中使用 Shiro标签
1,添加 pom.xml grade: compile('com.github.theborakompanioni:thymeleaf-extras-shiro:1.2.1') 2, Subject ...
- 状态管理工具对比vuex、redux、flux
1.为什么要使用状态管路工具 在跨层级的组件之间传递信息,尤其是复杂的组件会非常困难.也不利于开发和维护,这时我们就a需要用到状态管理工具. 2.Flux
- php list()函数 语法
php list()函数 语法 作用:用于在一次操作中给一组变量赋值.博智达 语法:list(var1,var2...) 参数: 参数 描述 var1 必需.第一个需要赋值的变量. var2,... ...
- jQuery ajax - ajaxSetup() 方法
实例 为所有 AJAX 请求设置默认 URL 和 success 函数: $("button").click(function(){ $.ajaxSetup({url:" ...
- Linux 安装R包
https://www.cnblogs.com/jessepeng/p/10984983.html Linux 的R环境,可以通过anaconda jupyter notbook很容易的配置,见我之前 ...
- LINUX boot 内存不够
查看当前使用内核版本号.输入 uname -a 查看. 删除旧内核.输入命令: sudo apt-get remove linux-image- 接着按两下tab键,将显示所有的内核版本:把目前使用的 ...
- MySql中报错:java.sql.SQLException: Incorrect string value: '\xF0\x9F\x90\xBB' for column
问题描述: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x90\xBB' for column 'nickName' at row ...