fastjson序列化hibernate代理和延迟加载对象出现no session异常的解决办法

fastjson序列化hibernate代理和延迟加载对象出现org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.eecn.warehouse.api.model.Tags.childTags, could not initialize proxy - no Session。

对于这个可以使用fastjson给出的扩展点,实现PropertyFilter接口,过滤不想序列化的属性。

下面的实现,如果是hibernate代理对象或者延迟加载的对象,则过滤掉,不序列化。如果有值,就序列化。

package com.test.json;

import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;

import com.alibaba.fastjson.serializer.PropertyFilter;

public class SimplePropertyFilter implements PropertyFilter {

	/**
	 * 过滤不需要被序列化的属性,主要是应用于Hibernate的代理和管理。
	 * @param object 属性所在的对象
	 * @param name 属性名
	 * @param value 属性值
	 * @return 返回false属性将被忽略,ture属性将被保留
	 */
	@Override
	public boolean apply(Object object, String name, Object value) {
		if (value instanceof HibernateProxy) {//hibernate代理对象
			LazyInitializer initializer = ((HibernateProxy) value).getHibernateLazyInitializer();
			if (initializer.isUninitialized()) {
				return false;
			}
		} else if (value instanceof PersistentCollection) {//实体关联集合一对多等
			PersistentCollection collection = (PersistentCollection) value;
			if (!collection.wasInitialized()) {
				return false;
			}
			Object val = collection.getValue();
			if (val == null) {
				return false;
			}
		}
		return true;
	}

}
当然,可以上述类,继续进行扩展,添加构造函数,配置,指定Class,以及该Class的哪个属性需要过滤。进行更精细化的控制。后面再续。

调用的时候,使用如下的方式即可,声明一个SimplePropertyFilter

@RequestMapping("/json")
	public void test(HttpServletRequest request, HttpServletResponse response) {
		Tags tags = tagsDaoImpl.get(2);
		Tags parentTags = tagsDaoImpl.get(1);
		tags.setParentTags(parentTags);
		
		long d = System.nanoTime();
		SimplePropertyFilter filter = new SimplePropertyFilter();
		String json = JSON.toJSONString(tags, filter);
		System.out.println(System.nanoTime() -d);
		
		ObjectMapper mapper = new ObjectMapper();
		mapper.registerModule(new Hibernate4Module());
		mapper.setSerializationInclusion(Include.NON_NULL);
		
		long d2 = System.nanoTime();
		String json2 = null;
		try {
			json2 = mapper.writeValueAsString(tags);
		} catch (JsonProcessingException e) {
			
		}
		System.out.println(System.nanoTime() - d2);
		System.out.println(json);
		System.out.println(json2);
	}

上面的代码同样展示了,如果使用jackson,这里使用的是jackson2,想序列化hibernate代理和延迟加载的对象,你需要引入hibernate4module。Maven以来如下

<dependency>
		  <groupId>com.fasterxml.jackson.datatype</groupId>
		  <artifactId>jackson-datatype-hibernate4</artifactId>
		  <version>2.2.3</version>
		</dependency>

绝对原创,保留一切权利。转载请注明出处。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Fastjson是一款流行的Java JSON库,用于序列化和反序列化Java对象JSON数据。在Fastjson 1.2.24及之前的版本中存在一个安全漏洞,被称为Fastjson序列化漏洞(Fastjson Deserialization Vulnerability)或Fastjson序列化漏洞。 该漏洞的主要原因是Fastjson在反序列化过程中存在一些不安全的默认行为,可能导致恶意攻击者利用特制的JSON数据触发远程代码执行。攻击者可以构造恶意JSON数据,利用漏洞触发任意代码执行、命令执行、远程命令执行等攻击。 Fastjson团队在发现漏洞后迅速发布了修复版本,并建议所有使用Fastjson的开发者升级到最新版本以解决安全问题。此外,开发者还可以采取以下措施来防止Fastjson序列化漏洞的利用: 1. 及时升级:确保使用的Fastjson版本是修复了该漏洞的最新版本。 2. 输入验证:在接收JSON数据并进行反序列化之前,对输入进行严格验证和过滤,确保只接受可信任的数据。 3. 白名单机制:限制反序列化过程中可以实例化的类和调用的方法,使用白名单机制来控制允许的操作。 4. 安全配置:通过配置Fastjson的ParserConfig,禁用自动类型识别(autoTypeSupport)或限制白名单(setAccept)等来增强安全性。 总结而言,Fastjson序列化漏洞是由于Fastjson在反序列化过程中的不安全默认行为导致的安全问题。及时升级Fastjson版本、输入验证、白名单机制和安全配置等措施可以帮助防止该漏洞的利用。 请注意,本回答仅涉及Fastjson序列化漏洞的概述,具体防范措施可能因应用场景和需求而有所不同。建议在实际开发中仔细研究并采取适合的安全措施来保护应用程序免受潜在攻击。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值