2011-05-09 51 views
10

我正在使用grails-1.3.2和hbase-0.2.4。grails.converters.JSON几个属性除外

我有以下域类:

class MyClass{ 
    String val1 
    String val2 
    String val3 

    //---- 

} 

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

     String valAsJson = (myClass as JSON) 

     render valAsJson 
    } 
} 

我的问题是,是任何短期方式渲染性能的唯一部分(例如渲染以外的所有财产VAL3)?

回答

3

如果您只想一直包含特定属性,那么您确实需要使用ObjectMarshaller接口。有关更多详细信息,请参阅this article

+0

Gregg它的工作原理,但我想除了属性,因为我有几个域类,可以需要20个以上的属性,我想除了只有一个或two.If我没有找到其他的解决方案,除了我会用它...谢谢 – Bella 2011-05-10 11:06:32

+0

很酷的东西!你救了我的一天) – 2014-06-30 12:46:53

+0

@Gregg你认为或遇到性能问题时marshallers实施。我们在2个项目中使用了它们,并且我们体验了它们。有没有其他方法呢? – 2015-08-07 08:46:51

5

你可以做这样的事情:

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

+0

谢谢你的回答...它不适用于hbase,我找不到类似的hbase。 – Bella 2011-05-09 13:40:40

+2

你应该参考你得到代码http://foxgem.blogspot的位置。com/2010/06/return-partial-domain-class.html – 2012-06-11 13:32:44

3

或者,你可以只制作一张你想要的属性,然后对其进行编码为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 
+0

@tim_yates ..是否有类似的代码除外属性? – Bella 2011-05-09 13:43:11

+0

添加了我认为应该工作的内容......但未对其进行测试...如果您尝试了它,并且它能正常工作,您可以告诉我吗? – 2011-05-09 13:55:24

+0

它的工作,但它不呈现我的班级名称。 – Bella 2011-05-09 15:35:17

2

如果你只是想呈现的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') 
    } 
} 
+0

它不适合我。 – Bella 2011-05-10 07:25:07

1

的JSON排除的Marshaller插件

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

install the plugin之后,您将有权访问名为excludeFor *()的grails.converters.JSON类上的方法。

更广泛的文档可以在这里找到:How to use the JSON Exclusion 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添加。无论如何,教师不需要看到任何这些属性。

该插件正在为我服务......我希望别人也发现它也有帮助。