Java远程方法调用是编程过程中比较常见的问题,列举一下主要包括如下几类:

1、Java RMI (Remote Method Invocation)

2、EJB远程接口调用

3、WebService,如jax-ws axis xfire cfx

4、Hessian以及Spring HttpInvoker

5、直接动态请求返回JSON数据

 

       本文从配置复杂性、编码难度、执行效率、跨语言性、兼容性、安全性、协议类型、是否绑定特定框架等方面做一个简单的比较分析。

 

       JavaRMI是jdk中内嵌的一个最底层的解决方案,它应用起来最轻量级,也最简单,它不需要任何的web服务器,直接在代码中绑定IP地址和相应的端口,如果是非常简单的小微应用比较适合,因为最底层其效率应该不错,接下来的几种调用方式其他有一些都是以这个为基础扩展而来的。其缺点也很明显,如果业务非常多而复杂、接口调用非常频繁需要分布在多台服务器,那么其编码很不优雅、也难于实现分布式等,且所有的东西都集中在代码里了,可读性可维护性等都不太理想,不具备跨语言的调用。

 

       EJB远程接口调用,其最本质的底层仍然是JavaRMI,通过JNDI来调用服务。不过EJB远程接口调用的优点是,可以非常轻松的实现分布式,客户端编码有些版本比较复杂,但多数代码一般可以借助IDE自动完成,EJB3.0以后的版本编码和配置起来也更简单。缺点是,EJB是个重量级的框架,需要EJB容器的支撑,很多web服务器都不具备这个功能,如resin、tomcat等,如果业务代码不是使用EJB的话,远程调用自然不适用。目前互联网开发中EJB已经非常少见了,可能是spring的崛起以及非常有名的那本书《Expert One-on-One J2EE Development without EJB》,有中文版。

 

       WebService是很常见的远程调用方法,其最大的优势就是跨平台语言,无论客户端是Java还是.NET都能轻松的调用。它采用SOAP(Simple Object Access Protocol)协议来封装序列化的消息,实际上是形成一个xml文件,可以通过http进行网络传输。WebService的客户端调用其实是使用生成文件的方式,只要知道发布接口的URL即可,而不需要额外传递jar包或者class文件。常见的WebService实现有jax-ws2.0、axis、xfire以及cfx,其中jax-ws2.0是jdk中封装好的,有一定的灵活性,但是这种把框架内嵌进入JVM其实对其可控性大大降低;axis有1.0和2.0两个版本,这个不是太了解;xfire和cfx其实是一个源头,xfire在07年停止开发,和另外一个框架合并形成了cfx,是一个比较受欢迎的WebService实现。

 

       Hessian是另外一个非常常用的远程调用方案,它基于Binary-RPC协议,这个协议把请求和响应的数据统统使用标准的二进制格式进行封装,所以它也具有跨语言平台传输数据的能力,而且它有自己的高效的序列化和反序列化机制。不过hessian在版本控制中经常出现互不兼容的情况,服务器端和客户端通常要保持一致的版本,否则会出现莫名其妙的问题,还有常见的各种错误,如使用nginx反向代理后返回411错误等。spring对hessian提供了很好的支持,通常配合使用;同时spring还有一套自己的远程调用方法HttpInvoker。如果你使用过Hessian和HttpInvoker的话,就会发现它俩的配置几乎一模一样,包括接口名称、类名、字段名、调用和发布代码。。。而且不能同时使用,会相互产生冲突。它们都是通过servlet进行请求处理,需要servlet容器支持,效率不错。

 

       直接动态请求返回JSON数据,是一个直观上的方式,严格来说不属于远程方法的调用。这种方式就是通过一个servlet请求直接由容器返回封装好的JSON数据,数据结构不够灵活,安全性也不足。不过实现起来简单,和业务代码一起就顺带写完了,几乎都不需要客户端的概念,只要请求数据足够简单、安全措施做好也可以使用。