博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RPC实践(二)JsonRPC实践
阅读量:2497 次
发布时间:2019-05-11

本文共 8106 字,大约阅读时间需要 27 分钟。

一、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 );    }    @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"));                        // 请求头中添加的信息,这里可以自己定义            Map
headers = 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); }}

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 ++++++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&params=JTViJTVk

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

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

服务端打印

JsonRpcService service being calldo 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 按钮后,在返回区可以看到返回内容

你可能感兴趣的文章
vue-cli 3.0安装和使用
查看>>
数据结构与算法6—树
查看>>
.net mvc 超过了最大请求长度 限制文件上传大小
查看>>
PDU与SDU理解
查看>>
linux分盘笔记
查看>>
606. Construct String from Binary Tree
查看>>
[iOS] Win8下在Vmware11中安装使用苹果系统OS X 10.10
查看>>
Flex布局
查看>>
峰Redis学习(8)Redis 持久化AOF方式
查看>>
spring指导的index.html在spring文件夹中的位置
查看>>
12.6今日任务
查看>>
Debian8.3.0下安装Odoo8.0步骤
查看>>
Maven 3-Maven依赖版本冲突的分析及解决小结
查看>>
Lists
查看>>
WPF 关于鼠标事件和坐标
查看>>
100个直接可以拿来用的JavaScript实用功能代码片段
查看>>
[转]Design Pattern Interview Questions - Part 2
查看>>
winform错误提示 :窗口类名无效(Window class name is not valid)
查看>>
[STemWin教程入门篇]第一期:emWin介绍
查看>>
编译原理
查看>>