文档章节

Spring+Hibernate整合Hessian

dexterman
 dexterman
发布于 2013/07/30 10:19
字数 727
阅读 945
收藏 2
点赞 0
评论 0

软件环境: JDK1.6、Spring3.0.5、Hibernate3.2.2、Hessian3.1.5

参考Spring Documents:中文|英文

服务端:

###1. remoting-servlet.xml <!-- 扫描并加注HessianService使用的bean --> <context:annotation-config /> <!-- <context:component-scan base-package="com.**" /> -->

<!--Hessian 启动BeanNameMapping 映射功能,以httpRequest作为处理Adapter-->
<!-- <bean
    class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    <property name="defaultHandler" ref="httpRequestHandlerAdapter" />
</bean> -->

<!-- Hessian 方式以Http进行传递 -->
<!-- <bean id="httpRequestHandlerAdapter" class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" /> -->
    
    <!-- 解决Hibernate实体对象bean中集合对象延迟加载lazyLoad,
        导致Hessian客户端抛出no session or session closed异常的问题 -->
<bean id="lazySerializer" class="com.test.webservice.LazyHibernateSerializerFactory"></bean>

<!-- UnifiedUser -->
<bean id="unifiedUserService" class="com.test.manager.impl.UnifiedUserServiceImpl" />
<bean name="/UnifiedUserService" class="org.springframework.remoting.caucho.HessianServiceExporter">
	<property name="serializerFactory" ref="lazySerializer"/>
	<property name="service" ref="unifiedUserService" />
	<property name="serviceInterface" value="com.test.manager.UnifiedUserService"/>
</bean>

###2. LazyHibernateSerializerFactory实现
参考: https://github.com/resthub/spring-amqp-hessian/issues/5

引用: http://code.google.com/p/rich-hibernate-lazy/wiki/HessianWithLazyHibernate

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Hibernate;
import org.hibernate.collection.PersistentList;
import org.hibernate.collection.PersistentMap;
import org.hibernate.collection.PersistentSet;

import com.caucho.hessian.io.AbstractHessianOutput;
import com.caucho.hessian.io.CollectionSerializer;
import com.caucho.hessian.io.HessianProtocolException;
import com.caucho.hessian.io.JavaSerializer;
import com.caucho.hessian.io.MapSerializer;
import com.caucho.hessian.io.Serializer;
import com.caucho.hessian.io.SerializerFactory;

/**
 * 处理:Hessian远程调用时,对象序列化hibernate实体bean中集合对象延迟加载问题 ,
 * 		采取将集合对象替换为空集合。
 * 
 *
 */
public class LazyHibernateSerializerFactory extends SerializerFactory {
	public static   String versionString = org.hibernate.Version.getVersionString();
	
	@Override
	public Serializer getSerializer(Class cls) throws HessianProtocolException {
		try {
			if(versionString.startsWith("3") &&Class.forName("org.hibernate.collection.PersistentCollection")
                    .isAssignableFrom(cls)){
				return new LazySerializerForHibernate3(cls); 
			}else if(versionString.startsWith("4") &&   
    Class.forName("org.hibernate.collection.spi.PersistentCollection").isAssignableFrom(cls)){
				return new LazySerializerForHibernate4(cls); 
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		return super.getSerializer(cls);
	}
}

class LazySerializerForHibernate3 extends JavaSerializer {

	public LazySerializerForHibernate3(Class cls) {
		super(cls);
	}
	
	CollectionSerializer collectionSeiralizer = new CollectionSerializer();
	MapSerializer mapSerializer = new MapSerializer();

	/**
	 * @Title: writeObject
	 * @Description: TODO(override hessian write)
	 * @param @param object
	 * @param @param out
	 * @param @throws IOException
	 * @return void
	 * @throws
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void writeObject(Object object, AbstractHessianOutput out)
			throws IOException {

		boolean ifHaveInit = Hibernate.isInitialized(object);
		Object obj = convertPersistent(object);
		if (ifHaveInit && object!=null) {
			out.writeObject(obj);  
            out.flush();
			return;
		}
		if (PersistentMap.class.isAssignableFrom(object.getClass())) {
			mapSerializer.writeObject(new HashMap(), out);
		} else {
			collectionSeiralizer.writeObject(new ArrayList(), out);
		}

	}
	
	@SuppressWarnings("unchecked")
	public static List convertListFromPersistentList(PersistentList plist) {
		List list = new ArrayList();
		if (plist != null) {
			for (int i = 0; i < plist.size(); i++) {
				list.add(plist.get(i));
			}
		}
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public static Set convertSetFromPersistentSet(PersistentSet pset){
		Set set = new HashSet();
		if (pset != null) {
			for (int i = 0; i < pset.size(); i++) {
				set.add(pset.toArray()[i]);
			}
		}
		return set;
	}
	
	public static Object convertPersistent(Object obj){
		 
		if(obj.getClass().isAssignableFrom(PersistentSet.class)){
			return convertSetFromPersistentSet((PersistentSet)obj);
		}else if (obj.getClass().isAssignableFrom(PersistentList.class)){
			return convertListFromPersistentList((PersistentList)obj);
		}else{
			return obj;
		}
	}
}

class LazySerializerForHibernate4 extends JavaSerializer {

	public LazySerializerForHibernate4(Class cls) {
		super(cls);
	}
	
	CollectionSerializer collectionSeiralizer = new CollectionSerializer();

	MapSerializer mapSerializer = new MapSerializer();

	/**
	 * @Title: writeObject
	 * @Description: TODO(override hessian write)
	 * @param @param object
	 * @param @param out
	 * @param @throws IOException
	 * @return void
	 * @throws
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void writeObject(Object object, AbstractHessianOutput out)
			throws IOException {

		boolean ifHaveInit = Hibernate.isInitialized(object);

		if (ifHaveInit) {
			out.writeObject(object);
			out.flush();
			return;
		}

		try {
			if (Class
					.forName("org.hibernate.collection.internal.PersistentMap")
					.isAssignableFrom(object.getClass())) {
				mapSerializer.writeObject(new HashMap(), out);
			} else {
				collectionSeiralizer.writeObject(new ArrayList(), out);
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

###3. web.xml 中添加

<filter>
	<filter-name>osivFilter</filter-name>
	<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
    <!-- Hessian -->
    <!-- 解决 Hibernate session 在Hessian客户端序列化对象前提前关闭问题 -->
<filter-mapping>
	<filter-name>osivFilter</filter-name>
	<url-pattern>/remoting/*</url-pattern>
</filter-mapping>
    
    <!-- Hessian -->
<servlet>
    <servlet-name>hessian</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/config/application-context.xml
			,/WEB-INF/config/remoting-servlet.xml
		</param-value>
	</init-param>
</servlet>
<servlet-mapping>
    <servlet-name>hessian</servlet-name>
    <url-pattern>/remoting/*</url-pattern>
</servlet-mapping>

客户端:

###1. HessianClient.java

<!-- lang: java -->
import com.caucho.hessian.client.HessianProxyFactory;
import service.UnifiedUserMng;

public class HessianClient {
	
	public static void main(String[] args) throws Exception {
		// 远程调用地址
		String url = "http://localhost:8080/remoting/UnifiedUserService";
		// 默认写法
		HessianProxyFactory factory = new HessianProxyFactory(); // 实例化
		UnifiedUserService base = (UnifiedUserService) factory.create(UnifiedUserMng.class, url);
		// 调用接口,并打印结果
		System.out.println(base.getByUsername("admin").getEmail());
	}
}

总结

Hibernate抛出no session or session closed原因:Hessian调用服务器服务,序列化Hibernate持久化对象中集合对象(Set)时,session已经关闭。参考

© 著作权归作者所有

共有 人打赏支持
dexterman
粉丝 5
博文 29
码字总数 11697
作品 0
广州
程序员
Hibernate4.3+Spring4.2 整合问题

其实Spring+Hibernate的整合非常简单,只需要配置一个xml文件就可以将spring+hibernate整合起来。下面就以为一个添加用户的例子来整合这个: 首先实体必不可少的: 然后是实体对应的hbm文件(...

Mr_K ⋅ 2016/07/12 ⋅ 2

SpringMVC整合Hessian

SpringMVC整合HessianSpring整合Hessian的demo网上一堆,适用于Srping+Struts2+Mybatis。但是SpirngMVC整合Hessina的也是很常见的,毕竟SpringMVC已经慢慢代替了Struts2。那么问题来了,因为...

大山_ ⋅ 2016/11/08 ⋅ 0

spring整合hibernate(注解、xml)applicationContext.xml配置

每次ssh框架整合都很麻烦,今天有空余时间总结下(主要总结spring+hibernate): 1.注解方式整合: applicationContext.xml配置文件: <?xml version="1.0" encoding="UTF-8"?><beans xmlns...

18号 ⋅ 2013/04/12 ⋅ 0

spring怎么对session进行管理,控制关闭

用spring+hibernate整合,,,在dao层查询了某个对象后,,,到service层后 想拿到关联对象里面的其他值,,,,但是取值的时候 报session已经关闭,,怎么控制session的关闭...

alone: ⋅ 2012/02/21 ⋅ 8

浅谈Hessian远程调用及其使用

1.1 概述 Hessian是一个轻量级的remoting onhttp工具,是由 caucho 提供的一种开源的远程通讯协议。相比WebService,Hessian更简单、快捷、同时支持跨语言通讯。Hessian采用的是二进制RPC协议...

科比可比克 ⋅ 2016/06/29 ⋅ 1

com.caucho.hessian.client.HessianConnectionException: 500

最近在spring中整合Hessian报 com.caucho.hessian.client.HessianConnectionException: 500: java.io.IOException: Server returned HTTP response code: 500 for URL: http://127.0.0.1:80......

开源大法好啊 ⋅ 2016/09/27 ⋅ 0

基于Spring Boot的全注解版Hessian服务

首先你得先了解常见的Hessian的spring配置方式,即XML配置方式,不知道的可参考一下网上的博客,如: 1. Spring4整合Hessian4(MavenWeb实例) 2. hessian系列之三:与Spring集成 现在我们将...

Robinson_L ⋅ 2016/09/12 ⋅ 0

自己动手整合 Hessian 到 Hasor 中发布服务

Hessian 是一种通信协议,使用 Hessian 可以实现跨平台的方法调用,有点类似 SOAP。您可以使用下面任意一种语言通过 Hessian 协议进行互相调用,Hessian 本身使用的是二进制传输格式。 好了废...

哈库纳 ⋅ 2013/12/25 ⋅ 3

Java程序员从笨鸟到菜鸟之(七十九)细谈Spring(八)spring+hibernate整合基本详解

由于Spring和Hibernate处于不同的层次,Spring关心的是业务逻辑之间的组合关系,Spring提供了对他们的强大的管理能力, 而Hibernate完成了OR的映射,使开发人员不用再去关心SQL语句,直接与对...

长平狐 ⋅ 2012/11/12 ⋅ 0

JFinal如何整合hessian?

@JFinal 你好,想跟你请教个问题: 能给个JFinal整合hessian的例子吗?或者有什么好的其他推荐也可以。

Romotc ⋅ 2013/08/14 ⋅ 3

没有更多内容

加载失败,请刷新页面

加载更多

下一页

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 今天 ⋅ 0

Java8新增的DateTimeFormatter与SimpleDateFormat的区别

两者最大的区别是,Java8的DateTimeFormatter也是线程安全的,而SimpleDateFormat并不是线程安全。 在并发环境下使用SimpleDateFormat 为了能够在多线程环境下使用SimpleDateFormat,有这三种...

人觉非常君 ⋅ 今天 ⋅ 0

多线程如何控制执行顺序

线程的生命周期说明: 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、...

MarinJ_Shao ⋅ 今天 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Django第一期

安装Django 去https://www.djangoproject.com/download/ 下载最新版的Django,然后解压放到Anaconda\Lib\site-packages目录下,然后cmd进入此目录,输入安装命令: python setup.py install ...

大不了敲一辈子代码 ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部