導航:首頁 > 編程語言 > 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連接相關的資料

熱點內容
c語言12位的數據應該怎麼存儲 瀏覽:953
將ape導入iphone 瀏覽:107
js組合快捷鍵 瀏覽:174
linux系統盤默認掛在的文件夾 瀏覽:667
淘寶數據包如何操作上架 瀏覽:567
vb編程中輸入cls是什麼意思 瀏覽:81
linuxtime服務 瀏覽:184
瘋狂安卓講義第二版代碼 瀏覽:420
老炮兒三小時版本下載 瀏覽:313
matlab怎麼調試程序 瀏覽:2
winxp升級win7的危害 瀏覽:496
網路沒連上卻不可用是怎麼回事 瀏覽:752
社區版本 瀏覽:738
怎麼查微信公眾號什麼時候開通的 瀏覽:717
安裝三菱編程閃退怎麼回事 瀏覽:488
手機怎麼創建word文件格式 瀏覽:694
c語言連接資料庫 瀏覽:887
數據線粉色和白色哪個是正 瀏覽:775
vb編程應注意什麼 瀏覽:855
js循環添加控制項 瀏覽:615

友情鏈接