开始调研Hessian和Mina,目的是希望能够建立一个简单的“高性能分布式服务调用框架”!类似于Dubbo或者淘宝的HSF那种,但是是要跨平台的,而不仅仅局限在Java领域。
hessian是一种远程调用的机制(RPC) ,类似于web service,不过它是使用自己的序列化协议(二进制序列化)。淘宝的HSF高性能服务框架中两台机器通信用到的序列化技术就是Hessian的,它的内部实现就是基于Hessian和Mina,这里是几篇关于Hessian源码解析的文章可以参考。
基于Hessian的远程调用协议。
约束:
这里我们主要先讲一下如果利用Hessian实现RPC:
(一)Java客户端调用Java服务:
1 下载Eclipse IDE for JavaEE Developer(http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/keplersr1)
2 下载hessian-4.0.37.jar (http://hessian.caucho.com/index.xtp#IntroductiontoHessian)
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!"; } }
<?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>
<%@ 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()); %>
在浏览器中输入 http://localhost:8390/WebProjTest/hello.jsp 可以看到期望的输出。说明成功了。
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(); } } }
本文参考: http://blog.sina.com.cn/s/blog_a27c1c670101fphf.html
这里是我提供的源码下载: 下载地址是我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#客户端了。
以上只是我的两个想法,有待验证,或者有更好的方法请大家不吝赐教,谢谢!!!