RPC实践(二)JsonRPC实践

一、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的主要内容,就是创建一个服务端对象,由客户端进行调用

对象关系

对象关系图如下:

RPC实践(二)JsonRPC实践_第1张图片

3.1工程搭建

1) 创建一个web projcct工程

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

RPC实践(二)JsonRPC实践_第2张图片

3)发布,并运行tomcat

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

RPC实践(二)JsonRPC实践_第3张图片

 注意: 最后的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 ++++++
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¶ms=JTViJTVk

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

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


服务端打印

JsonRpcService service being call
do something; count=>3

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

用get方法:

RPC实践(二)JsonRPC实践_第4张图片

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

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


用post 方法:

RPC实践(二)JsonRPC实践_第5张图片

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

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

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

RPC实践(二)JsonRPC实践_第6张图片















你可能感兴趣的:(JAVA,RPC)