架构师日记——手写利用HTTP协议远程模块调用
2017-08-24 09:41
465 查看
远程模块调用比较流行的协议有RPC协议、RMI协议和HTTP协议
本篇博客教大家如何使用HTTP协议试远程模块的调用
接下来我一个一个讲解他们的作用
1.根据不同的uuid去获取到远端方法的url
2.实现参数中非法字符的转换
3.组合url和参数
代码如下
一个利用HTTP远程调用模块的Demo就写好了,但HTTP协议效率较低,所以在日常开发中,我们常常使用RPC协议实现远程调用模块,比如使用著名的Dubbo框架
本篇博客教大家如何使用HTTP协议试远程模块的调用
1.定架构
总体架构如下接下来我一个一个讲解他们的作用
2.ModuleModel
这个类的作用是记录不同uuid对应的module的信息,包括远端ip和url等,代码如下/** * 调用远端方法的协议类 */ public class InteractiveModel { /** * 操作类型 */ private String opeType; /** * 操作参数 */ private Map<String,Object>map=new HashMap<String ,Object>(); public InteractiveModel(String opeType, Map<String, Object> map) { this.opeType = opeType; this.map = map; } public InteractiveModel() { } public String getOpeType() { return opeType; } public void setOpeType(String opeType) { this.opeType = opeType; } public Map<String, Object> getMap() { return map; } public void setMap(Map<String, Object> map) { this.map = map; } }
3.InteractiveModel
这个类可以说是调用方法的协议类,它包含操作类型和操作参数,代码如下/** * 调用远端方法的协议类 */ public class InteractiveModel { /** * 操作类型 */ private String opeType; /** * 操作参数 */ private Map<String,Object>map=new HashMap<String ,Object>(); public InteractiveModel(String opeType, Map<String, Object> map) { this.opeType = opeType; this.map = map; } public InteractiveModel() { } public String getOpeType() { return opeType; } public void setOpeType(String opeType) { this.opeType = opeType; } public Map<String, Object> getMap() { return map; } public void setMap(Map<String, Object> map) { this.map = map; } }
4.InteractiveCallHelper
InteractiveCallHelper是调用远端方法的发起者,这个类可以独立于这个项目,为了方便我就我不把它单独提取出来了,既可以返回string也可以返还一个指定类型的对象。这个类的作用主要有以下几个1.根据不同的uuid去获取到远端方法的url
2.实现参数中非法字符的转换
3.组合url和参数
代码如下
/** * 调用远端方法的发起者 */ public class InteractiveCallHelper { /** * * @param moduleId 模块Id * @param opeType 需要调用的具体的业务操作类型 * @param mapParams 调用所需要传递的参数 * @return 服务端返回的Json数据 */ public String call(String moduleId, String opeType, Map<String,Object>mapParams){ //1.根据moduleId去获取到该模块部署的信息,理论上要根据moduleId去设置,这里写死 ModuleModel moduleModel=new ModuleModel(); moduleModel.setDeployIP("localhost"); moduleModel.setDeployPort("8080"); moduleModel.setIntereractiveUrl("/goods/call"); //2.准备要传递的数据,把Map转换为JSON String paramStr= JSON.toJSONString(mapParams); //因为#在url里有特殊含义,所以将#替换为* paramStr=paramStr.replace("#","*"); //3.拼接一个远程调用的URL String urlStr="http://"+ moduleModel.getDeployIP()+":"+moduleModel.getDeployPort()+moduleModel.getIntereractiveUrl() +"?jsonParam={opeType:"+opeType+",map:"+paramStr+"}"; //4.使用URL进行远程调用,流式操作 BufferedReader in =null; String retJson=""; try { URL url=new URL(urlStr); URLConnection urlConnection=url.openConnection(); // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader( urlConnection.getInputStream())); String line; while ((line = in.readLine()) != null) { retJson += line; } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } return retJson; } /** * * @param moduleId 模块Id * @param opeType 需要调用的具体的业务操作类型 * @param mapParams 调用所需要传递的参数 * @param cls 需要转的类型 * @return 服务器返回的对象 */ public <T>T call(String moduleId, String opeType, Map<String,Object>mapParams,Class<T> cls){ String json=call(moduleId,opeType,mapParams); return JSON.parseObject(json,cls); } /** * 测试方法 * @param args */ public static void main(String[]args){ InteractiveCallHelper interactiveCallHelper=new InteractiveCallHelper(); Map<String,Object>map=new HashMap<String,Object>(); String str=interactiveCallHelper.call("goods","1",map); System.out.println(str); } }
5.InteractiveBaseController
这个类是远端被调用方法的基类,这个类是个抽象类,任何远端可被调用的controller都要继承它,继承call方法和实现它的doCall方法,代码如下/** * 远端被调用方法的基类 */ public abstract class InteractiveBaseController { /** * 解析参数 * @param jsonParam * @return */ @RequestMapping("/call") @ResponseBody public Object call(String jsonParam){ if (jsonParam!=null&&jsonParam.contains("*")){ //将*变回# jsonParam=jsonParam.replace("*","#"); } InteractiveModel interactiveModel= JSON.parseObject(jsonParam,InteractiveModel.class); Object ret=doCall(interactiveModel.getOpeType(),interactiveModel.getMap()); return ret; } protected abstract Object doCall(String opetype, Map<String,Object>map); }
6.GoodsModel
这个类是JavaBean,和数据库对应的实体类,可自由替换,代码如下/** * 要操作的实体类 */ public class GoodsModel { private String uuid; private String name; public GoodsModel(String uuid, String name) { this.uuid = uuid; this.name = name; } public GoodsModel() { } public String getUuid() { return uuid; } public void setUuid(String uuid) { this.uuid = uuid; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "GoodsModel{" + "uuid='" + uuid + '\'' + ", name='" + name + '\'' + '}'; } }
7.GoodsController
远程方法示例,根据不同opetype执行不同的操作,如opetype为1时往数据库插入一个实体,代码如下@RestController @RequestMapping(value = "goods") public class GoodsController extends InteractiveBaseController{ @Override protected Object doCall(String opetype, Map<String, Object> map) { //执行不同的操作 if ("1".equals(opetype)){ }else if ("2".equals(opetype)){ } GoodsModel goodsModel=new GoodsModel(); goodsModel.setName("abc"); goodsModel.setUuid("132132"); System.out.println("call"); return goodsModel; } }
一个利用HTTP远程调用模块的Demo就写好了,但HTTP协议效率较低,所以在日常开发中,我们常常使用RPC协议实现远程调用模块,比如使用著名的Dubbo框架
完整代码已上传到github:https://github.com/jkgeekJack/UseRemoteInvoker
相关文章推荐
- JAVA与.NET的相互调用——利用JNBridge桥接模式实现远程通讯
- 玩转PowerShell第二节——【利用PsExec进行远程调用】-技术&分享
- Java利用Axis远程调用WebService接口
- 利用python的paramiko模块,自定义函数远程批量执行shell命令
- ASP.NET 3.5核心编程学习笔记(58):利用页面方法来进行远程调用
- 【远程调用框架】如何实现一个简单的RPC框架(三)优化一:利用动态代理改变用户服务调用方式
- python利用import调用功能模块
- JAVA与.NET的相互调用——利用JNBridge桥接模式实现远程通讯
- 利用c#实现远程注入非托管WIN32程序,并利用嵌入汇编调用非托管WIN32程序中的内部过程
- 使用接口的方式调用远程服务 ------ 利用动态调用服务,实现.net下类似Dubbo的玩法。
- 利用python fabric模块写的批量操作远程主机脚本(命令执行,上传、下载文件)
- node.js利用javascript中构造函数继承,实现模块调用
- 利用模块添加系统调用(不重新编译内核)
- Android中除了利用VideoView、Mediaplayer播放视频文件外,还可以用发送Intent来调用视频播放模块。
- 详解JBOSS系列一(利用JNDI,EJB远程调用本地的Bean)
- Firefly distributed模块的原理与twisted中PB远程调用协议
- “.NET研究”JAVA与.NET的相互调用——利用JNBridge桥接模式实现远程通讯
- Android中如何利用AIDL机制调用远程服务
- 利用jquery,访问ashx,调用ironPython模块功能
- Python调用paramiko模块实现远程管理多台服务器