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

原文地址:https://www.cnblogs.com/luxiaoxun/p/3969982.html