一、JsonRPC介绍

json-rpc是基于json的跨语言远程调用协议,比xml-rpc、webservice等基于文本的协议传输数据格小;相对hessian、Java-rpc等二进制协议便于调试、实现、扩展,是非常优秀的一种远程调用协议。目前主流语言都已有json-rpc的实现框架,java语言中较好的json-rpc实现框架有jsonrpc4j、jpoxy、json-rpc。三者之中jsonrpc4j既可独立使用,又可与spring无缝集合,比较适合于基于spring的项目开发。

二、JsonRPC简单说明

1、调用的Json格式

向服务端传输数据格式如下:
   { "method": "方法名", "params": [“参数数组”], "id":  方法ID}

说明:

第一个参数: 是方法的名值对

第二个参数: 是参数数组

第三个参数: 是方法ID(可以随意填)

举例:  { "method": "doSomething", "params": [], "id": 1234}

doSomething 是远程对象的方法, []  表示参数为空

2、输出的Json格式

{
  "jsonrpc": "2.0",
  "id": "1234",
  "result": null
}

三、JsonRPC的demo

下面展示一个demo,这个demo的主要内容,就是创建一个服务端对象,由客户端进行调用

对象关系

对象关系图如下:

3.1工程搭建

1) 创建一个web projcct工程

2) 创建相应的class,拷贝lib中需要的jar包

3)发布,并运行tomcat

发布myeclipse的tomcat环境,最重要的是web.xml文件,下面展现web.xml的内容

注意: 最后的url,在  "主机:端口"后跟的工程名称,然后是url-pattern

以上图为例: http://127.0.0.1:8080/StudyJsonrpc4j/rpc

3.2代码

1) 实体类

HelloWorldService.java

package com.cwqsolo.demo.enitity;/** 定义一个服务的接口*/
public interface HelloWorldService {public HelloWorldBean getDemoBean(String code, String msg);public Integer getInt(Integer code);public String getString(String msg);public void doSomething();}

HelloWorldBean.java

package com.cwqsolo.demo.enitity;import java.io.Serializable;public class HelloWorldBean implements Serializable{private static final long serialVersionUID = -12345L;private int code;private String msg;public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}

HelloWorldServiceImpl.java

package com.cwqsolo.demo.enitity;public class HelloWorldServiceImpl  implements HelloWorldService {int  count=0;public HelloWorldBean getDemoBean(String code, String msg) {System.out.println("HelloWorldBean get");HelloWorldBean bean1 = new HelloWorldBean();bean1.setCode(Integer.parseInt(code));bean1.setMsg(msg+",javaBean is fine!");return bean1;}//计算服务端count值与客户端传进来的code值的和public Integer getInt(Integer code) {return code+count;}//返回某种字符串操作的结果public String getString(String msg) {return msg+",server is fine!";}//服务端接受调用,执行某些业务动作。这里是count进行技术public void doSomething() {count++;System.out.println("do something"+"; count=>"+count);} }

2) 服务端代码

JsonRpcService.java

package com.cwqsolo.demo.server;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.cwqsolo.demo.enitity.HelloWorldService;
import com.cwqsolo.demo.enitity.HelloWorldServiceImpl;
import com.googlecode.jsonrpc4j.JsonRpcServer;public class JsonRpcService  extends HttpServlet {private static final long serialVersionUID = 1L;private JsonRpcServer rpcServer = null;public JsonRpcService() {super();//服务端生成HelloWorldServiceImpl对象,并且提供对应的方法rpcServer = new JsonRpcServer(new HelloWorldServiceImpl(), HelloWorldService.class );}@Overrideprotected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {System.out.println("JsonRpcService service being call");rpcServer.handle(request, response);}}

3) 客户端代码

package com.cwqsolo.demo.client;import java.net.URL;
import java.util.HashMap;
import java.util.Map;import com.cwqsolo.demo.enitity.HelloWorldBean;
import com.googlecode.jsonrpc4j.JsonRpcHttpClient;public class JsonRpcClient{static JsonRpcHttpClient client;public JsonRpcClient() {}public static void main(String[] args) throws Throwable {// 实例化请求地址,注意服务端web.xml中地址的配置try {client = new JsonRpcHttpClient(new URL("http://127.0.0.1:8080/StudyJsonrpc4j/rpc"));// 请求头中添加的信息,这里可以自己定义Map<String, String> headers = new HashMap<String, String>();headers.put("Name", "Key");// 添加到请求头中去client.setHeaders(headers);//客户端doSomethine方法,通过调用远程对象的dosomethingJsonRpcClient test = new JsonRpcClient();//客户端getDemo,是获取远程对象的HelloWorldBeanHelloWorldBean demo = test.getDemo(1, "Hello");       //执行远程对象的get方法System.out.println("++++++ call remote javabean obj function ++++++");System.out.println(demo.getCode());System.out.println(demo.getMsg());          //执行远程对象的方法int code = test.getInt(10);System.out.println("++++++ call remote function Integer:first ++++++");System.out.println(code);//调用服务端doSomething 方法test.doSomething();//第二次调用远程对象的getInt方法code = test.getInt(10);System.out.println("++++++ call remote function Integer:second ++++++");System.out.println(code);String msg = test.getString("hello");System.out.println("++++++ Call remote function String  ++++++");System.out.println(msg);System.out.println("++++++ end ++++++");} catch (Exception e) {e.printStackTrace();}}/**客户端dosomething 方法,调用服务端的dosomething*/public void doSomething() throws Throwable {client.invoke("doSomething", null);}/**客户端getDemo 方法,调用服务端的getDemo*/public HelloWorldBean getDemo(int code, String msg) throws Throwable {String[] params = new String[] { String.valueOf(code), msg };HelloWorldBean demo = null;demo = client.invoke("getDemoBean", params, HelloWorldBean.class);return demo;}/** 客户端getInt 是调用服务端getInt方法*/public int getInt(int code) throws Throwable {Integer[] codes = new Integer[] { code };return client.invoke("getInt", codes, Integer.class);}/** 客户端getString 是调用服务端getString方法*/public String getString(String msg) throws Throwable {String[] msgs = new String[] { msg };return client.invoke("getString", msgs, String.class);}}

3.3运行和测试:

1) 服务端启动:

在myeclipse的环境下,启动server

信息: Starting Servlet Engine: Apache Tomcat/7.0.30
十二月 12, 2016 4:49:56 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory E:\cwqwork\MyEclipse_Workspace\.metadata\.me_tcat7\webapps\StudyJsonrpc4j
十二月 12, 2016 4:49:58 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-bio-8080"]
十二月 12, 2016 4:49:58 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["ajp-bio-8009"]
十二月 12, 2016 4:49:58 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in 2340 ms

可以看到打印出来的日志:

信息: Deploying web application directory E:\cwqwork\MyEclipse_Workspace\.metadata\.me_tcat7\webapps\StudyJsonrpc4j  ---表示发布在tomcat环境的工程,在tomcat启动后加载

Server startup in 2340 ms  ----表示tomcat启动成功

2) 客户端程序调用

直接运行客户端程序进行调用,在客户端代码类,右键运行:

++++++ call remote javabean obj function ++++++
1
Hello,javaBean is fine!
++++++ call remote function Integer:first ++++++
10
++++++ call remote function Integer:second ++++++
11
++++++ Call remote function String  ++++++
hello,server is fine!
++++++ end ++++++

可以看到 first,second调用,返回的结果不同,说明服务端的数据在第一次调用后,数据发生了改写

3)直接浏览器中get方式调用,以代码用doSomething 方法为例

http://127.0.0.1:8080/StudyJsonrpc4j/rpc?method=doSomething&id=1234&params=JTViJTVk

说明:params=JTViJTVk, 因为params 参数为空,填入的[],需要转换为 url编码,再转为base64编码,这个编码为 JTViJTVk

调用后,客户端会提示下载,下载后用浏览器打开,里面是调用返回的内容

服务端打印

JsonRpcService service being call
do something; count=>3

4) 可以用postman 工具来测试,用get方法,post方法都能成功

用get方法:

在第一个红框处输入: http://127.0.0.1:8080/StudyJsonrpc4j/rpc?method=doSomething&id=1234&params=JTViJTVk

第二个红框是send 后,返回的内容

用post 方法:

用POST方式,url 为:http://127.0.0.1:8080/StudyJsonrpc4j/rpc, 点击params 按钮后,在body里面,填入json串

{ "method": "doSomething", "params": [], "id": 1234}

点send 按钮后,在返回区可以看到返回内容

RPC实践(二)JsonRPC实践相关推荐

  1. Java内部类与异常类(上机实践二)

    Java内部类与异常类(上机实践二) 实践一 内部购物卷 手机专卖店为了促销自己的产品,决定发行内部购物券,但其他商场不能发行该购物券.编写一个 MobileShop 类(模拟手机专卖店),该类中有一 ...

  2. 软件工程专业(互联网应用开发与优化方向)软件工程实践二环节教学大纲

    软件工程专业(互联网应用开发与优化方向)软件工程实践二环节教学大纲 培训课程 Phthon Web开发 实训公司 XXX 总周数 3周

  3. 《Linux及安全》课程实践二

    编译生成新内核 一.实践原理 Linux模块是一些可以作为独立程序来编译的函数和数据类型的集合.之所以提供模块机制,是因为Linux本身是一个单内核.单内核由于所有内容都集成在一起,效率很高,但可扩展 ...

  4. P4语言编程快速开始 实践二

    参考:P4语言编程快速开始 上一篇系列博客:P4语言编程快速开始 实践二 Demo 2 本Demo所做的修改及实现的功能: 为simple_router添加一个计数器(counter),该计数器附加( ...

  5. ASP.NET MVC5 网站开发实践(二) Member区域 - 用户部分(2)用户登录、注销

    上次实现了用户注册,这次来实现用户登录,用到IAuthenticationManager的SignOut.SignIn方法和基于声明的标识.最后修改用户注册代码实现注册成功后直接登录. 目录: ASP ...

  6. Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(二)

    原文:Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(二) Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(一) 接上一篇 ...

  7. 中班音乐活动 机器人_【家门口的好幼儿园】玩转音乐,释放天性——岳阳幼儿园开展松江区骨干共同体名师二团实践研究活动...

    MUSIC 玩转音乐 释放天性 来园签到 11月20日上午,岳阳幼儿园开展了由业务园长张准老师带领的松江区骨干共同体名师二团实践研究活动.此次活动有幸邀请到了松江区学前教育科何琳芳科长.上海市特级园长 ...

  8. Nginx反向代理与负载均衡应用实践(二)

    Nginx反向代理与负载均衡应用实践(二) 链接:https://pan.baidu.com/s/1xB20bnuanh0Avs4kwRpSXQ 提取码:migq 复制这段内容后打开百度网盘手机App ...

  9. SOLR7实践(二)--DIH配置及使用

    DIH配置及使用@SOLR7实践(二) DIH配置及使用 网上已经有很多相关文章了,但是实践中还是遇到了些问题,备忘一下. 一.配置solrconfig.xml 编辑/var/solr/data/ne ...

  10. 《Python网络爬虫从入门到实践 第2版》第15章 爬虫实践二:知乎Live

    第15章 爬虫实践二:知乎Live 知乎是中文互联网一个非常大的知识社交平台.在知乎上,用户可以通过问答等交流方式获取知识.区别于百度知道等问答网站,知乎的回答往往非常深入,都是回答者精心写的,知乎上 ...

最新文章

  1. delete []实现机制
  2. 清理linux内存cache
  3. “山东土地集团杯”暨滨州市数据应用创新创业大赛正式启动!
  4. 2月28日云栖精选夜读 | 阿里云率先达成国家绿色数据中心标准,平均PUE低于1.3...
  5. MySQL调优(五):MySQL查询优化分析
  6. Python多重继承时属性的调用顺序
  7. 比机器人更优越的半机械昆虫,颜控党们会接受吗?
  8. SQL导入/导出Excel
  9. Eclipse反编译插件(免费无需下载资源)
  10. 新著作计划:《水利水电工程施工导流 水力计算与.NET编程》
  11. SAP从入门到精通 知识体系
  12. 计算机开机没有d盘,电脑每次开机总是自检D盘的解决办法
  13. 梯形公式预测校正matlab_鲁棒预测控制(Robust MPC)
  14. 华三防火墙应用二层和三层的配置实例
  15. gnuplot下载及基本使用
  16. Win10连接远程桌面失败
  17. CEA抗体对丨CalBioreagents 中英文说明书
  18. Java语音SDK接口开发经验及具体开发实现
  19. 产业区块链一周动态丨蚂蚁集团计划上市,苏州成立10亿元区块链基金
  20. eas报错日记_EAS8.1预留记录查询报错

热门文章

  1. 【shell】shell脚本实战-sed流编辑器
  2. day20.1-CE基本使用与原理
  3. 天勤数据结构代码——链表基本操作
  4. 车牌识别系统论文python_毕业设计 python opencv实现车牌识别 界面
  5. STC51定时器与定时器中断
  6. 【保姆级】黑客入门教程「Python安全攻防:渗透测试实战指南」经典纯狱风~
  7. QPainter::begin: Painter already active
  8. php文本编辑器fck,HTML文本编辑器:FCKeditor 2.6.3下载
  9. 华为手表GT2 模拟加密门禁卡
  10. ps保存psd后图层全没了_怎么利用ps把psd图层单独导出为一张张的图片?