Spring v3.0.2 Learning Note 16 - Integrate With Hessian

本文介绍如何使用 Spring 的 HessianServiceExporter 和 DispatcherServlet 配置远程服务,并提供了一个示例,包括 web.xml 和 spring 配置文件的具体设置。此外还探讨了解决在 WebLogic 服务器上部署时遇到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Reference Library

%SPRING%/dist/com.springsource.org.aopalliance-1.0.0.jar%SPRING%/dist/org.springframework.aop-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.asm-3.0.4.RELEASE.jar
%SPRING%/dist/org.springframework.beans-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.context-3.0.4.RELEASE.jar
%SPRING%/dist/org.springframework.core-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.expression-3.0.4.RELEASE.jar
%SPRING%/dist/org.springframework.transaction-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.web.servlet-3.0.2.RELEASE
%SPRING%/dist/org.springframework.web-3.0.4.RELEASE.jar
%SPRING_DEP%/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar
%SPRING_DEP%/com.caucho/com.springsource.com.caucho/3.2.1/com.springsource.com.caucho-3.2.1.jar
%SPRING_DEP%/javax.servlet/com.springsource.javax.servlet/2.5.0/com.springsource.javax.servlet-2.5.0.jar

Wiring up the DispatcherServlet for 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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>springhessian</display-name>

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

</web-app>

Using Spring's DispatcherServlet principles, as known from Spring Web MVC usage, you can easily wire up such a servlet exposing your services.

Exposing your beans by using the HessianServiceExporter

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:component-scan base-package="com.spring.hessian.test" />
    <bean id="acctService" class="com.spring.hessian.test.impl.AccountInfoImpl" />
    <bean name="/acctService"
        class="org.springframework.remoting.caucho.HessianServiceExporter">
        <property name="service" ref="acctService" />
        <property name="serviceInterface" value="com.spring.hessian.test.IAccountInfo" />
    </bean>
</beans>

Above configuration should be stored in WEB-INF/hessianServices-servlet.xml
Take note the configuration file name must be hessianServices-servlet.xml. 
According to spring manual, the file name is remoting-servlet.xml, I tried it but it could not work.

>>> After several try, found the naming rule is <servlet name defined in web.xml>-servlet.xml.
For example, I defined a servlet named hessianServices, so the configure file will be hessianServices-servlet.xml


Source Code

// interface
package com.spring.hessian.test;

import com.spring.hessian.test.bean.AccountInfo;

public interface IAccountInfo {

    public void createAccount(AccountInfo accountInfo);

    public boolean changeEmail(int accountId, String newEmail);

    public void deleteAccount(int accountId);
}


// implement class
package com.spring.hessian.test.impl;

import org.springframework.stereotype.Service;

import com.spring.hessian.test.IAccountInfo;
import com.spring.hessian.test.bean.AccountInfo;

@Service
public class AccountInfoImpl implements IAccountInfo {

    @Override
    public boolean changeEmail(int accountId, String newEmail) {
        System.out.println("Here is the logic to change email.");
        return false;
    }

    @Override
    public void createAccount(AccountInfo accountInfo) {
        System.out
                .println("Here is the logic to create account with account info = "
                        + accountInfo.toString());
    }

    @Override
    public void deleteAccount(int accountId) {
        System.out.println("Here is the logic to delete account with ID = "
                + accountId);
    }

}
 

// domain class
package com.spring.hessian.test.bean;

import java.io.Serializable;

public class AccountInfo implements Serializable {

    private static final long serialVersionUID = 5308953586718817188L;
    private int accountId;
    private String userName;
    private String password;
    private String email;

    public AccountInfo() {
        super();
    }

    public AccountInfo(int accountId, String userName, String password,
            String email) {
        super();
        this.accountId = accountId;
        this.userName = userName;
        this.password = password;
        this.email = email;
    }

    public int getAccountId() {
        return accountId;
    }

    public void setAccountId(int accountId) {
        this.accountId = accountId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String toString() {
        return "AccountInfo:[id]=" + this.accountId + ",[userName]="
                + this.userName + ",[pwd]=" + this.password + ",[email]="
                + this.email;
    }

}
 

// Junit test
package com.spring.hessian.test;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.caucho.hessian.client.HessianProxyFactory;
import com.spring.hessian.test.bean.AccountInfo;

public class HessianTester {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }

    @Test
    public void test() throws Exception {
        String url = "http://localhost:8080/springhessian/remote/acctService";
        HessianProxyFactory factory = new HessianProxyFactory();
        IAccountInfo accountInfo = (IAccountInfo) factory.create(
                IAccountInfo.class, url);
        AccountInfo account = new AccountInfo(125, "myName", "myPwd",
                "abc@email.com");
        accountInfo.createAccount(account);
        accountInfo.changeEmail(126, "def@email.com");
        accountInfo.deleteAccount(129);
    }
}


From tomcat console ,we can see the output if running above junit test case.

Here is the logic to create account with account info = AccountInfo:[id]=125,[userName]=myName,[pwd]=myPwd,[email]=abc@email.com
Here is the logic to change email.
Here is the logic to delete account with ID = 129

 

未解决的问题

以上代码和配置在tomcat中一切正常,但是移到weblogic v10.3下,当调用第一个远程方法后总会碰到空指针异常
<Oct 29, 2010 1:42:20 PM SGT> <Error> <Kernel> <BEA-000802> <ExecuteRequest failed
 java.lang.NullPointerException.
java.lang.NullPointerException
        at weblogic.utils.http.HttpChunkInputStream.initChunk(HttpChunkInputStream.java:66)
        at weblogic.utils.http.HttpChunkInputStream.skip(HttpChunkInputStream.java:197)
        at weblogic.utils.http.HttpChunkInputStream.skipAllChunk(HttpChunkInputStream.java:371)
        at weblogic.servlet.internal.ServletInputStreamImpl.ensureChunkedConsumed(ServletInputStreamImpl.java:30)
        at weblogic.servlet.internal.ServletRequestImpl.skipUnreadBody(ServletRequestImpl.java:192)
        Truncated. see log file for complete stacktrace
>



到现在仍没找到原因,不得已还是采用hessian的配置方式
<servlet>
  <servlet-name>HessianServlet</servlet-name>
  <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
  <init-param>
   <param-name>home-class</param-name>
   <param-value>com.spring.hessian.test.impl.AccountInfoImpl</param-value>
  </init-param>
  <init-param>
   <param-name>home-api</param-name>
   <param-value>com.spring.hessian.test.IAccountInfo</param-value>
  </init-param>
 </servlet>

 <servlet-mapping>
  <servlet-name>HessianServlet</servlet-name>
  <url-pattern>/remote2</url-pattern>
 </servlet-mapping>



客户端改用这个URL "http://<host>:<port>/hessian/remote2" 在weblogic下可得正确结果。


如果采用hessian的配置方式,以下依赖包就不再需要了
%SPRING%/dist/org.springframework.web.servlet-3.0.2.RELEASE
%SPRING%/dist/org.springframework.web-3.0.4.RELEASE.jar

以下配置文件不再需要
WEB-INF/hessianServices-servlet.xml 

web.xml内容改为:
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>springhessian</display-name>

    <servlet>
        <servlet-name>HessianServlet</servlet-name>
        <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
        <init-param>
            <param-name>home-class</param-name>
            <param-value>com.spring.hessian.test.impl.AccountInfoImpl</param-value>
        </init-param>
        <init-param>
            <param-name>home-api</param-name>
            <param-value>com.spring.hessian.test.IAccountInfo</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>HessianServlet</servlet-name>
        <url-pattern>/remote2</url-pattern>
    </servlet-mapping>
</web-app>

WEB-INF/classes 需要spring的配置文件,内容为:
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:component-scan base-package="com.spring.hessian.test" />
</beans>

为了部属到weblogic,还需要配置文件WEB-INF/weblogic.xml, 其内容为:
<?xml version='1.0' encoding='UTF-8'?>
<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd">
    <!-- share session in clustering env.  -->
    <session-descriptor>
        <persistent-store-type>replicated_if_clustered</persistent-store-type>
        <sharing-enabled>true</sharing-enabled> 
    </session-descriptor>
     <!-- load customized library files first  -->
    <container-descriptor>
        <prefer-web-inf-classes>true</prefer-web-inf-classes>
    </container-descriptor>
        <!-- set root context  -->
    <context-root>/hessian</context-root>

</weblogic-web-app>

<think>好的,我现在需要帮助用户找到JDK 21兼容的Spring Cloud版本。用户之前提到了Spring Boot和Spring Cloud的版本兼容问题,并且引用了几个相关的参考资料。首先,我需要确认JDK 21对应Spring Boot版本,因为Spring Cloud的版本通常依赖于Spring Boot的版本。 根据引用[4],提到Compatible Java Version是JDK 17+,但用户现在使用的是JDK 21,可能需要更新的Spring Boot版本。查阅Spring官方文档,通常每个Spring Boot版本都有对应Spring Cloud版本。例如,Spring Boot 3.x版本需要Spring Cloud 2022.x(也称为Kilburn系列),而Spring Boot 2.7.x对应的是Spring Cloud 2021.x(例如2021.0.8)。 不过,JDK 21是在2023年9月发布的,所以需要确认最新的Spring Cloud版本是否支持。目前,Spring Cloud的官方文档显示,Spring Cloud 2023.0.0(代号为“2023.0.0”)需要Spring Boot 3.2.x,而Spring Boot 3.2.x支持JDK 21。因此,用户应该使用Spring Cloud 2023.0.xSpring Boot 3.2.x组合,以确保兼容JDK 21。 另外,用户之前的引用中提到Spring Boot 2.4.2对应Hoxton.SR12,但那是针对JDK 8或11的旧版本。对于JDK 21,必须使用Spring Boot 3.x及以上版本,因为Spring Boot从3.0开始要求最低JDK 17,而3.1及以上版本支持JDK 21。 总结步骤:1. 确认Spring BootJDK 21的兼容性;2. 查找对应Spring Cloud版本;3. 提供版本组合建议。需要检查官方版本兼容表,确保信息准确。同时,提醒用户注意依赖管理,可能需要调整父POM或依赖项中的版本号。</think>根据Spring官方版本兼容性要求,Spring Cloud版本需要Spring Boot和JDK版本保持对应关系。对于JDK 21的兼容方案如下: ### 1. 基础版本对应原则 Spring Cloud版本通过`Release Train`命名(如2023.0.x),其必须特定Spring Boot版本匹配[^2][^4]。目前JDK 21支持的组合为: $$ \text{Spring Boot 3.2.x} + \text{Spring Cloud 2023.0.x} $$ ### 2. 具体版本推荐 | 组件 | 兼容版本 | JDK要求 | |--------------|----------------|-----------| | Spring Boot | 3.2.3 | 17-21 | | Spring Cloud | 2023.0.2 | 17-21 | ### 3. 配置示例 在Maven项目中需明确指定版本: ```xml <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.3</version> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2023.0.2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` ### 4. 注意事项 - 必须使用Spring Cloud 2023.0.x系列,早期版本如Hoxton/2021.x不支持JDK 21 - 需确认其他组件(如Spring Security、Spring Data)也升级到兼容版本 - 若使用Jakarta EE规范,需采用jakarta.*命名空间的依赖[^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值