Grails - grails.converters.JSON - удаление имени класса - PullRequest
12 голосов
/ 27 июня 2011

Есть ли способ удалить поле класса в преобразователе JSON?

Пример:

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

в виде строки

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

Я быпредпочитаете

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

Есть ли способ добавить еще одну строку кода в конце, чтобы удалить поле класса?

Ответы [ 7 ]

12 голосов
/ 24 сентября 2012

Вот еще один способ сделать это. Я добавил следующий код в класс домена:

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

Но, как я обнаружил, вы использовали аннотацию класса Groovy @ToString, когда вы также должны добавить 'class' для исключения параметра, например ::

@ToString(includeNames = true, includeFields = true, excludes = "metaClass,class")
7 голосов
/ 12 октября 2012

Мой предпочтительный способ сделать это:

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)
}

Это вернет все объекты из Book.getAllBoks (), но метод collect изменит ВСЕ в указанный вами формат.

3 голосов
/ 27 июня 2011

Один из вариантов - не использовать компоновщик:

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

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

Это немного менее ортогонально, так как вам нужно изменить рендеринг, если сотрудник изменился;с другой стороны, у вас больше контроля над тем, что визуализируется.

1 голос
/ 30 сентября 2016

Вы можете настроить поля, которые нужно исключить (включая имя класса), используя метод setExclude, предоставленный в grails.converters.JSON

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

и затем, вы можете использовать его так же, как в соответствии с вашими требованиями,

println converter.toString()
converter.render(new java.io.FileWriter("/path/to/my/file.xml"))
converter.render(response)
1 голос
/ 30 июля 2014
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) }
        }
    }
}

Это работает для меня.Вы можете легко передать в любое свойство исключить.Или переверните его:

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) }
        }
    }
}

Осторожно: это только для простых объектов.Если вы видите «Неправильный ключ: ожидаемый режим KEY, но был ОБЪЕКТ», это решение не для вас.:)

HP

1 голос
/ 06 сентября 2013

@ ответ wwarlock отчасти прав, я должен поместить registerObjectMarshaller в Bootstrap, он может работать.

1 голос
/ 28 июня 2011
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())
...