grails.converters.JSON 除了少数属性

发布于 2024-11-06 02:30:13 字数 389 浏览 4 评论 0原文

我正在使用 grails-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 属性之外的所有属性)?

I am using grails-1.3.2 and hbase-0.2.4.

I have the following domain class:

class MyClass{
  String val1
  String val2
  String val3

   //----

 }

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

        String valAsJson = (myClass as JSON)

        render valAsJson 
     }
}

My question is, is any short way render only part of properties(for example render all except val3 property) ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

柒夜笙歌凉 2024-11-13 02:30:13

你可以这样做:

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 应用程序中使用它。

You can do something like this :

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 = {
  }
}

If you know how to create our own plugin, then just create one plugin for this, so that you can use it across all the grails applications.

药祭#氼 2024-11-13 02:30:13

如果您只想将 MyClass 的实例呈现为 JSON,不包括某些属性,这里有一个使用 Grails 提供的 JSONBuilder 类的解决方案

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

If you simply want to render an instance of MyClass as JSON, excluding certain properties, here's a solution that uses the JSONBuilder class provided by 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')
     }
}
以为你会在 2024-11-13 02:30:13

如果您只想始终包含特定属性,那么您确实需要使用 ObjectMarshaller 接口。请参阅 这篇文章了解更多详细信息。

If you want to only include specific properties all the time, you would really want to use the ObjectMarshaller interface. See this article for more details.

顾忌 2024-11-13 02:30:13

或者,您可以只创建所需属性的映射,然后将它们编码为 JSON

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

要排除属性,您需要执行类似的操作(未经测试)

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

Or, you could just create a map of the properties you wanted, then encode them as JSON

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

To exclude properties, you would need to do something like this (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
夕嗳→ 2024-11-13 02:30:13

JSON Exclusion Marshaller 插件

我最近需要解决这个问题。我继续将解决方案打包到一个插件中,该插件允许您轻松地从 JSON 转换器的输出中排除类属性。它可以在 Grails 插件门户上找到。

安装插件后,您将可以访问一种方法在 grails.converters.JSON 类上,名为 exceptFor*()。

可以在这里找到更广泛的文档:如何使用 JSON 排除 Marshaller

但基本上它可以如下使用:

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 在幕后添加的。无论如何,教师不需要看到任何这些属性。

该插件对我很有帮助...我希望其他人也发现它有帮助。

The JSON Exclusion Marshaller Plugin

I needed to solve this problem recently. I went ahead and packaged the solution into a plugin that allows you to easily exclude class properties from the JSON converter's output. It is available on the Grails Plugin Portal.

After you install the plugin, you will have access to a method on the grails.converters.JSON class called excludeFor*().

More extensive documentation can be found here: How to use the JSON Exclusion Marshaller

But basically it can be used as such:

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(...) creates a named object marshaller called "excludeForTeachers". The marshaller excludes three properties of the student object from the resulting JSON output. the 'socialSecurityNumber' property is explicitly defined in the class, while the 'id' property was added by GORM behind the scenes. In any case, teachers don't need to see any of those properties.

The plugin is serving me well... I hope others find it helpful too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文