zoukankan      html  css  js  c++  java
  • JSON-RPC轻量级远程调用协议介绍及使用

    这个项目能够帮助开发人员利用Java编程语言轻松实现JSON-RPC远程调用。jsonrpc4j使用Jackson类库实现Java对象与JSON对象之间的相互转换。jsonrpc4j包含一个JSON-RPC服务器,支持Stream与HTTP(GET与POST),同时还提供一个支持Stream的JSON-RPC客户端。此外还提供一个HTTP客户端、Spring Service Provider和Spring Service Consumer。

    https://github.com/briandilley/jsonrpc4j (包下载)

    -----------------------------------------------

    JSON-RPC轻量级远程调用协议介绍及使用

    目录

    技术简介    1

    一、JSON-RPC协议描述    1

    二、JSON-RPC调用简单示例    1

    2.1、服务器端Java调用示例    1

    2.2、Java客户端调用示例    2

    2.3、PHP客户端调用示例    2

    2.3、JavaScript客户端调用示例    2

    2.4、直接GET请求进行调用    2

    三、JSON-RPC总结    3

    参考文档    3

    技术简介

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

    一、JSON-RPC协议描述

    json-rpc协议非常简单,发起远程调用时向服务端传输数据格式如下:

       { "method": "sayHello", "params": ["Hello JSON-RPC"], "id": 1}

    参数说明:

    method: 调用的方法名

    params: 方法传入的参数,若无参数则传入 []

    id : 调用标识符,用于标示一次远程调用过程

    服务器其收到调用请求,处理方法调用,将方法效用结果效应给调用方;返回数据格式:

     {   
        "result":          "Hello JSON-RPC",         
        "error":                null,       
          "id":                      1
     }                        

    参数说明:

    result: 方法返回值,若无返回值,则返回null。若调用错误,返回null。

    error :调用时错误,无错误返回null。

    id : 调用标识符,与调用方传入的标识符一致。

    以上就是json-rpc协议规范,非常简单,小巧,便于各种语言实现。

    二、JSON-RPC简单示例

    2.1、服务器端Java调用示例

    jsonrpc4j服务器端java示例:

    public class HelloWorldServlet extends HttpServlet {

        private static final long serialVersionUID = 3638336826344504848L;

        private JsonRpcServer rpcService = null;

        @Override

        public void init(ServletConfig config) throws ServletException {

            super.init(config);

            rpcService = new JsonRpcServer(new HelloWorldService(), HelloWorldService.class);

        }

        @Override

        protected void service(HttpServletRequest req, HttpServletResponse resp)

                throws ServletException, IOException {

            rpcService.handle(req, resp);    

        }

    }

    2.2、Java客户端调用示例

    jsonrpc4j的Java客户端调用示例:

            JsonRpcHttpClient client = new JsonRpcHttpClient(

                 new URL("http://127.0.0.1:8080/index.json"));

            Map<String,String> headers = new HashMap<String,String>();

            headers.put("name", "剑白");

         client.setHeaders(headers);

            String properties = client.invoke("getSystemProperties", null, String.class);

            System.out.println(properties);

    2.3、PHP客户端调用示例

    基于json-rpc-php的PHP客户端调用示例:

    <?php include(dirname(__FILE__)."/lib/client/JsonRpcClient.php");

    $client = new JsonRpcClient("http://10.13.49.234:8080/index.json");

    $response = $client->getSystemProperties();

    echo $response->result;

    ?>

    2.3、JavaScript客户端调用示例

    基于jsonrpcjs的JavaScript客户端调用示例:

    var rpc = new jsonrpc.JsonRpc('http://127.0.0.1:8080/index.json');

    rpc.call('getSystemProperties', function(result){

    alert(result);

    });

    2.4、直接GET请求进行调用

    无需任何客户端,只需手工拼接参数进行远程调用,请求URL如下:

    http://127.0.0.1:8080/index.json?method=getSystemProperties&id=3325235235235&params=JTViJTVk

    参数说明:

    method : 方法名

    params :调用参数,json的数组格式[], 将参数需先进行url编码,再进行base64编码

    id : 调用标识符,任意值。

    三、JSON-RPC总结

    json-rpc是一种非常轻量级的跨语言远程调用协议,实现及使用简单。仅需几十行代码,即可实现一个远程调用的客户端,方便语言扩展客户端的实现。服务器端有php、java、python、ruby、.net等语言实现,是非常不错的及轻量级的远程调用协议。

    参考文档

    http://code.google.com/p/jsonrpc4j/

    http://json-rpc.org/wiki/implementations

    http://en.wikipedia.org/wiki/JSON-RPC

    https://github.com/gimmi/jsonrpcjs

    http://bitbucket.org/jbg/php-json-rpc

    https://github.com/Pozo/json-rpc-php

    https://github.com/subutux/json-rpc2php

    -------------------------------------------------------------

    一、JSON-RPC-Java简介
            JSON-RPC-Java是一个用Java来实现动态JSON-RPC的框架. 利用它内置的一个轻级量JSON-RPC JavaScripIt客户端,可以让你透明地在JavaScript中调用Java代码。JSON-RPC-Java可运行在Servlet容器中如Tomcat也可以运行在JBoss与其它J2EE应用服务器中因此可以在一个基于JavaScript与DHTML的Web应用程序中利用它来直接调用普通Java方法与EJB方法。我们可以很方便的使用JSON-RPC-Java来开发我的们Ajax应用。
    二、JSON-RPC-Java实践
    1、从http://oss.metaparadigm.com/jsonrpc/download.html下载最新稳定版的JSON-RPC-Java框架并解压。新建一个JavaWeb工程,将jsonrpc-1.0.jar放到/webroot/WEB-INF/lib目录下,将jsonrpc.js放在/webroot下的任意目录下,保证在jsp页面可以引用即可。
     2、修改/webroot/WEB-INF/web.xml文件,添加以下代码:

     1<servlet>
     2        <servlet-name>JSONRPCServlet</servlet-name>
     3        <servlet-class>
     4            com.metaparadigm.jsonrpc.JSONRPCServlet
     5        </servlet-class>
     6    </servlet>
     7    <servlet-mapping>
     8        <servlet-name>JSONRPCServlet</servlet-name>
     9        <url-pattern>/JSON-RPC</url-pattern>
    10    </servlet-mapping>

    当然这里代码不一定要和上面一模一样,有一点基础即可看出这里只是添加了一个Servlet配置而,只要符合Servlet的配置规则即可。 
    3、编Java文件。
            Example.java 此文件提供各种业务操作,此方件编写没有什么特别的要求。但为了在JSP页面用标签,我们最好提供一个无参的构造方法。


     1package net.vicp.jiasoft;
     2
     3import java.io.Serializable;
     4import java.util.List;
     5import java.util.Map;
     6import java.util.Set;
     7
     8public class Example implements Serializable {
     9    private final static long serialVersionUID = 1L;
    10    
    11    public String sayString(String name) {
    12        return "Hello " + name + " !";
    13    }
    14
    15    public List sayList(List list) {
    16        list.add(new Integer(6));
    17        return list;
    18    }
    19    
    20    public Map sayMap (Map map) {
    21        map.put("age","23");
    22        return map;
    23    }
    24    
    25    public Set saySet (Set set) {
    26        set.add("sex");
    27        return set;
    28    }
    29    
    30    public User sayUser (User user) {
    31        user.setAge(25);
    32        return user;
    33    }
    34}


            User.java 此文件用于自定义数据类型传输数。要求是一个javabean,即要为每一个属性提供set和get方法,还有一个无参的构方法即可。


     1package net.vicp.jiasoft;
     2
     3import java.io.Serializable;
     4
     5public class User implements Serializable {
     6    private String name;
     7    private int age;
     8    public int getAge() {
     9        return age;
    10    }
    11    public void setAge(int age) {
    12        this.age = age;
    13    }
    14    public String getName() {
    15        return name;
    16    }
    17    public void setName(String name) {
    18        this.name = name;
    19    }
    20}


    4、编写javascript文件。
            Example.js 用于此处理客户端操作。


     1//The javascript file of the JSON-RPC-Java example application.
     2var jsonrpc = null;
     3//初始化JSONRpcClient对象
     4function onLoad() {
     5    jsonrpc = new JSONRpcClient("JSON-RPC");
     6}
     7//提交普通的字符串对象
     8function sayString() {
     9    var who = document.getElementById("who");
    10    var result = jsonrpc.hello.sayString(cbString, who.value);
    11}
    12function cbString(result, exception) {
    13    if (exception == null) {
    14        document.getElementById("say").innerHTML = "<em>操作提示:提交一个字符串并返回.</em><h2>" + result + "</h2><hr/>";
    15    } else {
    16        alert(exception.message);
    17    }
    18}
    19
    20//提交一个list对象并且将其返回
    21function sayList() {
    22    var list = {"javaClass":"java.util.ArrayList", "list":[1, 2, 3]};
    23    jsonrpc.hello.sayList(cbList, list);
    24}
    25function cbList(result, exception) {
    26    if (exception == null) {
    27        var list = result.list;
    28        var str = "<em>操作提示:提交一个List并返回.</em>";
    29        for (var value in list) {
    30            str += "<h2>list[" + value + "]=" + list[value] + "</h2><hr/>";
    31        }
    32        document.getElementById("say").innerHTML = str;
    33    //"list"可以直接用下面的语句输出
    34    //document.getElementById("say").innerHTML = "<h2>" + list + "</h2>";
    35    } else {
    36        alert(exception.message);
    37    }
    38}
    39
    40//提交一个map对象并且将其返回
    41function sayMap() {
    42    var map = {"javaClass":"java.util.HashMap", "map":{"name":"Huaxu", "sex":"u7537"}};
    43    jsonrpc.hello.sayMap(cbMap, map);
    44}
    45function cbMap(result, exception) {
    46    if (exception == null) {
    47        var map = result.map;
    48        var str = "<em>操作提示:提交一个Map并返回.</em>";
    49        for (var key in map) {
    50            str += "<h2>" + key + ":" + map[key] + "</h2><hr/>";
    51        }
    52        document.getElementById("say").innerHTML = str;
    53    } else {
    54        alert(exception.message);
    55    }
    56}
    57
    58//提交一个set对象并且将其返回
    59function saySet() {
    60    //set属性是一个数组对象,每个数组元素就是set里的一个元素.
    61    var set = {"javaClass":"java.util.HashSet", "set":{"name":"name"}};
    62    jsonrpc.hello.saySet(cbSet, set);
    63}
    64function cbSet(result, exception) {
    65    if (exception == null) {
    66        var set = result.set;
    67        var str = "<em>操作提示:提交一个Set并返回.</em>";
    68        for (var value in set) {
    69            str += "<h2>" + value + "</h2><hr/>";
    70        }
    71        document.getElementById("say").innerHTML = str ;
    72    } else {
    73        alert(exception.message);
    74    }
    75}
    76
    77//提交一个自定义的User对象并且将其返回
    78function sayUser() {
    79    //每个JSON对象属性对应一个User对象属性.
    80    var user = {"javaClass":"net.vicp.jiasoft.User", "name":"Huaxu", "age":23};
    81    jsonrpc.hello.sayUser(cbUser, user);
    82}
    83function cbUser(user, exception) {
    84    if (exception == null) {
    85        var str = "<em>操作提示:提交一个自定义的User对象并返回.</em><h2>name:" + user.name + "</h2><hr/>" + "<h2>age:" + user.age + "</h2><hr/>";
    86        document.getElementById("say").innerHTML = str ;
    87    } else {
    88        alert(exception.message);
    89    }
    90}
    91


    此文件中的jsonrpc.hello.say*()方法即是在Example.java中定义的。
    4、编写jsp页面。
            json.jsp 这个文件做什么不用说了吧,当然给用户一个操作的介面了。


     1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
     2 "http://www.w3.org/TR/html4/loose.dtd">
     3<%@ page contentType="text/html; charset=UTF-8"%>
     4<!-- 此处在session作用域中放入一个名为"JSONRPCBridge"的"com.metaparadigm.jsonrpc.JSONRPCBridge"对象,要注意的是名字一定要为"JSONRPCBridge",否可能出错! -->
     5<jsp:useBean id="JSONRPCBridge" scope="session"
     6    class="com.metaparadigm.jsonrpc.JSONRPCBridge" />
     7<jsp:useBean id="hello" scope="session" class="net.vicp.jiasoft.Example" />
     8<%
     9//此处将上面实例化的"net.vicp.jiasoft.Example"对象注册到"JSONRPCBridge"属性中,这样做即把服器端的方法暴露给客户端了,所以在Example.js中可以用jsonrpc.hello.say*()的方式调用"Example.java"类的方法。
    10JSONRPCBridge.registerObject("hello", hello);
    11%>
    12<html>
    13    <head>
    14        <title>JSON-RPC-Java Example by Huaxu</title>
    15        <script type="text/javascript" src="example.js"></script>
    16        <script type="text/javascript" src="jsonrpc.js"></script>
    17    </head>
    18    <style>
    19        em{
    20            color: red;
    21        }
    22    </style>
    23    <body bgcolor="#ffffff" onLoad="onLoad()">
    24        <center>
    25            <h2>
    26                JSON-RPC-Java Example by Huaxu
    27            </h2>
    28            <p>
    29                The JSON-RPC-Java
    30                <em>Example</em> application .
    31            </p>
    32            <p>
    33                <strong>Who:</strong>
    34                <input type="text" id="who" size="30" value="Huaxu" />
    35                <br />
    36                <br />
    37                <input type="button" value="Say String" onclick="sayString()" />
    38                <input type="button" value="Say List" onclick="sayList()" />
    39                <input type="button" value="Say Map" onclick="sayMap()" />
    40                <input type="button" value="Say Set" onclick="saySet()" />
    41                <input type="button" value="Say User" onclick="sayUser()" />
    42            <hr />
    43            </p>
    44            <div id="say" style=" 400px">
    45            </div>
    46        </center>
    47    </body>
    48</html>
    49


    源码下载:JsonRpcExample 

  • 相关阅读:
    C++自定义异常类
    上下栏固定, 中间滚动的HTML模板
    C# 代理应用
    C# 对象池的实现(能限制最大实例数量,类似于WCF的MaxInstanceCount功能)
    半同步半异步模式的实现
    EventBus实现
    C Socket初探
    C Socket初探
    VC++全屏
    MFC 坦克定位
  • 原文地址:https://www.cnblogs.com/fx2008/p/4086508.html
Copyright © 2011-2022 走看看