话不多说,先上图。
这里以调用RPC框架dubbo接口为例,每次我们都是在测试某个接口或者验证某个dubbo接口得时候,都是写个controller去进行curl,而想要手动调用dubbo接口得时候,都需要先查ip,端口号,然后进入dubbo命令行界面,输入invoke得到结果,这些重复得工作一遍又一遍,对于可爱得程序员和美丽得测试妹子来说,这是在浪费我们深度交流得宝贵时间,不可忍耐。
在《重构:改善既有代码的设计》第三章代码的坏味道中,第一个被批判的就是DuplicatedCode(重复代码),可见重复性是万恶之源,在代码中不可忍,重复的手工操作更是要拒绝。
那么有没有什么可以办法解决呢?别问,问就是没有。但是对于左手python右手java的我们来说,怎么可以说没有。下面就是笔者使用python脚本编写得使用telnet调用dubbo接口得简单封装,在此基础稍加修饰就可以改成更加通用得程序,之后我们就可以再写不用写controller和调用dubbo接口去查看接口情况了,测试妹子也可以更愉快得去写单元测试了。
以下代码适用于python2.x和python3.x,由于linux发行版本身附带的软件(如RedHat系的包管理器dnf就是用python写的)需要python环境,所以linux默认就拥有python2.7得环境,对于不熟悉python得同学,也能直接复制粘贴直接linux运行。由于从这里复制后直接在linux运行会语法错误,建议赋值到记事本将空格和注释全部去掉,获取一行一行的复制进去后就可以了。
话不多说,人生苦短,python走起。
import jsonimport telnetlibdef invoke(method_call_str, ip='127.0.0.1', port=20880): """ 类似在dubbo linux中的invoke的操作 :param method_call_str: :param ip: ip地址 :param port: 端口号 :return: """ prompt = 'dubbo>' coding = 'utf-8' # 创建telnet类对象 conn = telnetlib.Telnet() # 连接dubbo接口地址 conn.open(ip, port) # cmd命令格式: 接口全名字.方法名(参数1,参数2,参数3...参数n) # write方法就是模拟我们在linux上的操作,通过telnet或者nc -nvv ip port一样发起dubbo的请求的执行步骤,参数和单独使用telnet一致 # 我们输入telnet后要换行的 conn.write(b'\n') # 然后等待我们会出现dubbo>的标签头 data = conn.read_until(prompt.encode()) # 然后将我们的调用接口的信息发给dubbo 然后输入命令后要换行执行 conn.write(method_call_str.encode() + b"\n") # 然后等待我们会出现dubbo>的标签头 data = conn.read_until(prompt.encode()) # 然后将结果中result之后的部分取出来,就是一个返回的json对象 data = data.decode("utf-8", "ignore").split('result')[-1].split('\r\n')[0].split(': ')[-1].strip() return data# invoke 包的全限定名.方法名(参数1,参数2,参数3......)methon_info=r'invoke xxx.xxx("xxx")'#你得ip地址ip = 'xxx'# 你的dubbo端口号port = 20888data=invoke(methon_info, ip, port)data=json.loads(data)# 返回结果就是json对象# 然后就是根据具体的json对象去取具体想要的数据了code=data.get('code')# 这一步如果是python3.x 要改为print(code)print code
结束语
其实dubbo命令调用接口,最繁琐的就是invoke后的接口参数,他本身是将字符串进行反序列化构造参数。比如用户输入的指令为invoke com.mjcr.telnet.call('1111'), 那么他会将invoke识别成command命令,然后将invoke后面的东西解析成message去调用。
@SPIpublic interface TelnetHandler{ // 第一步 这里面会将我们传入的json串转为JSON对象 String telnet(Channel channel, String message) throws RemotingException;}