2013-10-23 69 views
1

我在调用JAXB.marshal时使用Class AdapterDataObj将Class DataObj转换为AdaptedDataObj。@XmlJavaTypeAdapter在相同情况下被忽略


package test; 

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

@XmlJavaTypeAdapter(AdapterDataObj.class) 
public class DataObj { 
    public String bla = "I'm DataObj"; 
    public String name; 
    public DataObj(String name) { 
     this.name = name; 
    } 

    } 

package test; 
public class AdaptedDataObj { 
     public String bla="I'm AdaptedDataObj"; 
     public String name; 

     public AdaptedDataObj(String name) { 
      this.name = name; 
     } 
} 

package test; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 
public class AdapterDataObj extends XmlAdapter { 
    @Override 
    public DataObj unmarshal(AdaptedDataObj v) throws Exception { 
     return null; // not needed in this case 
    } 

    @Override 
    public AdaptedDataObj marshal(DataObj v) throws Exception { 
     System.out.println("Marschal for " + v.name + " called!"); 
     return new AdaptedDataObj(v.name); 
    } 
} 

现在我把DataObj到一个新的类和JAXB.marshal被调用这个类。输出看起来很好。我也收到调用AdaptedDataObj的消息。


package test; 
import javax.xml.bind.JAXB; 
public class Testobj { 
    public DataObj x; 
    public Testobj() { 
     x = new DataObj("Hallo World"); 
    } 

    public static void main(String[] args) throws Exception { 
     System.out.println("Testobj"); 
     System.out.println("================================="); 
     Testobj to = new Testobj(); 
     JAXB.marshal(to, System.out); 
    } 
} 

现在我改变“public DataObj x;”为“public Object x;”,因为我想不仅DataObj存储在该班。

但是在这种情况下AdapterDataObj不再被调用。 DataObj而不是AdapterDataObj被导出为xml。

任何想法的问题是什么?

我也尝试没有成功将@XmlJavaTypeAdapter添加到package-info.java。 AdapterDataObj仍未调用。我已经测试了Java 1.7.0_45和1.8.0-ea。


package test; 
import javax.xml.bind.JAXB; 
import javax.xml.bind.annotation.XmlSeeAlso; 
@XmlSeeAlso({DataObj.class}) 
public class Testobj3 { 
     public Object x; 
    public Testobj3() { 
     x = new DataObj("Hallo World"); 
    } 

    public static void main(String[] args) throws Exception { 
     System.out.println("Testobj3"); 
     System.out.println("================================="); 
     Testobj3 to3 = new Testobj3(); 
     JAXB.marshal(to3, System.out); 
    } 
} 

回答

1

根据JAXB 2.2 specification

延伸XmlAdapter和类,接口或枚举类型(即一个 程序元件上匹配的元注释@目标= {类型上指定了@XmlJavaTypeAdapter })必须在参考点适应 boundType如下:

  1. 一个属性/字段,其引用类型是boundType
  2. 一个属性/字段,其中boundType用作参数类型

所以字段/属性必须被给定类型的到JAXB认识到适配器需要被使用。

出于同样的原因,您不能在根元素上使用适配器。解释可以在封闭的JAXB问题JAXB-117中找到:

适配器是根据类型定义的,而不是实例。特别是,在 中,适配器的设计方式使得并不总是可能的, 只是从一个实例推断正确的适配器。在JAXB类

编辑 使用对象是不是很常见。也许你想存储的对象有一些共同点,所以你可以提取可以用@XmlJavaTypeAdapter注解的接口/基类。如果他们没有共同点,最好将它们存储为独立的属性。

相关问题