2010-08-13 62 views
1

我有以下代码:IllegalAnnotationsException SetMultimap是一个接口,而JAXB无法处理接口

private SetMultimap<String, Dynamic> dynamicFields = TreeMultimap.create(Ordering.natural(), new Comparator<Dynamic>() { 
    @Override 
    public int compare(Dynamic o1, Dynamic o2) { 
    return o1.getTitle().compareTo(o2.getTitle()); 
    } 
}); 

使我有以下异常。

IllegalAnnotationsException SetMultimap is an interface, and JAXB can't handle interfaces 

我的问题是,如何走到这一步不工作,但这样做:

List<Dynamic> test = new ArrayList<Dynamic>(); 

我怎样才能解决SetMultimap使JAXB是幸福?

+0

JAXB从哪里进来? – skaffman 2010-08-13 11:42:34

+0

它与这个问题有关吗? – 2010-08-13 11:55:10

+0

是的,它是相关的。没有关于JAXB如何找到该接口的上下文。 – skaffman 2010-08-14 11:06:08

回答

1

列表/ ArrayList和SetMultimap之间的区别在于,一个是Java集合,另一个是外部的数据结构正常的Java收集层次结构这意味着JAXB认为它是一个普通的类。

JAXB规范不支持接口。您可能正在使用也不支持接口的Metro JAXB实现。一些JAXB实现如MOXy可以支持接口,但一些JAX-WS的实现依赖于特定的JAXB IMPL,而代以JAXB实现并不总是可能的:

你最好的办法是使用参数级别注释将SetMultimap转换为可由JAXB处理的类:

1

您需要添加注释,告诉JAXB可能的运行时类型的引用,就像这样:

@XmlElements({ 
@XmlElement(type = TreeMultimap.class, name = "treeMultimap"), 
@XmlElement(type = MultiHashMap.class, name = "hashMultimap") 
}) 
private SetMultimap<String, Dynamic> dynamicFields = TreeMultimap.create(Ordering.natural(), new Comparator<Dynamic>() { 
    @Override 
    public int compare(Dynamic o1, Dynamic o2) { 
    return o1.getTitle().compareTo(o2.getTitle()); 
    } 
}); 

有了上面的代码,你也可以用MultiHashMap的实例替换该字段,如果你想。您需要为每种可能的运行时类型添加一个@XmlElement。如果你永远不会使用hash多重映射,一个@XmlElementTreeMultimap.class是不够的:

@XmlElement(type = TreeMultimap.class, name = "treeMultimap") 
private SetMultimap<String, Dynamic> dynamicFields = TreeMultimap.create(Ordering.natural(), new Comparator<Dynamic>() { 
    @Override 
    public int compare(Dynamic o1, Dynamic o2) { 
    return o1.getTitle().compareTo(o2.getTitle()); 
    } 
}); 
+0

这没有奏效。我收到异常说: 'com.google.common.collect.TreeMultimap没有一个无参数默认构造函数.' TreeMultimap确实没有任何无参数的默认构造函数。也许它不起作用。 – 2010-08-13 14:02:10

+0

JAXB有点疯狂,因为它期望每个对象都有一个默认构造函数和可变成员。不是很好的IMO。但是,有几种方法可以解决这个问题。在你的情况下,我会去参加工厂班。使用@XmlType(factoryClass = MyFactory.class ...)为包装级别(如果可能,尚未尝试过)或子类TreeMultimap声明TreeMultimap的工厂。 – 2010-08-13 16:10:11

+0

如果我们在SO中有这个工作版本,那将是非常好的。 :)虽然我非常尊重明星川口康介,但我一直认为他在做JAXB的时候很无聊,而且还没有完成。 – 2010-08-15 16:55:26

相关问题