【JSON-RPC】JSON-RPC轻量级远程调用协议介绍和使用其进行接口测试

目录

  • 前言
  • 协议简述
    • 一、JSON-RPC协议描述
  • 使用JSON-RPC进行接口下发
    • 一、maven配置
    • 二、工具类书写

前言

之前使用java做接口测试,均使用HttpClient来进行,今次遇到一个新的项目使用python的odoo框架开发,其接口和之前的网站稍有不同,导致在前台看到的接口返回内容和之前的差别很大,一般的restful接口在控制台里是这样的:
【JSON-RPC】JSON-RPC轻量级远程调用协议介绍和使用其进行接口测试_第1张图片
而现项目的控制台显示如下:
【JSON-RPC】JSON-RPC轻量级远程调用协议介绍和使用其进行接口测试_第2张图片
这种参数用通用的HttpClient就不好进行接口下发了,这只是个比较简单的参数,实际上args里还有可能包含字符串列表等类型,故采用JSONRPC的java版进行接口下发就比较方便;

协议简述

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

一、JSON-RPC协议描述

son-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进行接口下发

JSON-RPC的java版配置比httpClient要简单很多,不需要管理连接、连接池、关闭返回等等,甚至连下发方式都略掉了。
maven地址
源码地址

一、maven配置

这里jsonrpc就一个包,另外一个用于json字符串处理;

<dependency>
      <groupId>com.github.briandilley.jsonrpc4jgroupId>
      <artifactId>jsonrpc4jartifactId>
      <version>1.5.2version>
	dependency>
    <dependency>
	  <groupId>com.alibabagroupId>
	  <artifactId>fastjsonartifactId>
	  <version>1.2.41version>
    dependency>

二、工具类书写

jsonrpc工具类代码如下

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.googlecode.jsonrpc4j.JsonRpcHttpClient;

public class JsonRpcUtil {

	private static final Logger log = LoggerFactory.getLogger(JsonRpcUtil.class);
	
	public static final String RPC_ACTION = "method";
	/**
	 * 单例模式
	 */
	private static JsonRpcUtil rpcUtil=new JsonRpcUtil();
	
	/**获得工具实例
	 * @return
	 */
	public static JsonRpcUtil getRpcUtil() {
		return rpcUtil;
	}

	private JsonRpcHttpClient rpcClient;

	/**设置headper
	 * @param url
	 * @param headers
	 * @return
	 * @throws MalformedURLException
	 */
	public JsonRpcUtil setHeaders(String url, Map<String, String> headers) throws MalformedURLException {
		rpcClient = new JsonRpcHttpClient(new URL(url));
		if (null != headers && headers.size() > 0) 
		{
			rpcClient.setHeaders(headers);
		} 
		return this;
	}

	/**远程调用
	 * @param action
	 * @param argument
	 * @param returnClass
	 * @return
	 * @throws Throwable
	 */
	public <T> T execute(String action, Object argument, Class<T> returnClass) throws Throwable {
		return this.rpcClient.invoke(action, argument, returnClass);
	}
	
	/**
	 * 远程过程调用
	 * 
	 * @param url 接口url
	 * @param headers 要加入的header
	 * @param argument 此处为浏览器控制台里参数里的params的值
	 * @param returnClass 返回值类型
	 * @return
	 * @throws MalformedURLException
	 * @throws Throwable
	 */
	public <T> T rpcExecute(String url, Map<String, String> headers, Object argument, Class<T> returnClass)
			throws MalformedURLException, Throwable {
		try {
			return JsonRpcUtil.getRpcUtil().setHeaders(url, headers).execute(RPC_ACTION, argument, returnClass);
		} finally {
			log.debug("api url:" + url);
			log.debug("api header:" + JsonUtil.ParseJson(headers));
			log.debug("api params:" + JsonUtil.ParseJson(argument));
			//this.clearParas();
		}
	}
	
}

json处理工具类:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature;

public class JsonUtil {
	public static String ParseJson(Object obj) {
		return JSON.toJSONString(obj);
	}

	public static <T> T parseObject(String json,Class<T> clas) {  
		return (T)JSON.parseObject(json, clas) ;  
	}
	
	public static <T> T parseObject(String json, TypeReference<T> type, Feature... features){
		return (T)JSON.parseObject(json, type,features) ; 
		
	}
}

调用的时候需要取控制台里的Request URL作为参数url的值传入;取Request Payload中params的值使用json转换为Object作为工具调用里的agument传入(或者也可以转换为Map),headers依然为Map,按需要传入即可,至于第四个参数returnClass,则根据具体返回的值的类型来定义,可以为Map.class,或者List.class等,如果不知道则直接传入Object.class即可,返回值根据这个参数来定义;
如下是个简单的调用范例:

public static void main(String[] args)
{
    String url = "http://127.0.0.1:8080/web/test";
    String param = "{ \"method\": \"sayHello\", \"args\": [\"Hello JSON-RPC\"]}";
    Map<String,Object> returnValue = JsonRpcUtil.rpcExecute(url,null,JsonUtil.parseObject(param,Object.class),Map.class);
 }

你可能感兴趣的:(接口测试,http协议,JSON-RPC)