java和c#使用hessian通信


介紹

hessian主頁:http://hessian.caucho.com/

一個簡單的例子學習hessian服務:服務端為Java,客戶端為C#。

先要准備好C#和Java的第三方類庫:http://hessian.caucho.com/

Hssiancharp.dll

hessian-4.0.37.jar

Hessian服務端(java)

打開eclipse創建一個Dynamic Web Project,將hessian-4.0.37.jar放到lib下,大概如圖所示:

創建一個通信接口IHello:

package hessian.test.server;

import java.util.ArrayList;

public interface IHello {

    String sayHello(String msg);   
    
    void sayHello2(int bean);
    
    void print(String msg);  
    
    HelloBean getData(HelloBean bean);
    
    ArrayList<HelloBean> getBeanList();
    
    ComplexData getComplexData();
    
}

IHello接口的一個實現:HelloImpl.java

package hessian.test.server;

import java.util.ArrayList;

public class HelloImpl implements IHello{
    
    public String sayHello(String msg){
        return "Hello " + msg;
    }
    
    public void sayHello2(int bean){
        System.out.println("Hello " + bean);
    }
    
    public void print(String msg){
        System.out.println(msg);
    }
    
    public HelloBean getData(HelloBean bean){
        HelloBean result = new HelloBean();
        result.setName("lu xiaoxun a new name");
        result.setAge(26);
        
        System.out.print(bean.getName());
        return result;
    }
    
    public ArrayList<HelloBean> getBeanList(){
        ArrayList<HelloBean> beans = new ArrayList<HelloBean>();
        
        HelloBean b1 = new HelloBean();
        b1.setName("lu1");
        b1.setAge(26);
        beans.add(b1);
        
        HelloBean b2 = new HelloBean();
        b2.setName("lu2");
        b2.setAge(27);
        beans.add(b2);
        
        return beans;
    }
    
    public ComplexData getComplexData(){
        ComplexData data = new ComplexData();
        ArrayList<HelloBean> beans = getBeanList();
        data.setData(beans, beans.size());
        
        return data;
    }
}

定義用來進行數據傳輸的類,兩個類都必須實現Serializable接口:

HelloBean.java

package hessian.test.server;

import java.io.Serializable;

public class HelloBean implements Serializable {

    private static final long serialVersionUID = 570423789882653763L;

    private String name;
    
    private int age;
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge(){
        return age;
    }
    
    public void setAge(int age){
        this.age = age;
    }
    
}

ComplexData.java

package hessian.test.server;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class ComplexData implements Serializable{

    private static final long serialVersionUID = 1L;

    private ArrayList<HelloBean> helloBeans;
    
    //private Map<String, HelloBean> helloBeanMap;
    
    private int number;
    
    public int getNumber(){
        return number;
    }
    
    public ArrayList<HelloBean> getHelloBeans(){
        return helloBeans;
    }
    
    public void setData(ArrayList<HelloBean> beans, int num){
        this.number = num;
        this.helloBeans = beans;
//        helloBeanMap = new HashMap<String, HelloBean>();
//        for (HelloBean helloBean : beans) {
//            if(!helloBeanMap.containsKey(helloBean.getName()))
//            {
//                helloBeanMap.put(helloBean.getName(), helloBean);
//            }
//        }
    }
}

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" 
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    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>hessian server</display-name>
    <servlet>
        <servlet-name>hessian</servlet-name>
        <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
        <init-param>
            <param-name>service-class</param-name>
            <param-value>hessian.test.server.HelloImpl</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>hessian</servlet-name>
        <url-pattern>/hessian</url-pattern>
    </servlet-mapping>
</web-app>

Hessian客戶端(c#)

定義一個與服務端對應的IHello接口:IHello.cs

    public interface IHello
    {
        String sayHello(String msg);

        void sayHello2(int bean);

        void print(String msg);

        HelloBean getData(HelloBean bean);

        HelloBean[] getBeanList();

        ComplexData getComplexData();
    }

定義與服務器端一致的的通信數據類:

HelloBean.cs

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

namespace hessian.test.server
{
    public class HelloBean
    {
        public String Name 
        {
            set { name = value; }
            get { return name; }
        }

        private String name; //類型和名稱需要和服務器端一致

        public int Age
        {
            set { age = value; }
            get { return age; }
        }

        private int age; //類型和名稱需要和服務器端一致

        public override String ToString()
        {
            return "Name: "+ name + " Age: " + age;
        }

    }
}

ComplexData.cs:

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

namespace hessian.test.server
{
    public class ComplexData
    {
        private HelloBean[] helloBeans;

        //private Dictionary<String, HelloBean> helloBeanMap;

        private int number;

        public int GetNumber()
        {
            return number;
        }

        public HelloBean[] GetBeans()
        {
            return helloBeans;
        }

        //public Dictionary<String, HelloBean> GetBeansDic()
        //{
        //    return helloBeanMap;
        //}
    }
}

在主項目中添加Hessiancsharp.dll引用。

測試代碼:

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

using hessiancsharp.client;
using hessian.test.server;

namespace HessianClientTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = @"http://localhost:8080/HessianServerTest/hessian";
            CHessianProxyFactory factory = new CHessianProxyFactory();

            IHello test = (IHello)factory.Create(typeof(IHello), url);

            //Test function
            Console.WriteLine(test.sayHello("lu"));   //打印從服務器端獲取的字符串
            test.sayHello2(12);                       //在服務器端控制台打印 "Hello 12"   
            test.print("hessian");                    //在服務器端控制台打印 "hessian"  

            //Test Object
            HelloBean bean = new HelloBean();
            //bean.setName("lu xiaoxun");
            bean.Name = "luxiaoxun";
            HelloBean result = test.getData(bean);
            Console.WriteLine(result.Name);
            Console.WriteLine(result.Age);
            Console.WriteLine(result);

            //Test Object Array
            HelloBean[] beans = test.getBeanList();
            if (beans != null)
            {
                foreach (HelloBean data in beans)
                {
                    Console.WriteLine(data.ToString());
                }
            }

            //Test complex data
            ComplexData complexData = test.getComplexData();
            if (complexData != null)
            {
                Console.WriteLine("Array number: " + complexData.GetNumber());

                HelloBean[] comArray = complexData.GetBeans();
                if (comArray != null)
                {
                    foreach (HelloBean data in comArray)
                    {
                        Console.WriteLine(data.ToString());
                    }
                }

                //Dictionary<String, HelloBean> helloBeanMap = complexData.GetBeansDic();
                //if (helloBeanMap != null)
                //{
                //    foreach (String key in helloBeanMap.Keys)
                //    {
                //        Console.WriteLine(helloBeanMap[key].GetHelloBeanInfo());
                //    }
                //}
            }

            Console.ReadKey();
        }
    }
}

測試結果:

注意事項:

1、服務端和客戶端用於數據傳遞的對象的命名空間要一致

IHello接口所在命名空間服務端和客戶端可以不一致,但是IHello中用到的HelloBean和ComplexData在Java服務端和C#客戶端中兩個HelloBean類所在的命名空間要一致。

2、類的字段要一致

用於數據傳輸的類的字段名和字段類型要一致(修飾類型可以不一致)。

3、服務端的類要序列化

4、盡量使用基本的數據類型

從上面的測試可以看出,傳遞基本的類型沒有問題,傳遞普通的類對象沒有問題,傳遞ArrayList的時候也沒有問題(C#客戶端使用Array數組),但是傳遞HashMap字典的時候會有問題,C#這邊使用Dictionary沒法對應一致,可能是由於hash函數內部實現不一致導致的,具體原因不明。

 

測試代碼:HessianTest.rar

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM