Grails XML编组:更改默认的“<list>”根元素名称</list>

时间:2014-02-06 02:15:24

标签: java xml grails serialization marshalling

默认情况下,Grails在XML中呈现List,其根目录中带有<list>元素标记。同样,它使用<map>呈现地图。我想控制根元素的名称。

如果我要返回User的ArrayList,那么我想看看:

<users>
    <user>...</user>
    <user>...</user>
</users>

如何实现上述目标?以下是要求:

  • 轻松将此序列化应用于50多个域类
  • 从开发人员那里抽象,因此在渲染域对象期间不需要显式编码(即,当调用render()respond()时,仍会传入ArrayList,而不会像{{1}那样进行显式转换/转换}})
  • 能够处理空列表的边缘情况(应该返回as MyNewType

尼斯到富人:

  • 如果此公式也可以应用于Map,那么很好:)

我在实现上述目标方面已经半成功,除了我不知道如何解释空列表案例。我实现了自己的ObjectMarshaller,它呈现了<users/>类型的所有对象。只要列表包含一个元素,我就可以检查元素的类型并确定复数标记名称应该是什么(User =&gt; users)。但是如果列表是空的,并且由于Java泛型是擦除的(除非在Groovy中有所不同?)然后我无法正确命名空列表而不是默认为List之类的东西,这是不可接受的。

我经历过的一些资源:

1 个答案:

答案 0 :(得分:3)

实现这一目标的一种方法是为CollectionMarshaller类编写一个子类,并在Grails应用程序中注册它。例如,我们可以使用以下代码在BootStrap.groovy中注册自定义实现:

import org.codehaus.groovy.grails.web.converters.marshaller.xml.CollectionMarshaller
import grails.converters.XML

class BootStrap {

  def init = { servletContext ->
    // Register custom collection marshaller for List with User instances.
    // The root element name is set to users.
    XML.registerObjectMarshaller(new CollectionMarshaller() {
        @Override
        public boolean supports(Object object) {
            object instanceof List<User>
        }

        @Override
        String getElementName(final Object o) {
            'users'
        }
    })
  }
}

为了使这个工作适用于更多的域类,我们可能会引用BootStrap.groovy中的所有域类,并循环它们以配置自定义的CollectionMarshaller实例。

对于地图,您可以扩展MapMarshaller

还在http://mrhaki.blogspot.com/2014/02/grails-goodness-customize-root-element.html

中进行了描述