导航:首页 > 编程语言 > jsonrpc连接

jsonrpc连接

发布时间:2024-05-04 08:40:51

Ⅰ 使用json-rpc规范交换数据,server用jsonRPCServer.php写的,在client用java做,怎么获取json数据

/**

* Copyright (c) linkwise 2007-2009 corporation.

* All rights reserved

*/

package com.linghui.common.util;

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import net.sf.json.JSONArray;

import net.sf.json.JSONObject;

import net.sf.json.JsonConfig;

import net.sf.json.util.CycleDetectionStrategy;

import com.linghui.common.util.DateUtil;

import com.linghui.common.util.jsonutil.DateJsonValueProcessor;

/**

*

*/

public class JsonUtil {

/**

* 从一个JSON 对象字符格式中得到一个java对象

* @param jsonString

* @param pojoCalss

* @return

*/

public static Object getObject4JsonString(String jsonString,Class pojoCalss){

Object pojo;

JSONObject jsonObject = JSONObject.fromObject( jsonString );

pojo = JSONObject.toBean(jsonObject,pojoCalss);

return pojo;

}

/**

* 从json HASH表达式中获取一个map,改map支持嵌套功能

* @param jsonString

* @return

*/

public static Map getMap4Json(String jsonString){

JSONObject jsonObject = JSONObject.fromObject( jsonString );

Iterator keyIter = jsonObject.keys();

String key;

Object value;

Map valueMap = new HashMap();

while( keyIter.hasNext())

{

key = (String)keyIter.next();

value = jsonObject.get(key);

valueMap.put(key, value);

}

return valueMap;

}

/**

* 从json数组中得到相应java数组

* @param jsonString

* @return

*/

public static Object getObjectArray4Json(String jsonString){

JSONArray jsonArray = JSONArray.fromObject(jsonString);

return jsonArray.toArray();

}

/**

* 从json对象集合表达式中得到一个java对象列表

* @param jsonString

* @param pojoClass

* @return

*/

public static List getList4Json(String jsonString, Class pojoClass){

JSONArray jsonArray = JSONArray.fromObject(jsonString);

JSONObject jsonObject;

Object pojoValue;

List list = new ArrayList();

for ( int i = 0 ; ijsonArray.size(); i++){

jsonObject = jsonArray.getJSONObject(i);

pojoValue = JSONObject.toBean(jsonObject,pojoClass);

list.add(pojoValue);

}

return list;

}

/**

* 从json数组中解析出java字符串数组

* @param jsonString

* @return

*/

public static String getStringArray4Json(String jsonString){

JSONArray jsonArray = JSONArray.fromObject(jsonString);

String stringArray = new String[jsonArray.size()];

for( int i = 0 ; ijsonArray.size() ; i++ ){

stringArray[i] = jsonArray.getString(i);

}

return stringArray;

}

/**

* 从json数组中解析出javaLong型对象数组

* @param jsonString

* @return

*/

public static Long getLongArray4Json(String jsonString){

JSONArray jsonArray = JSONArray.fromObject(jsonString);

Long longArray = new Long[jsonArray.size()];

for( int i = 0 ; ijsonArray.size() ; i++ ){

longArray[i] = jsonArray.getLong(i);

}

return longArray;

}

/**

* 从json数组中解析出java Integer型对象数组

* @param jsonString

* @return

*/

public static Integer getIntegerArray4Json(String jsonString){

JSONArray jsonArray = JSONArray.fromObject(jsonString);

Integer integerArray = new Integer[jsonArray.size()];

for( int i = 0 ; ijsonArray.size() ; i++ ){

integerArray[i] = jsonArray.getInt(i);

}

return integerArray;

}

/**

* 从json数组中解析出java Date 型对象数组,使用本方法必须保证

* @param jsonString

* @return

*/

public static Date getDateArray4Json(String jsonString,String DataFormat){

JSONArray jsonArray = JSONArray.fromObject(jsonString);

Date dateArray = new Date[jsonArray.size()];

String dateString;

Date date;

for( int i = 0 ; ijsonArray.size() ; i++ ){

dateString = jsonArray.getString(i);

date = DateUtil.stringToDate(dateString, DataFormat);

dateArray[i] = date;

}

return dateArray;

}

/**

* 从json数组中解析出java Integer型对象数组

* @param jsonString

* @return

*/

public static Double getDoubleArray4Json(String jsonString){

JSONArray jsonArray = JSONArray.fromObject(jsonString);

Double doubleArray = new Double[jsonArray.size()];

for( int i = 0 ; ijsonArray.size() ; i++ ){

doubleArray[i] = jsonArray.getDouble(i);

}

return doubleArray;

}

/**

* 将java对象转换成json字符串

* @param javaObj

* @return

*/

public static String getJsonString4JavaPOJO(Object javaObj){

JSONObject json;

json = JSONObject.fromObject(javaObj);

return json.toString();

}

/**

* 将java对象转换成json字符串,并设定日期格式

* @param javaObj

* @param dataFormat

* @return

*/

public static String getJsonString4JavaPOJO(Object javaObj , String dataFormat){

JSONObject json;

JsonConfig jsonConfig = configJson(dataFormat);

json = JSONObject.fromObject(javaObj,jsonConfig);

return json.toString();

}

/**

* @param args

*/

public static void main(String args) {

// TODO 自动生成方法存根

}

/**

* JSON 时间解析器具

* @param datePattern

* @return

*/

public static JsonConfig configJson(String datePattern) {

JsonConfig jsonConfig = new JsonConfig();

jsonConfig.setExcludes(new String{""});

jsonConfig.setIgnoreDefaultExcludes(false);

jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);

jsonConfig.registerJsonValueProcessor(Date.class,

new DateJsonValueProcessor(datePattern));

return jsonConfig;

}

/**

*

* @param excludes

* @param datePattern

* @return

*/

public static JsonConfig configJson(String excludes,

String datePattern) {

JsonConfig jsonConfig = new JsonConfig();

jsonConfig.setExcludes(excludes);

jsonConfig.setIgnoreDefaultExcludes(false);

jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);

jsonConfig.registerJsonValueProcessor(Date.class,

new DateJsonValueProcessor(datePattern));

return jsonConfig;

}

}

/**

* linkwise

*/

package com.linghui.common.util.jsonutil;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Date;

import net.sf.json.JsonConfig;

import net.sf.json.processors.JsonValueProcessor;

/**

* @author robert.feng

*

*/

public class DateJsonValueProcessor implements JsonValueProcessor {

public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";

private DateFormat dateFormat;

/**

* 构造方法.

*

* @param datePattern 日期格式

*/

public DateJsonValueProcessor(String datePattern) {

if( null datePattern )

dateFormat = new SimpleDateFormat(DEFAULT_DATE_PATTERN);

else

dateFormat = new SimpleDateFormat(datePattern);

}

/* (非 Javadoc)

* @see net.sf.json.processors.JsonValueProcessor#processArrayValue(java.lang.Object, net.sf.json.JsonConfig)

*/

public Object processArrayValue(Object arg0, JsonConfig arg1) {

// TODO 自动生成方法存根

return process(arg0);

}

/* (非 Javadoc)

* @see net.sf.json.processors.JsonValueProcessor#processObjectValue(java.lang.String, java.lang.Object, net.sf.json.JsonConfig)

*/

public Object processObjectValue(String arg0, Object arg1, JsonConfig arg2) {

// TODO 自动生成方法存根

return process(arg1);

}

private Object process(Object value) {

return dateFormat.format((Date) value);

}

}

Ⅱ Dubbo——HTTP 协议 + JSON-RPC

Protocol 还有一个实现分支是 AbstractProxyProtocol,如下图所示:

从图中我们可以看到:gRPC、HTTP、WebService、Hessian、Thrift 等协议对应的 Protocol 实现,都是继承自 AbstractProxyProtocol 抽象类。

目前互联网的技术栈百花齐放,很多公司会使用 Node.js、Python、Rails、Go 等语言来开发 一些 Web 端应用,同时又有很多服务会使用 Java 技术栈实现,这就出现了大量的跨语言调用的需求。Dubbo 作为一个 RPC 框架,自然也希望能实现这种跨语言的调用,目前 Dubbo 中使用“HTTP 协议 + JSON-RPC”的方式来达到这一目的,其中 HTTP 协议和 JSON 都是天然跨语言的标准,在各种语言中都有成熟的类库。

下面就重点来分析 Dubbo 对 HTTP 协议的支持。首先,会介绍 JSON-RPC 的基础,并通过一个示例,快速入门,然后介绍 Dubbo 中 HttpProtocol 的具体实现,也就是如何将 HTTP 协议与 JSON-RPC 结合使用,实现跨语言调用的效果。

Dubbo 中支持的 HTTP 协议实际上使用的是 JSON-RPC 协议。

JSON-RPC 是基于 JSON 的跨语言远程调用协议。Dubbo 中的 bbo-rpc-xml、bbo-rpc-webservice 等模块支持的 XML-RPC、WebService 等协议与 JSON-RPC 一样,都是基于文本的协议,只不过 JSON 的格式比 XML、WebService 等格式更加简洁、紧凑。与 Dubbo 协议、Hessian 协议等二进制协议相比,JSON-RPC 更便于调试和实现,可见 JSON-RPC 协议还是一款非常优秀的远程调用协议。

在 Java 体系中,有很多成熟的 JSON-RPC 框架,例如 jsonrpc4j、jpoxy 等,其中,jsonrpc4j 本身体积小巧,使用方便,既可以独立使用,也可以与 Spring 无缝集合,非常适合基于 Spring 的项目。

下面先来看看 JSON-RPC 协议中请求的基本格式:

JSON-RPC请求中各个字段的含义如下:

在 JSON-RPC 的服务端收到调用请求之后,会查找到相应的方法并进行调用,然后将方法的返回值整理成如下格式,返回给客户端:

JSON-RPC响应中各个字段的含义如下:

Dubbo 使用 jsonrpc4j 库来实现 JSON-RPC 协议,下面使用 jsonrpc4j 编写一个简单的 JSON-RPC 服务端示例程序和客户端示例程序,并通过这两个示例程序说明 jsonrpc4j 最基本的使用方式。

首先,需要创建服务端和客户端都需要的 domain 类以及服务接口。先来创建一个 User 类,作为最基础的数据对象:

接下来创建一个 UserService 接口作为服务接口,其中定义了 5 个方法,分别用来创建 User、查询 User 以及相关信息、删除 User:

UserServiceImpl 是 UserService 接口的实现类,其中使用一个 ArrayList 集合管理 User 对象,具体实现如下:

整个用户管理业务的核心大致如此。下面我们来看服务端如何将 UserService 与 JSON-RPC 关联起来。

首先,创建 RpcServlet 类,它是 HttpServlet 的子类,并覆盖了 HttpServlet 的 service() 方法。我们知道,HttpServlet 在收到 GET 和 POST 请求的时候,最终会调用其 service() 方法进行处理;HttpServlet 还会将 HTTP 请求和响应封装成 HttpServletRequest 和 HttpServletResponse 传入 service() 方法之中。这里的 RpcServlet 实现之中会创建一个 JsonRpcServer,并在 service() 方法中将 HTTP 请求委托给 JsonRpcServer 进行处理:

最后,创建一个 JsonRpcServer 作为服务端的入口类,在其 main() 方法中会启动 Jetty 作为 Web 容器,具体实现如下:

这里使用到的 web.xml 配置文件如下:

完成服务端的编写之后,下面再继续编写 JSON-RPC 的客户端。在 JsonRpcClient 中会创建 JsonRpcHttpClient,并通过 JsonRpcHttpClient 请求服务端:

在 AbstractProxyProtocol 的 export() 方法中,首先会根据 URL 检查 exporterMap 缓存,如果查询失败,则会调用 ProxyFactory.getProxy() 方法将 Invoker 封装成业务接口的代理类,然后通过子类实现的 doExport() 方法启动底层的 ProxyProtocolServer,并初始化 serverMap 集合。具体实现如下:

在 HttpProtocol 的 doExport() 方法中,与前面介绍的 DubboProtocol 的实现类似,也要启动一个 RemotingServer。为了适配各种 HTTP 服务器,例如,Tomcat、Jetty 等,Dubbo 在 Transporter 层抽象出了一个 HttpServer 的接口。

bbo-remoting-http 模块的入口是 HttpBinder 接口,它被 @SPI 注解修饰,是一个扩展接口,有三个扩展实现,默认使用的是 JettyHttpBinder 实现,如下图所示:

HttpBinder 接口中的 bind() 方法被 @Adaptive 注解修饰,会根据 URL 的 server 参数选择相应的 HttpBinder 扩展实现,不同 HttpBinder 实现返回相应的 HttpServer 实现。HttpServer 的继承关系如下图所示:

这里以 JettyHttpServer 为例简单介绍 HttpServer 的实现,在 JettyHttpServer 中会初始化 Jetty Server,其中会配置 Jetty Server 使用到的线程池以及处理请求 Handler:

可以看到 JettyHttpServer 收到的全部请求将委托给 DispatcherServlet 这个 HttpServlet 实现,而 DispatcherServlet 的 service() 方法会把请求委托给对应接端口的 HttpHandler 处理:

了解了 Dubbo 对 HttpServer 的抽象以及 JettyHttpServer 的核心之后,回到 HttpProtocol 中的 doExport() 方法继续分析。

在 HttpProtocol.doExport() 方法中会通过 HttpBinder 创建前面介绍的 HttpServer 对象,并记录到 serverMap 中用来接收 HTTP 请求。这里初始化 HttpServer 以及处理请求用到的 HttpHandler 是 HttpProtocol 中的内部类,在其他使用 HTTP 协议作为基础的 RPC 协议实现中也有类似的 HttpHandler 实现类,如下图所示:

在 HttpProtocol.InternalHandler 中的 handle() 实现中,会将请求委托给 skeletonMap 集合中记录的 JsonRpcServer 对象进行处理:

skeletonMap 集合中的 JsonRpcServer 是与 HttpServer 对象一同在 doExport() 方法中初始化的。最后,我们来看 HttpProtocol.doExport() 方法的实现:

介绍完 HttpProtocol 暴露服务的相关实现之后,下面再来看 HttpProtocol 中引用服务相关的方法实现,即 protocolBindinRefer() 方法实现。该方法首先通过 doRefer() 方法创建业务接口的代理,这里会使用到 jsonrpc4j 库中的 JsonProxyFactoryBean 与 Spring 进行集成,在其 afterPropertiesSet() 方法中会创建 JsonRpcHttpClient 对象:

下面来看 doRefer() 方法的具体实现:

在 AbstractProxyProtocol.protocolBindingRefer() 方法中,会通过 ProxyFactory.getInvoker() 方法将 doRefer() 方法返回的代理对象转换成 Invoker 对象,并记录到 Invokers 集合中,具体实现如下:

本文重点介绍了在 Dubbo 中如何通过“HTTP 协议 + JSON-RPC”的方案实现跨语言调用。首先介绍了 JSON-RPC 中请求和响应的基本格式,以及其实现库 jsonrpc4j 的基本使用;接下来我们还详细介绍了 Dubbo 中 AbstractProxyProtocol、HttpProtocol 等核心类,剖析了 Dubbo 中“HTTP 协议 + JSON-RPC”方案的落地实现。

阅读全文

与jsonrpc连接相关的资料

热点内容
5s升级ios92无服务 浏览:354
ubuntu翻译工具 浏览:665
wifi安装教程 浏览:398
苹果有些qq文件打不开 浏览:139
微信分身图片缓存在哪个文件 浏览:544
众筹用什么网站 浏览:1
天马座的幻想版本 浏览:536
微云保存文件图片没有了 浏览:236
如何把excel表格图片导出到文件夹 浏览:387
qq三国快速升级攻略 浏览:660
js监听手机home事件 浏览:439
第2章linux的桌面管理副本 浏览:452
qq邮箱手机上登录微信账号密码错误 浏览:627
编程如何让人物重复发射子弹 浏览:853
db2查看表空间文件 浏览:607
ps文件界面设置 浏览:779
c语言12位的数据应该怎么存储 浏览:953
将ape导入iphone 浏览:107
js组合快捷键 浏览:174
linux系统盘默认挂在的文件夹 浏览:667

友情链接