介绍
hessian主页:http://hessian.caucho.com/
一个简单的例子学习hessian服务:服务端为Java,客户端为C#。
Hessian服务端(java)
打开eclipse创建一个Dynamic Web Project,将hessian-4.0.37.jar放到lib下,大概如图所示:
创建一个通信接口IHello:
packagehessian.test.server;importjava.util.ArrayList;public interfaceIHello {
String sayHello(String msg);void sayHello2(intbean);voidprint(String msg);
HelloBean getData(HelloBean bean);
ArrayListgetBeanList();
ComplexData getComplexData();
}
IHello接口的一个实现:HelloImpl.java
packagehessian.test.server;importjava.util.ArrayList;public class HelloImpl implementsIHello{publicString sayHello(String msg){return "Hello " +msg;
}public void sayHello2(intbean){
System.out.println("Hello " +bean);
}public voidprint(String msg){
System.out.println(msg);
}publicHelloBean getData(HelloBean bean){
HelloBean result= newHelloBean();
result.setName("lu xiaoxun a new name");
result.setAge(26);
System.out.print(bean.getName());returnresult;
}public ArrayListgetBeanList(){
ArrayList beans = new ArrayList();
HelloBean b1= newHelloBean();
b1.setName("lu1");
b1.setAge(26);
beans.add(b1);
HelloBean b2= newHelloBean();
b2.setName("lu2");
b2.setAge(27);
beans.add(b2);returnbeans;
}publicComplexData getComplexData(){
ComplexData data= newComplexData();
ArrayList beans =getBeanList();
data.setData(beans, beans.size());returndata;
}
}
定义用来进行数据传输的类,两个类都必须实现Serializable接口:
HelloBean.java
packagehessian.test.server;importjava.io.Serializable;public class HelloBean implementsSerializable {private static final long serialVersionUID = 570423789882653763L;privateString name;private intage;publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public intgetAge(){returnage;
}public void setAge(intage){this.age =age;
}
}
ComplexData.java
packagehessian.test.server;importjava.io.Serializable;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.Map;public class ComplexData implementsSerializable{private static final long serialVersionUID = 1L;private ArrayListhelloBeans;//private Map helloBeanMap;
private intnumber;public intgetNumber(){returnnumber;
}public ArrayListgetHelloBeans(){returnhelloBeans;
}public void setData(ArrayList beans, intnum){this.number =num;this.helloBeans =beans;//helloBeanMap = new HashMap();//for (HelloBean helloBean : beans) {//if(!helloBeanMap.containsKey(helloBean.getName()))//{//helloBeanMap.put(helloBean.getName(), helloBean);//}//}
}
}
web.xml内容:
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"id="WebApp_ID"version="3.0">
hessian server
hessian
com.caucho.hessian.server.HessianServlet
service-class
hessian.test.server.HelloImpl
hessian
/hessian
Hessian客户端(c#)
定义一个与服务端对应的IHello接口:IHello.cs
public interfaceIHello
{
String sayHello(String msg);void sayHello2(intbean);voidprint(String msg);
HelloBean getData(HelloBean bean);
HelloBean[] getBeanList();
ComplexData getComplexData();
}
定义与服务器端一致的的通信数据类:
HelloBean.cs
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespacehessian.test.server
{public classHelloBean
{publicString Name
{set { name =value; }get { returnname; }
}private String name; //类型和名称需要和服务器端一致
public intAge
{set { age =value; }get { returnage; }
}private int age; //类型和名称需要和服务器端一致
public overrideString ToString()
{return "Name:"+ name + "Age:" +age;
}
}
}
ComplexData.cs:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespacehessian.test.server
{public classComplexData
{privateHelloBean[] helloBeans;//private Dictionary helloBeanMap;
private intnumber;public intGetNumber()
{returnnumber;
}publicHelloBean[] GetBeans()
{returnhelloBeans;
}//public Dictionary GetBeansDic()//{//return helloBeanMap;//}
}
}
在主项目中添加Hessiancsharp.dll引用。
测试代码:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usinghessiancsharp.client;usinghessian.test.server;namespaceHessianClientTest
{classProgram
{static void Main(string[] args)
{string url = @"http://localhost:8080/HessianServerTest/hessian";
CHessianProxyFactory factory= newCHessianProxyFactory();
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 = newHelloBean();//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 inbeans)
{
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 incomArray)
{
Console.WriteLine(data.ToString());
}
}//Dictionary 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函数内部实现不一致导致的,具体原因不明。