软件环境: JDK1.6、Spring3.0.5、Hibernate3.2.2、Hessian3.1.5
参考Spring Documents:中文|英文
<!-- 扫描并加注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>
参考:
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();
}
}
}
<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>
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已经关闭。参考