本文共 8106 字,大约阅读时间需要 27 分钟。
json-rpc是基于json的跨语言远程调用协议,比xml-rpc、webservice等基于文本的协议传输数据格小;相对hessian、Java-rpc等二进制协议便于调试、实现、扩展,是非常优秀的一种远程调用协议。目前主流语言都已有json-rpc的实现框架,java语言中较好的json-rpc实现框架有jsonrpc4j、jpoxy、json-rpc。三者之中jsonrpc4j既可独立使用,又可与spring无缝集合,比较适合于基于spring的项目开发。
向服务端传输数据格式如下: { "method": "方法名", "params": [“参数数组”], "id": 方法ID}
说明:
第一个参数: 是方法的名值对
第二个参数: 是参数数组
第三个参数: 是方法ID(可以随意填)
举例: { "method": "doSomething", "params": [], "id": 1234}
doSomething 是远程对象的方法, [] 表示参数为空
{ "jsonrpc": "2.0", "id": "1234", "result": null }
下面展示一个demo,这个demo的主要内容,就是创建一个服务端对象,由客户端进行调用
对象关系
对象关系图如下:
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
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 ); } @Override protected 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")); // 请求头中添加的信息,这里可以自己定义 Mapheaders = new HashMap (); headers.put("Name", "Key"); // 添加到请求头中去 client.setHeaders(headers); //客户端doSomethine方法,通过调用远程对象的dosomething JsonRpcClient test = new JsonRpcClient(); //客户端getDemo,是获取远程对象的HelloWorldBean HelloWorldBean 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); }}
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 ++++++1Hello,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¶ms=JTViJTVk
说明:params=JTViJTVk, 因为params 参数为空,填入的[],需要转换为 url编码,再转为base64编码,这个编码为 JTViJTVk
调用后,客户端会提示下载,下载后用浏览器打开,里面是调用返回的内容
服务端打印
JsonRpcService service being calldo something; count=>34) 可以用postman 工具来测试,用get方法,post方法都能成功
用get方法:
在第一个红框处输入: http://127.0.0.1:8080/StudyJsonrpc4j/rpc?method=doSomething&id=1234¶ms=JTViJTVk
第二个红框是send 后,返回的内容
用post 方法:
用POST方式,url 为:http://127.0.0.1:8080/StudyJsonrpc4j/rpc, 点击params 按钮后,在body里面,填入json串
{ "method": "doSomething", "params": [], "id": 1234}
点send 按钮后,在返回区可以看到返回内容