这是一个模型
import org.bson.types.ObjectId
class Foo{
ObjectId id
String name
}
这是一个动作
def action = {
render(status:200, contentType:"application/json") {
['foo' : Foo.get(params.id)]
}
}
该操作将返回类似这样的内容
{"foo":{"class":"Foo","id":{"class":"org.bson.types.ObjectId","inc":340737392,"machine":-2019394572,"new":false,"time":1299107672000},"name":"fooName"]}
我的问题是,如何在json中发送ObjectId的toString,我不想要这个
"id":{"class":"org.bson.types.ObjectId","inc":340737392,"machine":-2019394572,"new":false,"time":1299107672000}
我想要更像
的东西"id":18893828183
我知道我可以选择我想要的参数:
def foo = Foo.get(params.id)
['foo' : 'Foo' :[id:foo.id.toString(), name:foo.name]]
但是我不想总是声明我想要以json的形式返回,我想要返回所有对象,Foo.get(params.id).encodeAsJSON()......
有没有办法覆盖encodeAsJSON()
我已经尝试添加此
class Foo{
....
static transients : ['idStr']
def getIdStr(){
return this.id.toString()
}
....
}
但它在encodeAsJSON()
中被忽略了我甚至试过这个
class Foo{
....
def toJSON(){
def obj = this.encodeAsJSON()
def json = new JsonSlurper().parseText(obj);
json.idString = this.id.toString()
return json.toString()
}
...
}
这“有效”,但没有......
因为在此之后
render(status:200, contentType:"application/json") {
['foo' : Foo.get(params.id).toJSON()]
}
渲染对json进行编码,因此所有内容都被“转义”....
那么您认为解决方案是什么,建设者总是定义我想要返回的内容?
希望,我明白了我的问题......
我将从建造者开始,希望你能给我一个更简单/更清洁的解决方案......
由于
修改的 我刚刚做了一个将对象作为地图返回的方法,所以现在我做了类似的事情
render(status:200, contentType:"application/json") {
['foo' : getFooAsMap(Foo.get(params.id))]
}
答案 0 :(得分:3)
在Bootstarp.groovy注册此objectMarshaller,它将像魅力一样工作
import grails.converters.JSON
import org.bson.types.ObjectId
JSON.registerObjectMarshaller(ObjectId) {
return it.toStringMongod()
}
答案 1 :(得分:0)
如果你要将你的域类JSON编码到网上,我想知道ObjectId是不是最好的选择? GORM / MongoDB集成允许您使用任何类型的id。您可以将它声明为String类型(如果您希望将其用于随机性,则可以将其指定为ObjectId的toString),然后您不必担心这种混乱。任何性能/可伸缩性问题都可以在以后进行分析/处理,但除非是非常大型应用程序,否则我不会指望有任何问题。
答案 2 :(得分:0)
在地图中使用GStrings,您将获得ObjectId的数值。 E.g。
render ["foo":"$foo.id"] as JSON
答案 3 :(得分:0)
您也可以这样做:
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
或者更好,让它可重复使用。把这个封闭放在一个方便的地方:
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
}
然后从你的控制器那样打电话:
return render(contentType: "text/json") {
mongoObjectResponse.delegate = delegate
mongoObjectResponse(domainObj)
}
答案 4 :(得分:0)
只需将您的域类定义为
即可class Foo {
String id
String name
}
而不是ObjectId