`
234390216
  • 浏览: 10237785 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:462834
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1775883
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1398686
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:395130
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:680144
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:531107
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1184883
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:468625
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:151477
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:68320
社区版块
存档分类
最新评论

Spring整合Hessian访问远程服务

阅读更多

Spring整合Hessian访问远程服务

目录

1.1      Hessian简介

1.2      整合

1.2.1     概述

1.2.2     服务端整合

1.2.3     客户端整合

1.1     Hessian简介

       Hessian是一个轻量级的Web服务实现工具,它采用的是二进制协议,因此很适合发送二进制数据。它的一个基本原理就是把远程服务对象以二进制的方式进行发送和接收。

1.2     整合

1.2.1 概述

对于Hessian而言,有服务端和客户端,所以我们的整合也需要分服务端的整合和客户端的整合。服务端的整合是通过SpringMVC进行的,而客户端的整合则是通过Springbean进行的。

1.2.2 服务端整合

基于客户端要调用服务端的远程服务,所以我们先来谈一下服务端的整合。Hessian的远程服务是基于接口的,所以我们要作为远程服务的实现类必须要实现一个接口。作为示例,这里我们建立一个叫hessianServerweb项目作为远程服务的服务端,在这个项目中我们建立一个叫做UserService的接口:

package com.tiantian.hessianserver.service;
 
public interface UserService {
 
       public void addUser();
      
       public void updateUser();
      
       public void delUser();
      
       public String findUser(String username);
      
}

 

       然后建立一个它的实现类UserServiceImpl

package com.tiantian.hessianserver.service.impl;
 
import com.tiantian.hessianserver.service.UserService;
 
public class UserServiceImpl implements UserService {
 
       public void addUser() {
              System.out.println("-------------invoke addUser()---------------");
       }
 
       public void updateUser() {
              System.out.println("-------------invoke updateUser()---------------");
       }
 
       public void delUser() {
              System.out.println("-------------invoke delUser()---------------");
       }
      
       public String findUser(String username) {
              System.out.println("-------------invoke findUser---------------");
              return "return: " + username;
       }
 
}

 

       那么接下来我们要做的就是把UserServiceImpl作为一个远程服务进行发布,以致客户端能够进行访问。

       首先我们需要在web.xml中配置一个SpringMVCDispatcherServlet用于接收所有的Web服务请求,这里我们这样配置:

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

 

       可以看到我们这个DispatcherServlet会处理url为“/api/service/*”的请求,通配符“*”就对应着我们的处理器映射。

       接下来就是在SpringMVC的配置文件中利用Hessian来定义我们的远程服务了,这是通过Spring提供的HessianServiceExporter来实现的。我们需要在SpringMVC的配置文件中定义一个类型为HessianServiceExporterbean对象。该bean对象需要接收两个属性,一个是service属性,用于关联真正的service对象,另一个是serviceInterface属性,用于指定当前的服务对应的接口。HessianServiceExporter实现了HttpRequestHandler接口,当我们请求某一个远程服务的时候实际上请求的就是其对应的HessianServiceExporter对象,HessianServiceExporter会把请求的服务以二进制的方式返回给客户端。这里我们在SpringMVC的配置文件中这样定义:

       <bean id="userService" class="com.tiantian.hessianserver.service.impl.UserServiceImpl" />
       <bean name="/userService"
              class="org.springframework.remoting.caucho.HessianServiceExporter">
              <property name="service" ref="userService" />
              <property name="serviceInterface" value="com.tiantian.hessianserver.service.UserService" />
       </bean>

 

       注意看我们的HessianServiceExporter对应的beanname是“/userService”,在SpringMVC的配置文件中,当一个beanname是以“/”开始的时候Spring会自动对它进行BeanNameUrlHandlerMapping。所以这里相当于是我们把“/userService”映射到了HessianServiceExporter,根据上面的配置我们要请求这个远程服务的时候应该请求“/api/service/userService”。虽然说在Spring的配置文件中我们把bean的名称设为以“/”开始时Spring会自动对它进行一个beanName映射,但有一次不知道是哪里影响了,我这样使用的时候Spring没有对它进行自动映射,所以为了保险起见,这里我们最好自己指定一个BeanNameUrlHandlerMapping,代码如下所示:

       <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
       <bean id="userService" class="com.tiantian.hessianserver.service.impl.UserServiceImpl" />
       <bean name="/userService"
              class="org.springframework.remoting.caucho.HessianServiceExporter">
              <property name="service" ref="userService" />
              <property name="serviceInterface" value="com.tiantian.hessianserver.service.UserService" />
       </bean>

 

       注意,因为是根据beanName来进行映射的,所以我们必须要给HessianServiceExporter bean对象指定name属性,而且其对应的name必须以“/”开头,这样我们的客户端才能访问到对应的服务。

1.2.3 客户端整合

对于客户端要使用远程的Hessian服务的,我们需要在Spring的配置文件中定义对应的org.springframework.remoting.caucho.HessianProxyFactoryBean bean对象。     HessianProxyFactoryBean对象需要指定两个属性,一个是serviceInterface属性,表示当前请求的远程服务对应的接口;另一个是serviceUrl属性,表示当前的远程服务对应的服务端请求地址。这里在客户端为了使用hessianServer定义的UserService服务,我们建立一个对应的hessianClient项目,在hessianClient中我们定义一个对应的UserService接口,这个接口的内容跟hessianServer中的UserService接口的内容是一样的。代码如下所示:

package com.tiantian.hessianserver.service;
 
public interface UserService {
 
       public void addUser();
      
       public void updateUser();
      
       public void delUser();
      
       public String findUser(String username);
      
}

 

       之后我们就在当前Spring的配置文件中定义对应的HessianProxyFactoryBean对象。HessianProxyFactoryBean会根据指定的serviceInterfaceserviceUrl属性返回一个serviceInterface对应的代理对象。这里我们的Spring配置文件这样定义:

<?xml version="1.0" encoding="UTF-8"?>
<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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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">
 
       <bean id="userService"
              class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
              <property name="serviceUrl"
                     value="http://localhost:8080/hessianServer/api/service/userService" />
              <property name="serviceInterface" value="com.tiantian.hessianserver.service.UserService" />
       </bean>
</beans>

 

       可以看到我们通过HessianProxyFactoryBean定义了一个UserService对应的远程代理对象,之后我们就可以在我们的程序中把它作为一个普通的bean对象来使用这个UserService的代理对象了。这里我们定义以下测试代码:

package com.tiantian.hessianclient.test;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.tiantian.hessianserver.service.UserService;
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext.xml")
public class HessianTest {
 
       @Autowired
       private UserService userService;
      
       @Test
       public void test() {
              userService.addUser();
              userService.updateUser();
              userService.delUser();
              String user = userService.findUser("ZhangSan");
              System.out.println(user);
              System.out.println("---------------------------------finished----------------------------------");
       }
      
}

 

       之后我们启动我们的hessianServer,然后执行上面的测试程序,在服务端会输出如下内容:



 

       在客户端会输出如下内容:



 

       这说明我们已经成功地调用了远程服务UserService

注:

    1.Hessian不支持方法的重载,打个比方现在有一AddService,里面有一add(int a, int b)和一add(long a, long b)方法,然后我们把它发布为一个Hessian服务。那么当我们想要远程访问AddService的add方法时Hessian会报错,抛出异常

com.caucho.hessian.io.HessianProtocolException: '?' is an unknown code

因为默认情况下它是不支持方法的重载,这个时候我们可以在客户端使用的时候新增属性overloadEnabled,值为true。如:

<?xml version="1.0" encoding="UTF-8"?>  
<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"  
       xmlns:mvc="http://www.springframework.org/schema/mvc"  
       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">  
   
       <bean id="userService"  
              class="org.springframework.remoting.caucho.HessianProxyFactoryBean">  
              <property name="serviceUrl"  
                     value="http://localhost:8080/hessianServer/api/service/userService" />  
			  <property name="serviceInterface" value="com.tiantian.hessianserver.service.UserService" />
			  <!--新增overloadEnabled属性,并把它的值设置为true,默认是false,则Hessian就能支持方法的重载了。-->
			  <property name="overloadEnabled" value="true" />
       </bean>  
</beans>

 

       2.完整源码请查看附件。

  • 大小: 1.6 KB
  • 大小: 1.1 KB
12
2
分享到:
评论
10 楼 snfdf 2017-09-27  
234390216 写道
snfdf 写道
看了博主的文章,正好解决了我们最近项目的一个问题,但是在用了hessian后又出现另一个问题还要请教博主,客户端在请求服务端得到数据后,例如得到的是一个list对象,但是在准备循环遍历这个list中的对象时却报了一个异常:java.lang.ClassCastException: java.util.HashMap cannot be cast to xxx.xxx.xxx.xxx,而接口方法明明指定了返回值为List<xxx> findAll(),请问博主有碰到这种问题吗?有啥解决办法?谢谢。


没遇到过,在服务端检查一下list中存储的确实是你指定的xxx对象吗?List<XXX>中是可以存储YYY对象的,但是在使用的时候如果你以为存储的是XXX,把YYY当XXX用时就会报类型转换错误。


感谢博主的回复,问题已经解决了,参考了下面zoushaohua84兄的回复,我在写接口的时候两个项目的接口包名是不一致的,不过这确实没有任何影响,数据可以请求到,但我的问题是不但接口包名不一致,实体类的包名也不一致,这就导致从A项目请求到的数据在B项目中无法转换成对应的类型,可能是因为这个原因吧,hessian就当hashmap来处理的,我把两个项目的实体类的包名对应一致这个问题就解决了。
9 楼 234390216 2017-09-26  
snfdf 写道
看了博主的文章,正好解决了我们最近项目的一个问题,但是在用了hessian后又出现另一个问题还要请教博主,客户端在请求服务端得到数据后,例如得到的是一个list对象,但是在准备循环遍历这个list中的对象时却报了一个异常:java.lang.ClassCastException: java.util.HashMap cannot be cast to xxx.xxx.xxx.xxx,而接口方法明明指定了返回值为List<xxx> findAll(),请问博主有碰到这种问题吗?有啥解决办法?谢谢。


没遇到过,在服务端检查一下list中存储的确实是你指定的xxx对象吗?List<XXX>中是可以存储YYY对象的,但是在使用的时候如果你以为存储的是XXX,把YYY当XXX用时就会报类型转换错误。
8 楼 snfdf 2017-09-26  
看了博主的文章,正好解决了我们最近项目的一个问题,但是在用了hessian后又出现另一个问题还要请教博主,客户端在请求服务端得到数据后,例如得到的是一个list对象,但是在准备循环遍历这个list中的对象时却报了一个异常:java.lang.ClassCastException: java.util.HashMap cannot be cast to xxx.xxx.xxx.xxx,而接口方法明明指定了返回值为List<xxx> findAll(),请问博主有碰到这种问题吗?有啥解决办法?谢谢。
7 楼 zoushaohua84 2016-03-14  

如果 接口包路径不一致,可以调用
6 楼 keren 2014-08-30  
如果 接口包路径不一致,或者如果客户端是用其他语言来调用呢,比如php c等,怎么弄。
5 楼 234390216 2014-06-19  
OnTheRoad_lee 写道
这个好像是java project啊,不是web project,那怎么部署到tomcat里??add Deployment时没找到项目

这是基于Maven构建的Web项目。
4 楼 OnTheRoad_lee 2014-06-19  
这个好像是java project啊,不是web project,那怎么部署到tomcat里??add Deployment时没找到项目
3 楼 与天争锋 2013-08-20  
哇!好详细!收下了! 谢谢分享!
2 楼 234390216 2013-05-15  
7454103 写道
有没有尝试 客户端的包路径 和服务器端的路径不一致呢!或者解决办法?

这个没有尝试过,有时间时会试一下,不过估计是不可行的,而且一般也不会有这个需求,真正项目中进行Hessian远程服务调用的时候那些对应的接口一般我们都是会把它拿出来作为一个jar包进行依赖的,而不会像文中示例代码那样把一个接口写两次,这样服务端和客户端用的都是同路径的同一接口。
1 楼 7454103 2013-05-15  
有没有尝试 客户端的包路径 和服务器端的路径不一致呢!或者解决办法?

相关推荐

    在 Spring Web Flow 项目中应用 Hessian 服务

    要在Spring Web Flow项目中集成Hessian服务,我们需要以下步骤: 1. **配置Hessian服务**:在服务器端,我们需要创建一个实现了所需接口的业务服务类,并在Spring配置文件中声明它为Hessian服务,使用`&lt;bean&gt;`标签...

    Hessian的Spring配置

    在Spring框架中集成Hessian,我们需要进行以下步骤: 1. **创建服务接口和服务实现**: 首先,你需要定义一个服务接口,然后实现这个接口。例如,我们有一个`HelloHessianService`接口,包含一个`sayHello`方法。 `...

    hessian与spring整合的jar包

    4. 在客户端,通过Spring的`HessianClientInterceptor`或者直接使用`HessianProxyFactory`来创建Hessian代理,调用远程服务。 5. 配置服务器端(如Tomcat)以部署Spring应用上下文和Hessian服务。 6. 运行并测试服务...

    基于spring+hessian框架的webservice实例

    接着,客户端可以通过`myHessianClient` bean调用远程服务: ```java @Autowired private MyService myHessianClient; public void callService() { String result = myHessianClient.sayHello("World"); System...

    spring、hessian通过tomcat的简单环境应用源代码

    5. **客户端调用**:在客户端,同样使用Spring配置来创建HessianProxyFactoryBean,指向服务器的URL,这样就可以通过本地调用的方式,透明地访问远程Hessian服务。 6. **部署与运行**:将整个项目打包成WAR文件,...

    Hessian与spring整合

    Spring Security可以与Hessian整合,提供安全的远程服务访问。 8. **测试与监控**:为了确保服务的稳定性和可靠性,我们需要编写单元测试和集成测试,同时可以借助Spring Boot Actuator等工具,监控服务的运行状态...

    spring springmvc hessian rpc客户端及服务端示例demo

    本示例着重介绍如何在Spring和SpringMVC框架中集成Hessian RPC,以实现客户端和服务端的通信。 Hessian是一种轻量级的二进制Web服务协议,由Caucho公司开发。它具有较高的传输效率,支持Java和.NET等多种语言,特别...

    spring boot整合hessian的示例

    Spring Boot 整合 Hessian 的示例 在本文中,我们将通过实例代码来介绍如何将 Hessian 集成到 Spring Boot 应用程序中。Hessian 是一个基于 RPC(Remote Procedure Call,远程过程调用)的轻量级框架,它提供了一个...

    spring mvc hessian maven简单实例

    客户端使用Hessian时,需要创建一个HessianProxyFactory实例,并通过它来创建远程服务的代理对象。以下是一个简单的Hessian客户端示例: ```java import com.caucho.hessian.client.HessianProxyFactory; public ...

    Hessian(Spring集成的)的应用与研究

    Spring框架为了提供远程服务调用的支持,将其集成到自己的服务中,使得开发者能够利用Hessian的特性来实现高效、轻量级的服务间通信。本文将深入探讨Hessian在Spring中的应用以及相关研究。 一、Hessian简介 ...

    Hessian RPC-RMI技术 整合Structs Spring Hibernate Ibatis

    将Hessian与Structs整合,可以在Structs的Action中定义服务接口,通过Hessian调用远程服务,将结果返回给前端视图。 3. **Spring框架**: Spring作为全面的Java企业级应用框架,提供了强大的依赖注入和AOP(面向切...

    Spring 实现远程访问详解——rmi

    Spring为各种远程访问技术提供集成工具类。Spring远程访问通过使用普通POJOs,能更容易的开发远程访问服务。目前,Spring远程访问的主要技术如下: 1. 远程调用RMI(Remote Method Invocation): 通过使用 ...

    hessian-demo示例

    通过这个“hessian-demo”示例,开发者可以学习如何在实际项目中集成Hessian,实现高效、轻量级的远程服务调用。同时,结合Spring和Jetty,我们可以快速搭建和部署服务,提高开发效率。在实际应用中,还可以考虑使用...

    Hessian 使用小结

    - Spring集成Hessian:http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/remoting.html 通过这些资源,开发者可以更深入地理解并应用Hessian在实际项目中的各种场景。

    外部接口调用 使用spring4+hessian4实例(二)

    三、Spring 4集成Hessian 4步骤 1. **创建服务提供者**:首先,我们需要定义一个服务接口及其实现。例如: ```java public interface HelloService { String sayHello(String name); } @Service(...

    hessian3.1和spring2.5的结合

    标题 "Hessian3.1与Spring2.5的整合" 涉及的是在Java开发环境中,如何将Hessian远程调用服务与Spring框架相结合,以便实现高效、轻量级的分布式服务通信。Hessian是一种二进制协议,它允许远程方法调用(RMI)在HTTP上...

    hessian远程通信

    Spring是一个广泛使用的Java企业级应用框架,它提供了强大的依赖注入、AOP(面向切面编程)以及服务治理等功能,能够帮助我们更好地管理和集成Hessian服务。 首先,我们需要在服务端创建一个Hessian服务。这通常...

    Springmvc+Hibernate+Hessian架包整合

    Spring MVC、Hibernate和Hessian的整合通常用于构建分布式微服务架构。具体步骤如下: 1. **配置Spring MVC**:在Spring MVC中配置Hessian的Servlet,以便处理Hessian请求。这通常涉及在web.xml中添加...

Global site tag (gtag.js) - Google Analytics