我尝试将 grails 域类序列化为 Maps 或类似的,以便能够将其存储在 memcached 中。
我只想读取对象,不需要 gorm crud。只是在不破坏它们所拥有的那种界面的情况下阅读它们。
例如:我可以将域转换为地图,因为它不会像
.<property>
或.findall
或类似那样破坏访问界面
首先,我尝试进行手动序列化,但很容易出错。所以我需要更通用的东西。
然后我尝试用 grails 编解码器序列化为地图。
但是我得到 StackOverFlowException。
我还尝试将所有域标记为可序列化,但是当我将它们从 memcached 带回时我需要重新附加每个域以避免休眠错误,如 org.hibernate.LazyInitializationException: 无法初始化代理 - 无会话
你知道实现这个的方法吗?
谷歌搜索类似“在 memcached 中存储域类”并发现这不是一个常见问题是非常令人沮丧的。
我还没有看到这样做的开箱即用的解决方案,但如果你想保持它的通用性,你可以手动(并始终如一地)这样做:
def yourDomainInst = DefaultGrailsDomainClass(YourDomainClazz)
List listOfOnlyPersistantProperties = yourDomainInst.persistantProperties
def yourNewMap
yourObjects.each { obj ->
listOfOnlyPersistantProperties.each { prop ->
def propName = prop.name
yourNewMap.put(propName, obj."$propName")
}
}
类似的东西应该有用。请注意,可能有一百个错误,因为我现在无法尝试,但这是一般的想法。
例如,您可以使用
YourDomain.gormPersistentEntity.persistentProperties
仅检索域上的持久属性。
在另一个线程上阅读这个答案。
grails.converters
大部分时间都有效。目前存在 XML 和 JSON 转换器:
def person = new Person(name: "Maicon", active: true) as grails.converters.JSON
assert person == '{"name":"Maicon","version":null,"active":false}'
您可以使用setExcludes或setIncludes方法来过滤属性:
// person.includes = ['name'] // to include only name
// assert person.toString() == '{"name":"Maicon"}'
person.excludes = ['version', 'password']
assert person.toString() == '{"name":"Maicon","active":true}'
你必须有
org.grails.plugins:converters
作为依赖。如果你有org.grails:grails-plugin-rest
,那就不需要了.
Options()
自定义输出:
def generator = new JsonGenerator.Options()
.excludeNulls()
.excludeFieldsByName('version', 'password')
.build()
def person = new Person(name: "John", active: true)
assert generator.toJson(person) == '{"name":"John","active":true}'
阅读更多在这里
def json = JsonOutput.toJson(new Person(name: 'Max'))
assert json == '{"name":"Max","password":null,"active":false}'
阅读更多在这里