[英]Grails render encodeAsJSON GORM with ObjectId (mongodb)
Here is a Model 这是一个模型
import org.bson.types.ObjectId
class Foo{
ObjectId id
String name
}
And here an action 这是一个动作
def action = {
render(status:200, contentType:"application/json") {
['foo' : Foo.get(params.id)]
}
}
The action will return something like this 该动作将返回类似这样的内容
{"foo":{"class":"Foo","id":{"class":"org.bson.types.ObjectId","inc":340737392,"machine":-2019394572,"new":false,"time":1299107672000},"name":"fooName"]}
My question is, how can I send in the json the toString of the ObjectId, I don't want this 我的问题是,我该如何在json中发送ObjectId的toString,我不要这个
"id":{"class":"org.bson.types.ObjectId","inc":340737392,"machine":-2019394572,"new":false,"time":1299107672000}
I want something more like 我想要更多类似的东西
"id":18893828183
I know I can select the parameters I want like: 我知道我可以选择想要的参数:
def foo = Foo.get(params.id)
['foo' : 'Foo' :[id:foo.id.toString(), name:foo.name]]
But I don't want to declare always what I want to return as json, I want to return all the object, Foo.get(params.id).encodeAsJSON()... 但是我不想总是声明要作为json返回的内容,我想返回所有对象Foo.get(params.id).encodeAsJSON()...
Is there a way to override encodeAsJSON() 有没有一种方法可以重写encodeAsJSON()
I already tried to add this 我已经尝试添加
class Foo{
....
static transients : ['idStr']
def getIdStr(){
return this.id.toString()
}
....
}
But it's ignored in the encodeAsJSON() 但是在encodeAsJSON()中被忽略
I even tried this 我什至尝试过
class Foo{
....
def toJSON(){
def obj = this.encodeAsJSON()
def json = new JsonSlurper().parseText(obj);
json.idString = this.id.toString()
return json.toString()
}
...
}
this "works", but no.... 这个“作品”,但是不。
because after this 因为在此之后
render(status:200, contentType:"application/json") {
['foo' : Foo.get(params.id).toJSON()]
}
the render encode the json, so everything is "escaped".... 渲染对json进行编码,因此所有内容都被“转义了”。
So what do you think is the solution, with a builder always defining what I want to return? 那么您认为解决方案是什么,而构建器总是定义我要返回的内容?
Hope, I made my question clear.... 希望,我已经明确了我的问题...。
I'll start with the builder, hope you can give me another simpler / cleaner solution... 我将从构建器开始,希望您能给我另一个更简单/更简洁的解决方案...
Thanks 谢谢
edit I just did a method that returns the object as a map so now I do something like this 编辑我只是做了一个将对象作为地图返回的方法,所以现在我做这样的事情
render(status:200, contentType:"application/json") {
['foo' : getFooAsMap(Foo.get(params.id))]
}
Register this objectMarshaller at Bootstarp.groovy and it will work like a charm 在Bootstarp.groovy上注册该对象Marshaller,它将像魅力一样工作
import grails.converters.JSON
import org.bson.types.ObjectId
JSON.registerObjectMarshaller(ObjectId) {
return it.toStringMongod()
}
You can do this too: 你也可以这样做:
def domainObj = YourDomainClass.get(params.id)
Map props = [:]
def domain = new DefaultGrailsDomainClass(YourDomainClass.class)
domain.properties.each{
props[it.name] = domainObj[it.name]
}
props["id"] = domainObj.id.toString()
render props as JSON
Or better yet, make it reusable. 或更妙的是,使其可重用。 Put this closure someplace handy:
将此闭合放置在方便的位置:
def mongoObjectResponse = {dobj ->
Map props = [:]
def domain = new DefaultGrailsDomainClass(YourDomainClass.class)
domain.properties.each{
props[it.name] = dobj[it.name]
}
props["id"] = dobj.id.toString()
// I like to leave room in my responses for messages and such
message = ""
obj = props
}
Then call like this from your controller: 然后从您的控制器中这样调用:
return render(contentType: "text/json") {
mongoObjectResponse.delegate = delegate
mongoObjectResponse(domainObj)
}
Just define your domain class as 只需将您的域类定义为
class Foo {
String id
String name
}
Instead of ObjectId 代替ObjectId
If you're going to be JSON-encoding your domain classes out to the web, I wonder if ObjectId might not be the best choice? 如果您要对您的域类进行JSON编码到网络上,我想知道ObjectId是否不是最佳选择? The GORM/MongoDB integration allows you to use any type for the id.
GORM / MongoDB集成允许您对ID使用任何类型。 You could just declare it as a String type (which can be assigned as a toString of an ObjectId if you like to use that for its randomness) and then you don't need to worry about this mess.
您可以将其声明为String类型(如果您出于随机性而希望将其分配为ObjectId的toString),则不必担心这种混乱。 Any performance/scalability problems from this could be analysed/dealt with later, but I wouldn't expect there to be any unless it's a very large app.
以后可能会分析/处理由此引起的任何性能/可伸缩性问题,但是除非它是一个非常大的应用程序,否则我不希望有任何问题。
Use GStrings in your map and you will get a numeric value for your ObjectId. 在地图中使用GStrings,您将获得ObjectId的数字值。 Eg
例如
render ["foo":"$foo.id"] as JSON
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.