Grails - grails.converters.JSON - removing the class name
Asked Answered
A

7

12

Is there a way to remove the class field in a JSON converter?

Example:

import testproject.*
import grails.converters.*  
emp = new Employee()  
emp.lastName = "Bar"  
emp as JSON  

as a string is

{"class":"testproject.Employee","id":null,"lastName":"Bar"}

I'd prefer

{"id":null,"lastName":"Bar"}

Is there a way to add one more line of code at the end to remove the class field?

Allow answered 27/6, 2011 at 16:2 Comment(1)
Check this other answer https://mcmap.net/q/922428/-grails-jsonbuilder/…Ulyanovsk
P
12

Here is yet one way to do it. I've added a next code to the domain class:

static {
    grails.converters.JSON.registerObjectMarshaller(Employee) {
    return it.properties.findAll {k,v -> k != 'class'}
    }
}

But as I found if you have used Groovy @ToString class annotation when you also must add 'class' to excludes parameter, e.g.:

@ToString(includeNames = true, includeFields = true, excludes = "metaClass,class")
Proconsulate answered 24/9, 2012 at 5:12 Comment(0)
M
7

My preferred way of doing this:

def getAllBooks() {
    def result = Book.getAllBooks().collect {
        [
            title: it.title,
            author: it.author.firstname + " " + it.author.lastname,
            pages: it.pageCount,
        ]
    }
    render(contentType: 'text/json', text: result as JSON)
}

This will return all the objects from Book.getAllBoks() but the collect method will change ALL into the format you specify.

Muggy answered 12/10, 2012 at 8:34 Comment(0)
F
3

One alternative is to not use the builder:

def myAction = {
    def emp = new Employee()
    emp.lastName = 'Bar'

    render(contentType: 'text/json') {
        id = emp.id
        lastName = emp.lastName
    }
}

This is a bit less orthogonal since you'd need to change your rendering if Employee changes; on the other hand, you have more control over what gets rendered.

Fashionable answered 27/6, 2011 at 16:9 Comment(0)
D
1

@wwarlock's answer is partly right, I have to put the registerObjectMarshaller on Bootstrap, it can work.

Dutra answered 27/6, 2011 at 16:2 Comment(0)
S
1
import testproject.*
import grails.converters.*  
import grails.web.JSONBuilder

def emp = new Employee()  
emp.lastName = "Bar"  

def excludedProperties = ['class', 'metaClass']

def builder = new JSONBuilder.build {
  emp.properties.each {propName, propValue ->

  if (!(propName in excludedProperties)) {
    setProperty(propName, propValue)
  }
}

render(contentType: 'text/json', text: builder.toString())
Staple answered 28/6, 2011 at 8:1 Comment(0)
K
1
def a = Employee.list()

String[] excludedProperties=['class', 'metaClass']
render(contentType: "text/json") {
    employees = array {
        a.each {
            employee it.properties.findAll { k,v -> !(k in excludedProperties) }
        }
    }
}

This works for me. You can easily pass in any property to exclude. Or turn it around:

def a = Employee.list()

String[] includedProperties=['id', 'lastName']
render(contentType: "text/json") {
    employees = array {
        a.each {
            employee it.properties.findAll { k,v -> (k in includedProperties) }
        }
    }
}

Beware: This is only for simple objects. If you see "Misplaced key: expected mode of KEY but was OBJECT" this solution is not for you. :)

HP

Kerchief answered 30/7, 2014 at 13:1 Comment(0)
B
1

You can customize the fields to be excluded (including the class name) using the setExcludes method provided in the grails.converters.JSON

def converter = emp  as JSON
converter.setExcludes(Employee.class, ["class",""])

and then, you can use it just like according to your requirements,

println converter.toString()
converter.render(new java.io.FileWriter("/path/to/my/file.xml"))
converter.render(response)
Brassy answered 30/9, 2016 at 9:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.