含实例源码博客推荐:http://blog.csdn.net/julyness/article/details/49023581

简介:

Hessian是一个简单的连接Web服务的二进制协议。

  • 客户端和服务端不依赖于其他任何jar,比起webService 它显得轻量许多,比如使用xfire包含核心库和客户端的jar,大小达到了10M ,而最新的hessian-4.0.7  jar大小也只有不到400K.
  • 更适合二进制的传输,比起webService.Hessian的 传输速度要高于webService.
  • 支持Java,c#,Flex(actionscrpit)

配置:

Hessian的访问分为客户端和服务端,首先都要有Hessian的jar包:

<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.</version>
</dependency>

首先在pom中添加Hessian的依赖,确保客户端和服务端都有这个jar文件。

接下来我们来看看服务端怎么配置,首先是web.xml文件:

[html] view plain copy
<!-- Hessian通过Servlet提供远程服务,需要将某个匹配的模式映射到hessian服务中, -->
<!-- spring的dispatcherServlet能完成此功能,DispatcherServlet可将匹配模式的请求转发到Hessian服务, -->
<!-- web.xml只是定义了“请求转发器”,该转发器将匹配/remoting/*的请求截获, 转发给context的bean处理。 -->
<!-- 而HessianServiceExporter提供bean服务。 -->
<servlet>
<servlet-name>remoting</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>remoting</servlet-name>
<url-pattern>/remoting/*</url-pattern>
</servlet-mapping>

和Spring集成,我们不再使用这个类:

<servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>  

这里是拦截所有包含remoting的请求,servlet的名称为remoting,注意这个名称,一会又用到。

然后看看这个文件remoting-servlet.xml是干什么用的呢?

<?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"
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 name="/userClientServiceRemote" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="userClientServiceRemote"/>
<property name="serviceInterface" value="com.darren.comm.client.user.service.UserClientService"/>
</bean>
</beans>

首先在WEB-INF目录下,我们不用在别的地方配置去引用到这个文件,主要靠它的名字,它的名字是这样构成的servet-name + servlet,那么servlet-name是什么呢,就是上边提到的remoting,刚好,于是它的名字就叫remoting-servlet.xml

文件的内容就是提供一个bean供客户端使用,  ref="userClientServiceRemote"/>这个依赖是通过Spring扫描后注入的一个bean。

注意:这个bean的名称要加斜线,和普通的bean不同

看一看接口的实现类是怎么配置的:

package com.darren.back.client.user.service.impl;  

import java.util.List;  

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import com.darren.back.back.user.service.UserService;
import com.darren.comm.client.user.service.UserClientService;
import com.darren.comm.exception.BusinessException;
import com.darren.comm.user.po.User;
import com.darren.comm.vo.ResultHandle; /**
* 用户远程服务接口的实现
*
* @author zhangpanfeng
*
*/
@Component("userClientServiceRemote")
public class UserClientServiceImpl implements UserClientService {
private static final Log LOG = LogFactory.getLog(UserClientServiceImpl.class);
/**
* 注入用户服务
*/
@Autowired
private UserService userService; public ResultHandle<List<User>> findAllUsers() {
ResultHandle<List<User>> resultHandle = new ResultHandle<List<User>>();
try {
List<User> userList = userService.findAllUsers();
resultHandle.setContent(userList);
} catch (BusinessException e) {
LOG.error("Error method <findAllUsers>");
LOG.error(e);
resultHandle.setErrorCode(e.getErrorCode());
resultHandle.setMessage(e.getMessage());
} return resultHandle;
}
}

好了,到此为止,服务端已配好了,接下来看看客户端怎么访问

客户端引入一个const.properties配置文件,内容如下:

darren_back.serviceUrl=http://localhost:9999/darren_back/remoting  

注:这里服务端的端口是9999

这个url包含remoting,所以会走Hessian的路线。

客户端需要配一个bean:

<!-- 用户接口 -->
<bean id="userClientService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
<property name="serviceUrl" value="${darren_back.serviceUrl}/userClientServiceRemote" />
<property name="serviceInterface" value="com.darren.comm.client.user.service.UserClientService" />
<property name="chunkedPost" value="false" />
<property name="overloadEnabled" value="true" />
</bean>

这样的话,客户端的控制器就可以使用这个bean来访问服务端的内容了

package com.darren.web.user.action;  

import java.util.List;  

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import com.darren.comm.client.user.service.UserClientService;
import com.darren.comm.exception.BusinessException;
import com.darren.comm.user.po.User;
import com.darren.comm.utils.StringUtil;
import com.darren.comm.vo.ClientMessage;
import com.darren.comm.vo.ResultHandle;
import com.darren.web.user.service.UserService; /**
* 用户控制器
*
* @author zhangpanfeng
*
*/
@Controller
public class UserAction { @Autowired
private UserClientService userClientService; @RequestMapping(value = "/login")
public String login(Model model, User user) throws BusinessException {
ClientMessage clientMessage = new ClientMessage();
String target = "/home"; ResultHandle<List<User>> resultHandle = userClientService.findAllUsers();
List<User> userList = resultHandle.getContent();
if (userList != null) {
for (User u : userList) {
System.out.println(u);
}
} return target;
} }

我们运行一下看看结果:

[plain] view plain copy
User [id=135e1bd1--447a-aebb-d1d807c519fd, userName=, password=BCBE3365E6AC95EA2C0343A2395834DD, createTime=Thu Apr :: GMT+: , updateTime=null]
User [id=2c1214b4-ea09-42f9-9daa-5bf7de1edeaf, userName=qqq, password=B2CA678B4C936F905FB82F2733F5297F, createTime=Thu Apr :: GMT+: , updateTime=null]
User [id=485786f6--4f72-8c34-1539e6e3b67d, userName=, password=96E79218965EB72C92A549DD5A330112, createTime=Thu Apr :: GMT+: , updateTime=null]
User [id=b0cab9c2-201c-4fc0-bf65-e4a8a8bb004a, userName=darren, password=96E79218965EB72C92A549DD5A330112, createTime=Wed Apr :: GMT+: , updateTime=null]
User [id=e284f6d0-b871-49e8--6f0118172ff5, userName=aaa, password=47BCE5C74F589F4867DBD57E9CA9F808, createTime=Thu Apr :: GMT+: , updateTime=null]
这是打印的结果信息,到此走通。

漏掉一个问题,我们需要看看ResultHandle类和User类
package com.darren.comm.vo;  

import java.io.Serializable;  

/**
* 远程调用的返回对象
*
* @author zhangpanfeng
*
* @param <T>
*/
public class ResultHandle<T> implements Serializable {
private static final long serialVersionUID = -5396872858744255371L;
/**
* 返回信息
*/
private String message;
/**
* 错误代码
*/
private String errorCode;
/**
* 返回内容
*/
private T content; public String getMessage() {
return message;
} public void setMessage(String message) {
this.message = message;
} public String getErrorCode() {
return errorCode;
} public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
} public T getContent() {
return content;
} public void setContent(T content) {
this.content = content;
}
}
package com.darren.comm.user.po;  

import com.darren.comm.base.po.BaseEntity;  

public class User extends BaseEntity {
private static final long serialVersionUID = 8380375210393218806L;
/**
* 用户ID
*/
private String id;
/**
* 用户名
*/
private String userName;
/**
* 密码
*/
private String password;
/**
* 确认密码
*/
private String confirmPassword; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} 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 getConfirmPassword() {
return confirmPassword;
} public void setConfirmPassword(String confirmPassword) {
this.confirmPassword = confirmPassword;
} @Override
public String toString() {
return "User [id=" + id + ", userName=" + userName + ", password=" + password + ", createTime=" + createTime
+ ", updateTime=" + updateTime + "]";
}
}
[java] view plain copy
package com.darren.comm.base.po; import java.io.Serializable;
import java.util.Date; /**
* 基础实体类
*
* @author zhangpanfeng
*
*/
public class BaseEntity implements Serializable {
private static final long serialVersionUID = -7982965810132366752L;
/**
* 创建时间
*/
protected Date createTime;
/**
* 更新时间
*/
protected Date updateTime; public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} public Date getUpdateTime() {
return updateTime;
} public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
} }
这些类都被序列化了,为什么要序列化,我们先来看看序列化的作用:

a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI(Remote Method Invocation,远程方法调用)传输对象的时候;
所以是要序列化的,否则会报错的。

Hessian整合Spring的更多相关文章

  1. CXF整合spring

    近公司需要弄webservics,还说不用框架整合(提倡使用hessian,他们既然说与操作系统有兼容问题,由于人员单薄,不得不屈服,哎),我想了老半天没弄明白他说的不用框架整合spring,尝试过直 ...

  2. Dubbo想要个网关怎么办?试试整合Spring Cloud Gateway

    一.背景 在微服务架构中 API网关 非常重要,网关作为全局流量入口并不单单是一个反向路由,更多的是把各个边缘服务(Web层)的各种共性需求抽取出来放在一个公共的"服务"(网关)中 ...

  3. 【Java EE 学习 81】【CXF框架】【CXF整合Spring】

    一.CXF简介 CXF是Apache公司下的项目,CXF=Celtix+Xfire:它支持soap1.1.soap1.2,而且能够和spring进行快速无缝整合. 另外jax-ws是Sun公司发布的一 ...

  4. Mybatis整合Spring

    根据官方的说法,在ibatis3,也就是Mybatis3问世之前,Spring3的开发工作就已经完成了,所以Spring3中还是没有对Mybatis3的支持.因此由Mybatis社区自己开发了一个My ...

  5. mybatis入门_一对多,多对多映射以及整合spring框架

    一.一对多映射. 1.1 一对多映射之根据多的一方关联查询一的一方 示例:查询出具体的订单信息,同时也查询出来订单的用户信息. 引入的订单表如下所示: 框选出来的为具体的外键. 订单的Pojo类如下所 ...

  6. 《SSM框架搭建》三.整合spring web

    感谢学习http://blog.csdn.net/zhshulin/article/details/37956105#,还是修改了spring到最新的版本和接口开发示例 根据前一篇日志,已经有了myb ...

  7. Maven 整合 spring profile实现多环境自动切换

    Maven 整合 spring profile实现多环境自动切换 时间:2014-03-19 15:32来源:Internet 作者:Internet 点击:525次 profile主要用在项目多环境 ...

  8. TinyFrame续篇:整合Spring IOC实现依赖注入

    上一篇主要讲解了如何搭建基于CodeFirst的ORM,并且在章节末我们获取了上下文对象的实例:BookContext.这节主要承接上一篇,来讲解如何整合Spring IOC容器实现控制反转,依赖注入 ...

  9. Ehcache 整合Spring 使用页面、对象缓存

    Ehcache 整合Spring 使用页面.对象缓存 Ehcache在很多项目中都出现过,用法也比较简单.一 般的加些配置就可以了,而且Ehcache可以对页面.对象.数据进行缓存,同时支持集群/分布 ...

随机推荐

  1. 如何使用mysql存储树形关系

    最近遇到业务的一个类似文件系统的存储需求,对于如何在mysql中存储一颗树进行了一些讨论,分享一下,看看有没有更优的解决方案. 一.现有情况 首先,先假设有这么一颗树,一共9个节点,1是root节点, ...

  2. .NET程序员提高效率的70多个开发工具

    工欲善其事,必先利其器,没有好的工具,怎么能高效的开发出高质量的代码呢?本文为各ASP.NET 开发者介绍一些高效实用的工具,涉及SQL 管理,VS插件,内存管理,诊断工具等,涉及开发过程的各个环节, ...

  3. Git_远程仓库

    到目前为止,我们已经掌握了如何在Git仓库里对一个文件进行时光穿梭,你再也不用担心文件备份或者丢失的问题了. 可是有用过集中式版本控制系统SVN的童鞋会站出来说,这些功能在SVN里早就有了,没看出Gi ...

  4. php远程获取图片或文件信息(get_headers,fsocketopen,curl)

    <?php if(!function_exists("remote_filesize")){ /** * 获取远程或本地文件信息 * @param string $strUr ...

  5. lanmp安装一(centos+apache+nginx+mysql+php=lanmp地址下载)

    背景 centos7 官网地址https://www.centos.org/download/ 下载选择DVD版进入(也就是标准版,系统齐全) 点击任何一个国家的下载链接 下载地址  http://m ...

  6. 通过adb把apk安装到系统分区

    通过adb把apk安装到系统分区 以谷歌拼音为例:GooglePinyin1.4.2.apk提取出so文件libjni_googlepinyinime_4.solibjni_googlepinyini ...

  7. ELNEC Programmer

    BeeHive204 Very fast universal 4x 48-pindrive concurrent multiprogramming system with ISP capability ...

  8. 关于ANDROID模拟器的一些事

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 继上一篇Android Studio VS Eclipse的文章后接着来分享AnDevCo ...

  9. Adding an instance to a MEF container

    How can you add an already created instance to a MEF container/cataloge to use when resolving Import ...

  10. 音频视频解决方案:GStreamer/ffmpeg/ffdshow/directshow/vfw

    音频视频编程相关:GStreamer/ffmpeg/directshow/vfw linux和window下几种流行的音频视频编程框架作一个总结,防止自己迷惘,免于晕头转向. 一.GStreamer ...