【问题标题】:Reflectively save domain class instances in Grails在 Grails 中反射性地保存域类实例
【发布时间】:2014-06-29 09:14:12
【问题描述】:

问题如下:我想处理一个带有 JSON 正文的 POST 请求。主体由 JSON 对象数组组成,无需进一步嵌套,即简单的 HashMap。所有这些对象都代表来自 Android 应用程序的 JSON 序列化域类,它们将在我的 Grails 应用程序中具有它们的对应项。我正在考虑解析 JSON 正文,遍历每个元素并将每个节点保存为其对应的域类实例。

a) 我应该如何保存实例?我对 Grails/Groovy 很陌生,所以请原谅任何重大错误。到目前为止的代码是

public static Object JSONArray2Instances(String json, Class type) {

    def slurper = new JsonSlurper()
    def result = slurper.parseText(json)
    //we only want to parse JSON Arrays
    if (!(result instanceof JSONArray))
        return null
    result.each {
        def instance = it.asType(type)


        // now I need to save to domain class!

    }
}

b) 我在哪里放置相应的代码?目前它位于 /grails-app/src/groovy 中。测试去哪儿了? (因为它不是一个“真正的”Grails 组件)
c) 中间命令对象是否更合适?

【问题讨论】:

    标签: json grails reflection polymorphism


    【解决方案1】:

    您的代码应该进入处理请求的控制器。请看一下 gson-grails plugin 提供了如何序列化和反序列化对象并将它们映射到域对象的示例。请查看 grails 基础知识,其中讨论了 grails 应用程序和布局中使用的约定。 grails 网站上有很好的例子。希望这会有所帮助

    【讨论】:

    • 谢谢大家,但这不是我想要的。事实上,这并不是回到基础场景。如果我知道要绑定到哪个域类,我会使用控制器,但问题是我事先不知道它。我有一组 JSON 对象,每个对象都可以对应于任何域类,它们都派生自同一个超类。所以,如果这是描述它的正确方式,我想使用“反射”进行绑定。
    • 您不必为每个域类都设置控制器。由于您将接受 JSON 对象数组,因此可以在一个控制器中处理它们,并且您可以将其委托给将处理此 JSON 对象的服务类。您确实知道哪个 JSON 对象映射到哪个域类,您只需要遍历您的数据,然后将其持久化。我看不出问题出在哪里
    • 好的,有道理,所以回顾一下:我在一个控制器中处理 JSON 主体,它对应于一个“抽象”域类,委托给一个服务,该服务迭代每个对象,然后将每个对象持久化到数据库。但是,我还无法从 grails-gson 文档中理解包含 [{..},{...},...] 样式的 JSON 的 POST 请求如何适用。我的意思是,如果这样的数组会自动绑定到多个域类实例,但如果没有发生,我将如何将其转换为 JSON 数组,以便稍后在服务中对其进行迭代?
    【解决方案2】:

    根据 allthenutsandbolts 的评论提供的帮助,我解决了我的问题如下。 :(不需要 Grails-Gson 插件)

    N2696AdminAction 为域类的名称

    在我的控制器中:

    class N2696AdminActionController extends RestfulController{
    
        static responseFormats = ['json', 'xml']
    
    
        def JSONHandlerService
    
    
        N2696AdminActionController() {
            super(N2696AdminAction)
        }
    
        @Override
        @Transactional
        def save(){
            if (request!=null)
            JSONHandlerService.instancesfromJSON(request.JSON)
        }
    }
    

    然后我将坚持委托给我的服务,如下所示

    类 JSONHandlerService {

    def instancesfromJSON(Object request){
    
        //we only want to parse JSON Arrays
        if (!(request instanceof JSONArray))
        return null
        request.each {
    
            def domainClass = Class.forName("${it.type}",
    

    是的,Thread.currentThread().getContextClassLoader())

            def newDomainObject = domainClass.newInstance(it)
            newDomainObject.save(failOnError:true, flush:true, insert: true)
    
    
        }
    

    } }

    type 是一个 Json 属性,它包含我的班级的完整(包括包)名称。这样,我可以使用相同的 POST 请求保存到多个域类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多