声明:该文章转载自Spring整合Hessian访问远程服务,本人搬过来只是为了记录下学习Hessian的过程,忘此博主理解,在此感谢,等本人有能力了再学一些原创的东东,本人实践了下,hessianServer项目不是web project,由于较菜,花了一个下午才把java project转换成为web project。

项目下载:

hessianServer:http://files.cnblogs.com/ontheroad_lee/hessianServer.rar

hessianClient:http://files.cnblogs.com/ontheroad_lee/hessianClient.rar

1.1     Hessian简介

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

1.2     整合

1.2.1 概述

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

1.2.2 服务端整合

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

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

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

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

  <servlet>
<servlet-name>hessianServer</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup></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的配置文件中定义一个类型为HessianServiceExporter的bean对象。该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对应的bean的name是“/userService”,在SpringMVC的配置文件中,当一个bean的name是以“/”开始的时候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会根据指定的serviceInterface和serviceUrl属性返回一个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>

Spring整合Hessian访问远程服务的更多相关文章

  1. SpringMVC整合Hessian访问远程服务

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

  2. Spring整合Hessian

    Spring让Hessian变得不但强大,而且易用,但是易用背后,却有不少陷阱!   这个例子很简单,但实际上的确花费了我超过一小时的时间,排除了种种问题,最后问题终于水落石出.   整合以上篇Hel ...

  3. Spring整合Hessian的使用

    该文章转赞自  https://www.cnblogs.com/ontheroad_lee/p/3797239.htm 个人感觉写的非常好,刚学习,先记录下来 1.1     Hessian简介 He ...

  4. hessian的简单使用以及与spring整合

    Hessian是一个由Caucho Technology开发的轻量级二进制RPC协议.和其他Web服务的实现框架不同的是,Hessian是一个使用二进制格式传输的Web服务协议的框架,相对传统soap ...

  5. Hessian与Spring整合

    1.服务端与Spring的整合 1.1:web.xml中配置控制器 <servlet> <servlet-name>hessian</servlet-name> & ...

  6. Spring Boot数据访问之整合Mybatis

    在Mybatis整合Spring - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中谈到了Spring和Mybatis整合需要整合的点在哪些方面,需要将Mybatis中数据库连接池等相关对 ...

  7. spring与hessian整合例

    spring与hessian的简单应用实现例: 开发环境:window7 64,jdk8,tomcat8,spring4.2.5,hessian4.0 开发语言:java hessianServer端 ...

  8. 【Dubbo实战】 Dubbo+Zookeeper+Spring整合应用篇-Dubbo基于Zookeeper实现分布式服务(转)

    Dubbo与Zookeeper.Spring整合使用 Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spri ...

  9. Dubbo+Zookeeper+Spring整合应用篇-Dubbo基于Zookeeper实现分布式服务(转)

    Dubbo与Zookeeper.Spring整合使用 Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spri ...

随机推荐

  1. [Java]用于将链表变成字符串并在元素之间插入分隔符的有用函数“String.join”

    将链表变成字符串并在元素之间插入分隔符,这种动作最常见于组合sql文“select a,b,c from tb”这种场景scenario,其中a,b,c你是存贮在链表中的, 如果要加逗号要么在循环中识 ...

  2. SSH开发中 使用超链接到action 其excute方法会被执行两次 actual row count: 0; expected: 1

    由于执行两次excute,所以在做删除操作的时候会出现 Batch update returned unexpected row count from update [0]; actual row c ...

  3. LC 676. Implement Magic Dictionary

    Implement a magic directory with buildDict, and search methods. For the method buildDict, you'll be ...

  4. 微信小程序开发工具下载以及安装教程

    微信公众平台上登录你的微信小程序账号   登录进入小程序开发-工具-下载,再根据你的系统选择相对应的版本地址进行下载.   以管理员身份运行下载,点击下一步,如图所示:   下一步,就会出现许可证协议 ...

  5. Linux Openssh源码升级

    telnet服务 yum install -y telnet-server xinetd systemctl start xinetd systemctl start telnet.socket #监 ...

  6. delphi 权限控制(delphi TActionList方案)

    在软件开发中,为软件加入权限控制功能,使不同的用户有不同的使用权限,是非常重要的一项功能,由其在开发数据库方面的应用,这项功能更为重要.但是,要为一个应用加入全面的权限控制功能,又怎样实现呢?大家知道 ...

  7. Qt qss问题总结

    1.在QWidget中设定了setObjectName,就是不起作用. 解决方法重写paintEvent. #ifndef BROWSEWIDGET_H #define BROWSEWIDGET_H ...

  8. Nginx实现负载均衡的方式有哪几种呢?

    什么是负载均衡 当一台服务器的单位时间内的访问量越大时,服务器压力就越大,大到超过自身承受能力时,服务器就会崩溃.为了避免服务器崩溃,让用户有更好的体验,我们通过负载均衡的方式来分担服务器压力. 我们 ...

  9. 【机器学习】Learning to Rank 简介

    Learning to Rank 简介 去年实习时,因为项目需要,接触了一下Learning to Rank(以下简称L2R),感觉很有意思,也有很大的应用价值.L2R将机器学习的技术很好的应用到了排 ...

  10. mybatis批量更新update-设置多个字段值allowMultiQueries=true

    mybatis由于简单易用性得到大家的认可和使用 但是在批量更新操作中,网上介绍的貌似不全,正好今天做个记录,大家一起进步 在实际项目开发过程中,常有这样的需求:根据ids更新表的某一个字段值,这时的 ...