我如何让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.
如果取消注释1和5,我得到:
javax.xml.bind.JAXBException: class org.oclc.presentations.simplejaxb.PlayerGroovy nor any of its super class is known to this context.
有任何想法吗?
Java的:
import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Player { }
Groovy的:
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) } }
取消注释1和4是使用Groovy设置JAXB的正确方法。 它不起作用的原因是每个Groovy类都有一个metaClass属性。 JAXB试图将其公开为JAXB属性,这显然是失败的。 由于您没有自己声明metaClass属性,因此无法对其进行注释以使JAXB忽略它。 而是将XmlAccessType设置为NONE。 此禁用JAXB自动发现属性以作为XML元素公开。 执行此操作后,您需要显式声明要公开的任何字段。
例:
@XmlAccessorType( XmlAccessType.NONE ) @XmlRootElement public class PlayerGroovy { @XmlAttribute String value }
我在暴露Grails GORM对象时遇到了同样的问题。 在研究了上面发布的解决方案后,使用@XmlAccessorType( XmlAccessType.NONE )
,我很快就厌倦了将所有内容标记为@XmlAttribute
。
我使用以下方面取得了很大的成功:
@XmlAccessorType( XmlAccessType.FIELD ) @XmlRootElement public class PlayerGroovy { String value }
请参阅: XmlAccessType
感谢最初的答案让我开始朝着正确的方向前进。
该解决方案似乎不适用于抽象子类。 我认为这是因为编译器不生成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')
我更喜欢更好的解决方案,但现在这就是我的全部。
- 关于空间/时间的Groovy集合性能考虑因素
- 如何使用grails中的现有java类
- 将Java库添加到Netbeans Grails项目中
- 在运行时从Java编译和使用Groovy类?
- 为什么我会得到exceptionjava.lang.NoClassDefFoundError org / codehaus / groovy /?
- 如何在Java或Groovy中获取许多语言的数字的序数后缀
- 即使我在正确的域上,Selenium addCookie也会获得无效的Cookie域exception
- 在Java中使用GroovyClassLoader时,找不到类:org.apache.ivy.core.report.ResolveReport
- 将sourcesJar任务添加到自定义Gradle插件