一、Hessian簡介
Hessian與WebService一樣,可以完成遠端方法調用。
例如,某公司已經有了CRM系統,之後想開發一個物流系統,而物流系統的客戶資訊需要用到CRM系統中的客戶資訊,這就需要從新的物流系統去掉用CRM系統的方法擷取客戶資料。我們通常可以在一個系統内調用系統内的方法,但是一般不可以調用其他系統的方法,而且有的時候,我們需要的其他系統的方法并不一定與我們使用的是同一種程式設計語言,而且這兩個系統一般不在同一台伺服器上。想要完成這種遠端方法調用,可以借助Hessian完成。
Hessian使用标準協定進行資料傳輸。相當于分布式的資料互動。
RMI(Java Remote Method Invocation)Java遠端方法調用。
其實在Java的内部就提供了RMI的接口。但是如果使用Java提供的RMI,會有一個問題,隻局限Java的調用。
幾種技術效率的比較:
RMI > Httpinvoker >= Hessian>>Burlap >> WebService
RMI是Java自帶的,有局限性,隻限于Java程式之間的遠端通路。
Httpinvoker使用Java的序列化技術傳輸對象,與RMI本質上是一樣的,從效率上看,二者也相差無幾。
效率最低的就是WebService,為啥還有大量的人在用呢?因為使用的是xml文檔,協定标準。
Hessian:
Hessian在傳輸少量對象的時候,比RMI還要快速,但傳輸資料結構複雜的對象或大量資料對象的時候,比RMI要慢20%,但隻是在資料量特别大的時候。
Hessian是基于Binary-RPC協定實作的,是一種二進制資料格式,是以可以跨不同的語言平台,是以不管是Java,還是.NET都可以使用。
二、Hessian下載下傳
http://hessian.caucho.com/#Java
三、Hessian應用簡單入門案例
建立兩個WEB項目:
一個server(服務端),一個client(用戶端),模拟兩個不同的系統,client調用server的功能。
将Hessian的jar包導入到lib中。
在服務端建立提供外界調用的方法的接口。
public interface HelloService {
public String sayHello();
}
提供這個接口的實作類。
public class HelloServiceImpl implements HelloService{
public String sayHello() {
return "Hello Service!!!";
}
}
寫到這裡,client還是不可以通路server的功能的,需要配置Hessian的服務。配置服務就可以被遠端調用了。
配置方式可以參考Hessian的文檔:Hessian.mht
點選這裡的标準的web.xml配置資訊可以擷取标準示例:
web.xml
<web-app>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
<init-param>
<param-name>home-class</param-name>
<param-value>example.BasicService</param-value>
</init-param>
<init-param>
<param-name>home-api</param-name>
<param-value>example.Basic</param-value>
</init-param>
</servlet>
<servlet-mapping>
<!—配置通路路徑,目前通路路徑是根目錄下的hello,可以改成自己需要的-->
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
将這一段貼到server端的web.xml中。可以看到,其實就是配置一個servlet。
這一段中,紅色加粗的部分需要我們改動。修改為:
<init-param>
<!-- 實作類,将<param-value>改為實作類的全限定名稱 -->
<param-name>home-class</param-name>
<param-value>service.HelloServiceImpl</param-value>
</init-param>
<init-param>
<!-- 接口,将<param-value>改為接口的全限定名稱 -->
<param-name>home-api</param-name>
<param-value>service.HelloService</param-value>
</init-param>
配置完成,将server釋出到tomcat中,運作tomcat,在用戶端就可以調用這個接口。
在浏覽器輸入:http://localhost:8080/server/hello就可以通路。
此時顯示這個界面,說Hessian需要一個post請求。
下一步我們做client。
在用戶端我們已經引入了Hessian的jar包,但是我們不能什麼都不寫就直接調用server的方法。必須把接口統一。
将server的接口連同包一起複制到client中,如圖:
接口的内容是一樣的:
public interface HelloService {
public String sayHello();
}
有了這個接口之後,就可以建立我們的測試用例了。可以在client建立立一個test包,并建立一個HessianTest測試類。
使用junit測試。
現在要在client調用伺服器的位址,這個位址就是我們剛才在浏覽器輸入的位址:http://localhost:8080/server/hello
注意,真實環境中,localhost是一個IP位址,因為一般server和client是在不同的伺服器中的。
測試類咋寫呢?
在Hessian的文檔中有示例代碼:
Hessian Client for Basic service
package example;
import com.caucho.hessian.client.HessianProxyFactory;
public class BasicClient {
public static void main(String []args)
throws Exception
{
String url = "http://www.caucho.com/hessian/test/basic";
HessianProxyFactory factory = new HessianProxyFactory();
Basic basic = (Basic) factory.create(Basic.class, url);
System.out.println("Hello: " + basic.hello());
}
}
用到的核心類是HessianProxyFactory工廠類。
import java.net.MalformedURLException;
import org.junit.Test;
import service.HelloService;
import com.caucho.hessian.client.HessianProxyFactory;
public class HessianTest {
@Test
public void hessianDemo() throws MalformedURLException {
//定義通路遠端主機的位址
String target = "http://localhost:8080/server/hello";
//擷取工廠對象
HessianProxyFactory factory = new HessianProxyFactory();
//通過工廠的create方法,擷取HelloService接口的實作類,
//第一個參數是要擷取的對象的類型,第二個是要通路主機的位址
//擷取的helloService對象其實是伺服器端的一個HelloService的代理對象,
//我們使用其方法的時候實際通路的是遠端主機的方法
HelloService helloService =
(HelloService) factory.create(HelloService.class, target);
//調用遠端主機的功能。
System.out.println(helloService.sayHello());
}
}
控制台顯示資訊:
至此,成功的從client通路了server的實作類的sayHello方法。
Hessian的通信原理:
helloService.sayHello()
在調用這一句的時候,其實是在底層通路了我們指定的位址,我們指定的位址是一個servlet,是以這裡實際通路的是這個servlet(HessianServlet),這個servlet就去找你指定的接口注冊的實作類(在server的web.xml中注冊),再從這個實作類中找到這個方法,再将這個方法的傳回值變為二進制傳回到client。