grails.converters.JSON, за исключением нескольких свойств - PullRequest
10 голосов
/ 09 мая 2011

Я использую Граайлс-1.3.2 и hbase-0.2.4.

У меня есть следующий класс домена:

class MyClass{
  String val1
  String val2
  String val3

   //----

 }

class MyClassController{
    def someAction = {
        def myClass = new MyClass()
        //----

        String valAsJson = (myClass as JSON)

        render valAsJson 
     }
}

Мой вопрос таков: можно ли каким-нибудь коротким способом отобразить только часть свойств (например, отобразить все, кроме свойства val3)?

Ответы [ 5 ]

5 голосов
/ 09 мая 2011

Вы можете сделать что-то вроде этого:

def myClass = MyClass.get(1)

 //include
 render myClass.part(include:['val1', 'val2']) as JSON

 //except
 render job.part(except:['val2','val3']) as JSON

Bootstrap.groovy:

import org.codehaus.groovy.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor as Events

class BootStrap {
 def grailsApplication

 def excludedProps = [Events.ONLOAD_EVENT,
    Events.BEFORE_DELETE_EVENT, Events.AFTER_DELETE_EVENT,
    Events.BEFORE_INSERT_EVENT, Events.AFTER_INSERT_EVENT,
    Events.BEFORE_UPDATE_EVENT, Events.AFTER_UPDATE_EVENT]

  def init = { servletContext ->
     grailsApplication.domainClasses.each{ domainClass ->
         domainClass.metaClass.part= { m ->
             def map= [:]
             if(m.'include'){
                 m.'include'.each{
                     map[it]= delegate."${it}"
                 }
             }else if(m.'except'){
                 m.'except'.addAll excludedProps
                 def props= domainClass.persistentProperties.findAll {
                     !(it.name in m.'except')
                 }
                 props.each{
                     map[it.name]= delegate."${it.name}"
                 }
             }
             return map
         }
     }
  }
  def destroy = {
  }
}

Если вы знаете, как создать наш собственный плагин, тогда простосоздайте для этого один плагин, чтобы вы могли использовать его во всех приложениях Grails.

3 голосов
/ 09 мая 2011

Или, вы можете просто создать карту свойств, которые вы хотели, а затем закодировать их как JSON

Map m = [ 'val1', 'val2' ].inject( [:] ) { map, val -> map."$val" = a."$val" ; map }
render m as JSON

Чтобы исключить свойства, вам нужно сделать что-то вроде этого (UNTESTED)

def exclude = [ 'val3' ]
Map m = new DefaultGrailsDomainClass( MyClass.class ).properties.findAll {
  !( it.name in exclude )
}.inject( [:] ) { map, val ->
  map."$val.name" = a."$val.name" ; map
}
render m as JSON
3 голосов
/ 09 мая 2011

Если вы хотите постоянно включать только определенные свойства, вам действительно нужно использовать интерфейс ObjectMarshaller.Подробнее см. в этой статье .

2 голосов
/ 09 мая 2011

Если вы просто хотите отобразить экземпляр MyClass как JSON, исключая определенные свойства, вот решение, которое использует класс JSONBuilder, предоставленный Grails

import grails.web.JSONBuilder

class MyClassController{

    def someAction = {

        def myClass = new MyClass()

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

            // Properties excluded from the JSON
            def excludes = ['class', 'metaClass', 'val3']

            if (!excludes.contains(propName)) {

                setProperty(propName, propValue)
            }
        }
        render(text: builder.toString(), contentType: 'application/json')
     }
}
1 голос
/ 30 июня 2013

Плагин JSON Exclusive Marshaller

Мне нужно было решить эту проблему недавно.Я пошел дальше и упаковал решение в плагин, который позволяет вам легко исключать свойства класса из выходных данных JSON-конвертера.Он доступен на портале плагинов Grails.

После того как вы установите плагин , у вас будет доступ к методу класса grails.converters.JSON, который называется excludeFor * ().

Более обширную документацию можно найти здесь: Как использовать маршаллера исключения JSON

Но в основном его можно использовать так:

import grails.converters.JSON

def json, resultTeachersWillSee, resultOtherStudentsWillSee

// Given a TestStudent Domain Class
def student = new TestStudent([
    firstName: "Tobias",
    lastName: "Funke",
    gradePointAverage: 3.6,
    studentID: "FS-210-7312",
    socialSecurityNumber: "555-55-5555"
])
student.save(flush: true)

// When
JSON.excludeForTeachers(TestStudent, ['socialSecurityNumber', 'id', 'class'])

JSON.use('excludeForTeachers') {
    json = new JSON(student)
}
resultTeachersWillSee = json.toString()

// Then
assert resultTeachersWillSee == '{"firstName":"Tobias",
       "gradePointAverage":3.6, "lastName":"Funke", 
       "studentID":"FS-210-7312"}'



// And When
JSON.excludeForOtherStudents(TestStudent, ['gradePointAverage', 'studentID', 
     'socialSecurityNumber', 'id', 'class'])

JSON.use('excludeForOtherStudents') {
    json = new JSON(student)
}
resultOtherStudentsWillSee = json.toString()

// Then
assert resultOtherStudentsWillSee == '{"firstName":"Tobias",
       "lastName":"Funke"}'

JSON.excludeForTeachers (...) создает маршаллер именованного объекта с именем excludeForTeachers.Маршаллер исключает три свойства объекта ученика из полученного вывода JSON.свойство socialSecurityNumber явно определено в классе, а свойство id было добавлено GORM за кулисами.В любом случае, учителям не нужно видеть ни одно из этих свойств.

Плагин хорошо мне подходит ... Надеюсь, другие тоже найдут его полезным.

...