我如何让Groovy和JAXB一起玩得很好

Jac*_*kie 21 java groovy jaxb

我试图让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.
Run Code Online (Sandbox Code Playgroud)

如果取消注释1和5,我得到:

  javax.xml.bind.JAXBException: class org.oclc.presentations.simplejaxb.PlayerGroovy
        nor any of its super class is known to this context.
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Java的:

    import javax.xml.bind.annotation.XmlRootElement;

    @XmlRootElement
    public class Player {
    }
Run Code Online (Sandbox Code Playgroud)

Groovy的:

    import javax.xml.bind.annotation.XmlRootElement

    @XmlRootElement
    public class PlayerGroovy {
    }
Run Code Online (Sandbox Code Playgroud)

测试:

    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)
        }
    }
Run Code Online (Sandbox Code Playgroud)

Chr*_*ail 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
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*dis 16

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

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

@XmlAccessorType( XmlAccessType.FIELD )
@XmlRootElement
public class PlayerGroovy {
    String value
}
Run Code Online (Sandbox Code Playgroud)

请参阅:XmlAccessType

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

  • 需要注意的是,这会影响返回的内容.XmlAccessType.FIELD返回"字符串值"的值,而不是getter和setter中发生的任何操作.这就是我不喜欢这种方式的原因.但是,它确实使事情变得不那么冗长. (5认同)