我试图让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 {
}
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)
}
}
答案 0 :(得分: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
}
答案 1 :(得分:15)
我在暴露Grails GORM对象时遇到了同样的问题。在使用@XmlAccessorType( XmlAccessType.NONE )
研究上面发布的解决方案后,我很快就厌倦了将所有内容标记为@XmlAttribute
。
我使用了很多成功:
@XmlAccessorType( XmlAccessType.FIELD )
@XmlRootElement
public class PlayerGroovy {
String value
}
请参阅:XmlAccessType
感谢最初的答案让我开始朝着正确的方向前进。
答案 2 :(得分:1)
该解决方案似乎不适用于抽象子类。我认为这是因为编译器不生成getMetaClass
覆盖代码。我最终模仿this question中的步骤如下:
@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')
我更喜欢更好的解决方案,但现在这就是我的全部。