21

我试图让 JAXB 与我的一个 groovy 类一起工作,但是,它似乎不起作用,但 java 版本可以。这是代码...

以下是场景:

如果 2 和 3 未注释,则可以正常工作。

如果未注释 1 和 4,我会得到:

 com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException:
       2 counts of IllegalAnnotationExceptions
 groovy.lang.MetaClass is an interface, and JAXB can't handle interfaces.

如果未注释 1 和 5,我会得到:

  javax.xml.bind.JAXBException: class org.oclc.presentations.simplejaxb.PlayerGroovy
        nor any of its super class is known to this context.

有任何想法吗?

爪哇:

    import javax.xml.bind.annotation.XmlRootElement;

    @XmlRootElement
    public class Player {
    }

时髦的:

    import javax.xml.bind.annotation.XmlRootElement

    @XmlRootElement
    public class PlayerGroovy {
    }

测试:

    import org.junit.Test
    import javax.xml.bind.JAXBContext
    import javax.xml.bind.Marshaller
    import org.junit.Assert

    class PlayerTest {
        @Test
        public void testJaXB(){
            //1 PlayerGroovy player = new PlayerGroovy()
            //2 Player player = new Player()
            StringWriter writer = new StringWriter();
            //3 JAXBContext context = JAXBContext.newInstance(Player.class);
            //4 JAXBContext context = JAXBContext.newInstance(PlayerGroovy.class);
            //5 JAXBContext context = JAXBContext.newInstance(PlayerGroovy.getClass());
            Marshaller m = context.createMarshaller();
            m.marshal(player, writer);
            println(writer)
            Assert.assertTrue(true)
        }
    }
4

3 回答 3

22

取消注释 1 和 4 是使用 Groovy 设置 JAXB 的正确方法。它不起作用的原因是每个 Groovy 类都有一个 metaClass 属性。JAXB 试图将其公开为显然失败的 JAXB 属性。由于您自己没有声明 metaClass 属性,因此无法对其进行注释以让 JAXB 忽略它。相反,您将 XmlAccessType 设置为 NONE。这会禁用 JAXB 对要作为 XML 元素公开的属性的自动发现。完成此操作后,您需要显式声明要公开的任何字段。

例子:

@XmlAccessorType( XmlAccessType.NONE )
@XmlRootElement
public class PlayerGroovy {
    @XmlAttribute
    String value
}
于 2009-07-24T14:10:00.627 回答
16

我在公开 Grails GORM 对象时遇到了同样的问题。在研究了上面发布的解决方案后@XmlAccessorType( XmlAccessType.NONE ),我很快就厌倦了将所有内容标记为@XmlAttribute.

我使用以下方法取得了很大的成功:

@XmlAccessorType( XmlAccessType.FIELD )
@XmlRootElement
public class PlayerGroovy {
    String value
}

请参阅:XmlAccessType

感谢最初的答案让我朝着正确的方向开始。

于 2009-10-21T17:05:45.390 回答
1

该解决方案似乎不适用于抽象子类。我认为这是因为编译器不会生成getMetaClass覆盖代码。我最终模仿了这个问题的步骤如下:

@XmlAccessorType(XmlAccessType.NONE)
package groovy.lang;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

是的,这有点奇怪。就我而言,我有这样的代码:

package pkg;
abstract class ScriptMomma extends groovy.lang.Script {
    // write some nice supporting code here
}

为了执行我的脚本,我有:

def config = new org.codehaus.groovy.control.CompilerConfiguration()
config.scriptBaseClass = 'pkg.ScriptMomma'
ScriptMomma mine = new GroovyShell(config).evaluate(scriptFile, 'TheOne')

我更喜欢更好的解决方案,但现在这就是我所拥有的。

于 2014-01-17T05:48:22.440 回答