首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hessian 輕量級 RPC 實戰:純 Java 與 Spring 整合雙模式詳解

     編輯:Java 相關知識

認識 Hessian:二進制 RPC 的極簡之選

Hessian 是 Caucho 推出的輕量級遠程調用框架,特點鮮明:

  • 二進制協議:比 XML/JSON 更緊湊,序列化效能高,天然適合二進制數據傳輸
  • HTTP 傳輸:穿透防火牆,無需額外端口
  • 無需 IDL:面向接口編程,動態代理透明調用
  • 跨語言:Python、PHP、C++ 等多語言客戶端支援

對比傳統 WebService(SOAP/XML):Hessian 更簡單、更快、帶寬佔用更低。

架構原理

客戶端 → 序列化 → HTTP Request → 服務端反序列化 → 調用實現 → 序列化結果 → HTTP Response → 客戶端反序列化

核心組件:

  • 服務端:HessianServlet 處理請求分發
  • 客戶端:HessianProxyFactory 創建動態代理
  • Spring 整合:HessianServiceExporter、HessianProxyFactoryBean

模式一:純 Hessian 實現(無 Spring 依賴)

1. 定義服務接口

package michael.hessian;
import java.util.List;
import java.util.Map;

public interface HelloHessian {
    String sayHello();
    MyCar getMyCar();
    List<String> myLoveFruit();
    Map<String, String> myBabays();
}

2. 實現類繼承 HessianServlet

package michael.hessian.impl;

import michael.hessian.HelloHessian;
import michael.hessian.MyCar;
import com.caucho.hessian.server.HessianServlet;
import java.util.*;

public class HelloHessianImpl extends HessianServlet implements HelloHessian {
    public MyCar getMyCar() {
        MyCar car = new MyCar();
        car.setCarName("阿斯頓·馬丁");
        car.setCarModel("One-77");
        return car;
    }
    
    public Map<String, String> myBabays() {
        Map<String, String> map = new HashMap<>();
        map.put("son", "孫吳空");
        map.put("daughter", "孫小美");
        return map;
    }
    
    public List<String> myLoveFruit() {
        return Arrays.asList("apple", "kiwi", "orange");
    }
    
    public String sayHello() {
        return "welcome to Hessian";
    }
}

3. 實體類實現 Serializable

package michael.hessian;
import java.io.Serializable;

public class MyCar implements Serializable {
    private static final long serialVersionUID = 4736905401908455439L;
    private String carName;
    private String carModel;
    // getter/setter/toString 省略
}

4. web.xml 配置 Servlet

<servlet>
    <servlet-name>HelloHessian</servlet-name>
    <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
    <init-param>
        <param-name>home-class</param-name>
        <param-value>michael.hessian.impl.HelloHessianImpl</param-value>
    </init-param>
    <init-param>
        <param-name>home-api</param-name>
        <param-value>michael.hessian.HelloHessian</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>HelloHessian</servlet-name>
    <url-pattern>/HessianService</url-pattern>
</servlet-mapping>

5. Java 客戶端調用

String url = "https://localhost:8082/J2EE_sJSky/HessianService";
HessianProxyFactory factory = new HessianProxyFactory();
HelloHessian hello = (HelloHessian) factory.create(HelloHessian.class, url);

System.out.println(hello.sayHello());
MyCar car = hello.getMyCar();
System.out.println(car);  // my car name:[阿斯頓·馬丁] model:[One-77].

hello.myBabays().forEach((k, v) -> System.out.println(k + " " + v));
hello.myLoveFruit().forEach(System.out::println);

模式二:Spring + Hessian 整合(推薦生產環境)

1. web.xml 配置 DispatcherServlet

<servlet>
    <servlet-name>springhessian</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springhessian</servlet-name>
    <url-pattern>/springhessian/*</url-pattern>
</servlet-mapping>

2. springhessian-servlet.xml 導出服務

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="helloHessianImpl" class="michael.hessian.impl.HelloHessianImpl" />
    
    <bean name="/helloHessianService" 
          class="org.springframework.remoting.caucho.HessianServiceExporter">
        <property name="service" ref="helloHessianImpl" />
        <property name="serviceInterface" value="michael.hessian.HelloHessian" />
    </bean>
</beans>

關鍵點:Bean 名稱 /helloHessianService 直接映射為 URL 路徑,完整訪問地址:/springhessian/helloHessianService。

3. Spring 客戶端配置 (hessian-client.xml)

<beans>
    <bean id="helloHessianClient" 
          class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
        <property name="serviceUrl" 
            value="https://localhost:8082/J2EE_sJSky/springhessian/helloHessianService" />
        <property name="serviceInterface" value="michael.hessian.HelloHessian" />
    </bean>
</beans>

4. 客戶端調用

ApplicationContext ctx = new ClassPathXmlApplicationContext("hessian-client.xml");
HelloHessian hello = (HelloHessian) ctx.getBean("helloHessianClient");
// 後續調用同純 Java 模式

常見異常排查:HessianProtocolException

現象

com.caucho.hessian.io.HessianProtocolException: expected string at 0x6d
    at com.caucho.hessian.io.Hessian2Input.readString(Hessian2Input.java:1362)
    at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:249)

根因分析

  • 客戶端與服務端 Hessian 版本不一致(如一邊 4.0.x,一邊 3.x)
  • 協議版本不匹配:Hessian 1.x vs 2.x 序列化格式不同
  • 類定義不一致:serialVersionUID、字段類型、順序變更

解決方案

  1. 統一雙端 Hessian JAR 版本(推薦 4.0.74+)
  2. 服務端啟用調試日誌:-Dhessian.debug=true
  3. 確保實體類 serialVersionUID 顯式聲明且雙端一致
  4. 避免接口方法簽名變更,採用兼容性擴展(新增方法、可選參數)

最佳實踐總結

場景推薦模式理由
微服務內部調用、高性能要求Spring + Hessian統一配置管理、AOP 支援、事務整合
輕量級獨立模塊、無 Spring 依賴純 Hessian零配置、啟動快、部署簡單
跨語言調用均可協議標準化,客戶端只需實現 Hessian 協議

結語

Hessian 以「簡單、高效、二進制」三大特性,在內部服務調用、移動端 API、異構系統集成中佔據一席之地。雖然 gRPC、Dubbo 等新框架功能更強,但 Hessian 的零學習成本、零配置複雜度、原生 HTTP 傳輸,使其在中小型項目、遺留系統改造、快速原型開發中依然極具競爭力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved