JAXB编组和generics
我正在尝试使用JAXB的内省来编组和取消用JAXB注释标记的一些现有域对象。 大多数事情按预期工作,但是我在编写一个相当简单的类序列时遇到了很多麻烦。 这个类在许多bean上用作@XmlElement,看起来像:
public class Range<E extends Comparable> implements Serializable { protected boolean startInclusive, endInclusive; protected E start, end; public Range(){ startInclusive = endInclusive = true; } public boolean contains(E value){...} public E getEnd() { return end; } public void setEnd(E end) { this.end = end; } public boolean isEndInclusive() { return endInclusive; } public void setEndInclusive(boolean endInclusive) { this.endInclusive = endInclusive; } public E getStart() { return start; } public void setStart(E start) { this.start = start; } public boolean isStartInclusive() { return startInclusive; } public void setStartInclusive(boolean startInclusive) { this.startInclusive = startInclusive; } }
我试图做以下事情,但没有成功,JAXB仍然对Comparable接口感到愤怒。
public class DoubleRange extends Range {}
使用Range和DoubleRange作为bean getter的返回类型会产生如下exception:
java.lang.Comparable是一个接口,JAXB无法处理接口。 此问题与以下位置有关: 在java.lang.Comparable 在受保护的java.lang.Comparable com.controlpath.util.Range.start中 在example.util.Range 在example.util.DoubleRange 在public example.util.DoubleRange example.domain.SomeBean.getRange() 在example.domain.SomeBean
我意识到在大多数情况下,List 和Map 只能工作,因为JAXB规范在bean上遇到这些类型时有特殊规定,但是有什么方法可以传达我想要的JAXB内省引擎无需重新实现非通用字段的范围?
您可以通过执行以下操作编写自定义适配器(不使用JAXB的XmlAdapter):
1)声明一个接受所有类型元素并具有JAXB注释并根据需要处理它们的类(在我的示例中,我将所有内容转换为String)
@YourJAXBAnnotationsGoHere public class MyAdapter{ @XmlElement // or @XmlAttribute if you wish private String content; public MyAdapter(Object input){ if(input instanceof String){ content = (String)input; }else if(input instanceof YourFavoriteClass){ content = ((YourFavoriteClass)input).convertSomehowToString(); }else if(input instanceof .....){ content = ((.....)input).convertSomehowToString(); // and so on }else{ content = input.toString(); } } } // I would suggest to use a Map,IMyObjToStringConverter> ... // to avoid nasty if-else-instanceof things
2)在你的待编组课程中使用这个课而不是E课
笔记
- 当然,这对复杂(嵌套)数据结构不起作用。
- 你必须考虑如何再次解决这个问题,可能会更棘手。 如果它太棘手了,请等待比我更好的提议;)
怎么样
public class Range<**E extends Number**> implements Serializable { ...
-
数字是一个类
-
我敢打赌JAXB知道Number的默认编组/解组规则
对于特定类型的解组,你需要我在这里描述的XmlAdapter: JAXBinheritance,解组为封送类的子类
尝试使用Simple XML Serialization之类的东西,它支持带有许多注释的XML元素中的generics类型,例如@Element和@ElementList。 编程模型非常相似,但比JAXB更简单。
实际上,我不清楚为什么这不起作用。 似乎JAXB应该能够正确地解析特定的子类型:if(并且仅当!)此类型不是根类型(它不是根据您的描述)。 我的意思是,它只是一个豆; 所以如果用T替换直接类型的bean工作,那么通用版本iff应该使用子类来绑定类型(如示例中所做)。
那么也许它可能是实施中的一个错误?
因此看起来问题是E
在start
和end
的擦除是Comparable
。 如果它无法处理接口你可以尝试Object
,但我希望它也会抱怨(现在或以后)。 可能你可以使Range
抽象并为每个特定的E
专门化它。 我应该更多地了解JAXB。