1. 程式人生 > >Hessian學習之(一):簡單測試 + C#呼叫Java服務

Hessian學習之(一):簡單測試 + C#呼叫Java服務

開始調研Hessian和Mina,目的是希望能夠建立一個簡單的“高效能分散式服務呼叫框架”!類似於Dubbo或者淘寶的HSF那種,但是是要跨平臺的,而不僅僅侷限在Java領域。

hessian是一種遠端呼叫的機制(RPC) ,類似於web service,不過它是使用自己的序列化協議(二進位制序列化)。淘寶的HSF高效能服務框架中兩臺機器通訊用到的序列化技術就是Hessian的,它的內部實現就是基於Hessian和Mina,這裡是幾篇關於Hessian原始碼解析的文章可以參考。

基於Hessian的遠端呼叫協議。

  • 連線個數:多連線
  • 連線方式:短連線
  • 傳輸協議:HTTP
  • 傳輸方式:同步傳輸
  • 序列化:Hessian二進位制序列化
  • 適用範圍:傳入傳出引數資料包較大,提供者比消費者個數多,提供者壓力較大,可傳檔案。
  • 適用場景:頁面傳輸,檔案傳輸,或與原生hessian服務互操作

約束:

  • 引數及返回值需實現Serializable介面
  • 引數及返回值不能自定義實現List, Map, Number, Date, Calendar等介面,只能用JDK自帶的實現,因為hessian會做特殊處理,自定義實現類中的屬性值都會丟失。

這裡我們主要先講一下如果利用Hessian實現RPC:

(一)Java客戶端呼叫Java服務:

3 建立Dynamic Web Project,記得Target Runtime選擇Tomcat,最後記得勾選上生成Web.xml

4 引入hessian的jar檔案

5 伺服器端開發: 

(1)建立介面以及實現類:

package com.jiq.hessian;
/**
 * 
 */

/**
 * @author Think
 *
 */
public interface IHelloService {
	public String SayHello();
}
package com.jiq.hessian;


//import com.caucho.hessian.server.HessianServlet;
/**
 * @author Think
 *
 */
public class HelloService implements IHelloService{

	public String SayHello()
	{
		return "hello, Hessian!";		
	}
}

(2)配置Web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>WebProjTest</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>     
        <servlet-name>hello</servlet-name>     
        <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>     
        <init-param>     
            <param-name>service-class</param-name>
            <param-value>com.jiq.hessian.HelloService</param-value>     
        </init-param>
        <init-param>     
            <param-name>home-api</param-name>     
            <param-value>com.jiq.hessian.IHelloService</param-value>     
        </init-param>
  </servlet>     
         
  <servlet-mapping>     
      <servlet-name>hello</servlet-name>     
      <url-pattern>/hello</url-pattern>
  </servlet-mapping> 
</web-app>

(3)編寫一個測試用的JSP:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ page import="com.caucho.hessian.client.HessianProxyFactory"  %>
<%@ page import="com.jiq.hessian.IHelloService" %>

<%
	HessianProxyFactory factory = new HessianProxyFactory();
	String url = "http://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/hello";
	IHelloService proxy = (IHelloService)factory.create(IHelloService.class, url);
	out.print(proxy.SayHello());
%>

在view中開啟servers試圖,空白處右擊,建立server,選擇你的tomcat(我選擇的是tomcat 7),然後add你的工程,啟動伺服器。

6 客戶端開發:

需要建立一個一模一樣的IHelloService的介面,下面是程式碼:

package com.jiq.test;

import java.net.MalformedURLException;

import com.caucho.hessian.client.HessianProxyFactory;
import com.jiq.hessian.*;

public class HessianTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String url = "http://localhost:8390/WebProjTest/hello"; 
		HessianProxyFactory factory = new HessianProxyFactory(); 
		
		try { 
			IHelloService proxy =(IHelloService)factory.create(IHelloService.class, url); 
			System.out.println(proxy.SayHello()); 
		} catch (MalformedURLException e) { 
		e.printStackTrace(); 
		} 
	}

}

右擊,執行,可以看到期望輸出。

這裡是我提供的原始碼下載: 下載地址是我export為Archive file的。

(二)C#客戶端呼叫Java服務:

(1)引入Hessiancsharp.dll;

(2)編寫一個介面IHelloService,和Java服務端的一樣(類似WCF中的契約):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NETHessianTest
{
    interface IHelloService
    {
        string SayHello();
    }
}


(3)編寫測試程式碼:

namespace NETHessianTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = @"http://192.168.1.100:80/WebProjTest/hello";
            CHessianProxyFactory factory = new CHessianProxyFactory();

            IHelloService proxy = (IHelloService)factory.Create(typeof(IHelloService), url);
            Console.WriteLine(proxy.SayHello());
            Console.ReadKey();
        }
    }
}

這就OK了,但是我不知道為什麼呼叫很慢很慢,有待繼續深入。

這裡是.NET客戶端測試工程下載,裡面有Hessiancsharp.dll

(三)關於DataTable的返回:

接下來最關鍵的就是,以前C#開發都是WCF來請求服務,一般查詢資料庫都會返回DataSet,裡面包含了DataTable,那麼Java服務查詢了資料庫之後,怎麼返回資料(結果集)給C#的客戶端呢?Java又沒有DataSet或者DataTable,我大概有兩個思路,不過還沒有親自嘗試:

(1)自己模擬一個DataTable物件:

大概像這樣:

A workaround I've used is JTable. It doesn't have the robust data features of a proper DataTable but it will allow you grab some data and bind it to a control with some structure.

class TableModel extends AbstractTableModel
{
    String[] columnNames = {“FirstName”,”LastName”,”Title”};
    Object[][] rowData= {{‘John,”Smith”,”President”},{“John”,”Doe”,”Employee”}};

    public int getColumnCount()
    {
        return columnNames.length;
    }

    public int getRowCount()
    {
        return rowData.length;
    }

    public String getColumnName(int col)
    {
        return columnNames[col];
    }

    public Object getValueAt(int row, int col)
    {
        return data[row][col];
    }
}
And then to use you simply:

JTable table = new JTable(new TableModel());
Again, this is quick and simple and if you are dealing with large amounts of data I would recommend using a proper ORM tool.

share|improve this answer
answered Jun 17 '11 at 18:14

Menefee
192111
add comment
up vote
0
down vote
From Standard Library DefaultTableModel is good class.

ResultSet set = s.getResultSet();
        ResultSetMetaData metaData = set.getMetaData();
        int totalColumn = metaData.getColumnCount();
        Object[] dataRow = new Object[totalColumn];
        if(set!= null)
        {
            for(int i=1;i<=totalColumn;i++)
            {
                table.addColumn(metaData.getColumnName(i));
            }
            while(set.next())
            {
                for(int i=1;i<=totalColumn;i++)
                {
                    dataRow[i-1] = set.getObject(i);
                }
                table.addRow(dataRow);
            }

        }
但是很明顯,這樣查了資料之後,還要在拷貝到自定義物件中,效能上有所瑕疵。


(2) 使用ORM,即實體關係對映。

採用實體關係對映,比如Hibernate之後,java查詢資料庫直接返回List<Object>,就可以直接返回給C#客戶端了。

以上只是我的兩個想法,有待驗證,或者有更好的方法請大家不吝賜教,謝謝!!!

相關推薦

Hessian學習簡單測試 + C#呼叫Java服務

開始調研Hessian和Mina,目的是希望能夠建立一個簡單的“高效能分散式服務呼叫框架”!類似於Dubbo或者淘寶的HSF那種,但是是要跨平臺的,而不僅僅侷限在Java領域。 hessian是一種遠端呼叫的機制(RPC) ,類似於web service,不過它是使用自己

STM32F103學習筆記簡單的按鍵程式

通過幾個按鍵,來控制LED燈的開關狀態。沒有涉及到中斷,只是簡單的按鍵程式 程式包括key.c,key.h;led.c,led.h;以及main函式 一、LED程式 led.h #ifndef __LED__H #define __LED__H #include "

網路遊戲《叢林戰爭》開發與學習網路程式設計的基礎知識

《叢林戰爭》是一款完整的網路遊戲案例,運用U3D開發客戶端,Socket開發服務端,其中涉及到了網路程式設計、資料庫和Unity的功能實現,之前通過U3D開發了一個單機遊戲《黑暗之光》,並沒有涉及網路程式設計的知識,通過《叢林戰爭》這個完整的遊戲,系統性地學習網路程式設計,並

淺談單元測試單元測試的意義

單元測試是檢查一個獨立工作單元的行為。在JAVA應用程式中,獨立工作單元經常是(但不總是)一個獨立的方法。相比之下,整合測試和驗收測試檢查的是各種元件如何互動。一個工作單元就是一項任務,不直接依賴於其

網路遊戲《叢林戰爭》開發與學習粘包分包現象以及服務端解析資料

1. 粘包和分包 粘包和分包是利用Socket在TCP協議下內部的優化機制。粘包指的是傳送資料比較頻繁,但資料量較少,此時客戶端不會直接將資料包傳送給伺服器,而是會與其它的資料包進行一個結合,例如遊戲中的位置資訊就是屬於頻繁傳送但資料量小的資訊,此時如果每條資料都S

C#可擴展編程MEF學習筆記MEF簡介及簡單的Demo

com ring this exec hosting code .cn 引用 展開 在文章開始之前,首先簡單介紹一下什麽是MEF,MEF,全稱Managed Extensibility Framework(托管可擴展框架)。單從名字我們不難發現:MEF是專門致力於解決擴展性

Unity3D學習簡單梳理下Unity跨平臺的機制原理

12px get 一個 bsp 嵌入 ram 屬於 開源 runtime 前言 首先需要了解的是,Unity3D的C#基礎腳本模塊是通過Mono來實現的。 什麽是Mono? 參考下百度百科:Mono是一個由Novell公司(由Xamarin發起)主持的項目,並由Migu

Django學習筆記環境安裝與簡單實例

rom dex ftime not host 名稱 本機 turn perl Django學習筆記(一):環境安裝與簡單實例 通過本文章實現: Django在Windows中的環境安裝 Django項目的建立並編寫簡單的網頁,顯示歡迎語與當前時間 一、環境安裝 結合版

Spring學習筆記眼見為實,先上一個簡單例子

概述 所謂眼見為實,Spring雖然是一個輕量級的框架,但涉及眾多的概念,理解起來並不容易,因此,先參考資料寫一個簡單的Demo,從中洞見Spring的大體工作流程,為後面深入學習做鋪墊。 本文的Demo很簡單:模擬圖書資料訪問服務,即向資料庫中新增圖書資訊,涉及IBoo

各種音視訊編解碼學習詳解 編解碼學習筆記基本概念

最近在研究音視訊編解碼這一塊兒,看到@bitbit大神寫的【各種音視訊編解碼學習詳解】這篇文章,非常感謝,佩服的五體投地。奈何大神這邊文章太長,在這裡我把它分解很多小的篇幅,方便閱讀。大神部落格傳送門:https://www.cnblogs.com/skyofbitbit/p/3651270.htm

MongoDB 學習筆記安裝及簡單shell操作

一、說明 1、該系列MongoDB學習筆記的學習環境採用的MongoDB版本為mongodb-win32-i386-2.4.6,作業系統為win7。 二、安裝 1、新建兩個目錄,分別是D:\Installations\MongoDB-2.4.6\MongoDB和D:\Ins

一站式學習WiresharkWireshark基本用法

11g 實現 alt href ascii 根據 無線網絡 完成 analyze 按照國際慣例,從最基本的說起。 抓取報文: 下載和安裝好Wireshark之後,啟動Wireshark並且在接口列表中選擇接口名,然後開始在此接口上抓包。例如,如果想要在無線網絡上抓取流量

HLSL學習筆記基礎

pad ddx 做了 cto har 分割 with 圖形 content http://www.cnblogs.com/rainstorm/archive/2013/05/04/3057444.html 前言 五一在家無事,於是學習了一下HLSL,基於XAN4.0的。學習

Tomcat學習筆記一個簡單的Web服務

sub 調用 [] ont 拒絕 address 剖析 文件 getprop 內容為《深入剖析Tomcat》第一章重點,以及自己的總結,如有描述不清的,可查看原書。 一、HTTP協議: 1、定義:用於服務器與客戶端的通訊的協議,允許web服務器和瀏覽器通過互聯網進行發送和接

EF6 學習筆記Code First 方式生成數據庫及初始化數據庫實際操作

view sqlserver 4.5 xpl 安裝 右鍵 ef6 字符串 ref 參考原文地址: https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-wit

Servlet學習筆記生命周期

磁盤 停止 生命 第一個 每一個 clas 瀏覽器 doget des 一、Servlet 生命周期:   Servlet 生命周期可被定義為從創建直到毀滅的整個過程。以下是 Servlet 遵循的過程:初始化——響應請求——終止——回收 Servlet 通過調用 in

JSP學習筆記JSP語法和指令

沒有 文件的 encoding 引入 2.0 .cn name blog .get 一、語法 1、腳本程序的語法格式:   腳本程序可以包含任意量的Java語句、變量、方法或表達式,只要它們在腳本語言中是有效的。 <% 代碼片段 %> 2、中文編碼問題   

Linux kernel的中斷子系統綜述

lock www. api cdc 電平 還需 結構 現在 ces 一、前言一個合格的linux驅動工程師需要對kernel中的中斷子系統有深刻的理解,只有這樣,在寫具體driver的時候才能:1、正確的使用linux kernel提供的的API,例如最著名的request

Docker學習系列windows下安裝docker

阻止 statistic pro nta 雙擊 copyright ner notebook 現在 本文目錄如下: windows按照docker的基本要求 具體安裝步驟 開始使用 安裝遠程連接工具連接docker 安裝中遇到的問題 Docker的更新 Dock

一起學習Rviz——顯示簡單立體模型

edit ide tutorials setup tutorial 添加 tar dev als 先甩個鍋咯,手敲下來的難免有些小錯誤,錯別字啥的,理解哈~~~ Ubuntu 14.04,ROS版本 indigo 1、Rviz顯示簡單立體模型 首先,創建工作空間。 創建文件