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应该使用子类来绑定类型(如示例中所做)。

那么也许它可能是实施中的一个错误?

因此看起来问题是Estartend的擦除是Comparable 。 如果它无法处理接口你可以尝试Object ,但我希望它也会抱怨(现在或以后)。 可能你可以使Range抽象并为每个特定的E专门化它。 我应该更多地了解JAXB。