2012-02-09 14 views
4

JAXB 2.2.4を使用してXMLへのインターフェイスをシリアル化しようとしていますが、マップ内にインターフェイスがある場合、そして、私にエラーを与える:JAXB XMLインターフェイスのシリアル化インターフェイス(Map <String、ISomeInterface>が機能しない)

com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions com.test.IInterface2 is an interface, and JAXB can't handle interfaces. this problem is related to the following location: at com.test.IInterface2 at public java.util.Map com.test.Interface1Impl.getI2() at com.test.Interface1Impl com.test.IInterface2 does not have a no-arg default constructor. this problem is related to the following location: at com.test.IInterface2 at public java.util.Map com.test.Interface1Impl.getI2() at com.test.Interface1Impl

このコードは、テストされ、私は地図<を削除する場合は作品>、とさえ私はリスト<を使用している場合、それが動作するように得ている>が、地図についての何かがあるされています<> JAXBは好きではありません。

これは私が実行しているコードですが、これを修正する方法が分かっている場合は教えてください!

package com.test; 
    import java.io.StringWriter; 
    import javax.xml.bind.JAXBContext; 
    import javax.xml.bind.JAXBException; 
    import javax.xml.bind.Marshaller; 
    import javax.xml.bind.annotation.XmlSeeAlso; 

    @XmlSeeAlso({Interface2Impl.class}) 
    public class main 
    { 

     /** 
     * @param args 
     */ 

     public static void main(String[] args) { 

      IInterface1 i1 = new Interface1Impl(); 
      i1.setA("SET A VALUE"); 
      i1.setB("Set B VALUE"); 
      IInterface2 i2 = new Interface2Impl(); 
      i2.setC("X"); 
      i2.setD("Y"); 
      i1.getI2().put("SOMVAL",i2); 

      String retval = null; 
      try { 
       StringWriter writer = new StringWriter(); 
       JAXBContext context = JAXBContext.newInstance(Interface1Impl.class, Interface2Impl.class); 
       Marshaller m = context.createMarshaller(); 
       m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
       m.marshal(i1, writer);  
       retval = writer.toString(); 
      } catch (JAXBException ex) { 
       //TODO: Log the error here! 
       retval = ex.toString(); 
      } 
      System.out.println(retval); 

     } 
    } 

package com.test; 
    import java.util.Map; 
    import javax.xml.bind.annotation.XmlRootElement; 
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 
    import com.sun.xml.bind.AnyTypeAdapter; 
    @XmlRootElement 
    @XmlJavaTypeAdapter(AnyTypeAdapter.class) 
    public interface IInterface1 
    { 
     Map<String,IInterface2> getI2(); 
     String getA(); 
     String getB(); 
     void setA(String a); 
     void setB(String b); 
     void setI2(Map<String,IInterface2> i2); 
    } 

package com.test; 
    import java.util.HashMap; 
    import java.util.Map; 
    import javax.xml.bind.annotation.XmlRootElement; 
    @XmlRootElement 
    public class Interface1Impl implements IInterface1 
    { 
     Map<String,IInterface2> i2 = new HashMap<String,IInterface2>(); 
     String a; 
     String b; 
     public Interface1Impl() 
     { 
     } 

     public String getA() { 
      return a; 
     } 
     public void setA(String a) { 
      this.a = a; 
     } 
     public String getB() { 
      return b; 
     } 
     public void setB(String b) { 
      this.b = b; 
     } 

     public Map<String,IInterface2> getI2() { 
      return i2; 
     } 

     public void setI2(Map<String,IInterface2> i2) { 
      this.i2 = i2; 
     } 
    } 

package com.test; 

    import javax.xml.bind.annotation.XmlRootElement; 
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 
    import com.sun.xml.bind.AnyTypeAdapter; 
    @XmlRootElement 
    @XmlJavaTypeAdapter(AnyTypeAdapter.class) 
    public interface IInterface2 
    { 
     String getC(); 
     String getD(); 

     void setC(String c); 
     void setD(String d); 
    } 

package com.test; 
    import javax.xml.bind.annotation.XmlRootElement; 
    @XmlRootElement 
    public class Interface2Impl implements IInterface2 
    { 
     String c; 
     String d; 

     public Interface2Impl() 
     { 
     } 

     public String getC() { 
      return c; 
     } 
     public void setC(String c) { 
      this.c = c; 
     } 
     public String getD() { 
      return d; 
     } 
     public void setD(String d) { 
      this.d = d; 
     } 
    } 

答えて

5

あなたができる次の出力を取得するには(下記参照)、以下:私たちはMap<String, IInterface2>を処理するためにXmlAdapterを使用します

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<interface1Impl> 
    <a>SET A VALUE</a> 
    <b>Set B VALUE</b> 
    <i2> 
     <entry> 
      <key>SOMVAL</key> 
      <value> 
       <c>X</c> 
       <d>Y</d> 
      </value> 
     </entry> 
    </i2> 
</interface1Impl> 

I2Adapter。 XmlAdapterは、JAXBがマップできないオブジェクトを変換できるJAXBメカニズムです。

package com.test; 

import java.util.*; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class I2Adapter extends XmlAdapter<I2Adapter.AdaptedI2, Map<String, IInterface2>> { 

    @Override 
    public AdaptedI2 marshal(Map<String, IInterface2> v) throws Exception { 
     if(null == v) { 
      return null; 
     } 
     AdaptedI2 adaptedI2 = new AdaptedI2(); 
     for(Map.Entry<String,IInterface2> entry : v.entrySet()) { 
      adaptedI2.entry.add(new Entry(entry.getKey(), entry.getValue())); 
     } 
     return adaptedI2; 
    } 

    @Override 
    public Map<String, IInterface2> unmarshal(AdaptedI2 v) throws Exception { 
     if(null == v) { 
      return null; 
     } 
     Map<String, IInterface2> map = new HashMap<String, IInterface2>(); 
     for(Entry entry : v.entry) { 
      map.put(entry.key, entry.value); 
     } 
     return map; 
    } 

    public static class AdaptedI2 { 
     public List<Entry> entry = new ArrayList<Entry>(); 
    } 

    public static class Entry { 
     public Entry() { 
     } 

     public Entry(String key, IInterface2 value) { 
      this.key = key; 
      this.value = value; 
     } 

     public String key; 

     @XmlElement(type=Interface2Impl.class) 
     public IInterface2 value; 
    } 

} 

Interface1Impl

@XmlJavaTypeAdapterアノテーションはXmlAdapterを登録するために使用されます。この例では、i2プロパティに登録します。詳細情報以下は


については

package com.test; 

import java.util.*; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

@XmlRootElement 
public class Interface1Impl implements IInterface1 { 
    Map<String, IInterface2> i2 = new HashMap<String, IInterface2>(); 
    String a; 
    String b; 

    public Interface1Impl() { 
    } 

    public String getA() { 
     return a; 
    } 

    public void setA(String a) { 
     this.a = a; 
    } 

    public String getB() { 
     return b; 
    } 

    public void setB(String b) { 
     this.b = b; 
    } 

    @XmlJavaTypeAdapter(I2Adapter.class) 
    public Map<String, IInterface2> getI2() { 
     return i2; 
    } 

    public void setI2(Map<String, IInterface2> i2) { 
     this.i2 = i2; 
    } 
} 

は非モデルクラスから削除JAXB注釈付きモデルの残りの部分であります:

package com.test; 

import java.io.StringWriter; 
import javax.xml.bind.*; 

public class main { 

    /** 
    * @param args 
    */ 

    public static void main(String[] args) { 

     IInterface1 i1 = new Interface1Impl(); 
     i1.setA("SET A VALUE"); 
     i1.setB("Set B VALUE"); 
     IInterface2 i2 = new Interface2Impl(); 
     i2.setC("X"); 
     i2.setD("Y"); 
     i1.getI2().put("SOMVAL", i2); 

     String retval = null; 
     try { 
      StringWriter writer = new StringWriter(); 
      JAXBContext context = JAXBContext.newInstance(Interface1Impl.class, 
        Interface2Impl.class); 
      Marshaller m = context.createMarshaller(); 
      m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
      m.marshal(i1, writer); 
      retval = writer.toString(); 
     } catch (JAXBException ex) { 
      // TODO: Log the error here! 
      retval = ex.toString(); 
     } 
     System.out.println(retval); 

    } 
} 

IInterface1

package com.test; 

import java.util.Map; 

public interface IInterface1 { 
    Map<String, IInterface2> getI2(); 

    String getA(); 

    String getB(); 

    void setA(String a); 

    void setB(String b); 

    void setI2(Map<String, IInterface2> i2); 
} 

IInterface2

package com.test; 

public interface IInterface2 { 
    String getC(); 

    String getD(); 

    void setC(String c); 

    void setD(String d); 
} 

インタフェース2Impl

package com.test; 

public class Interface2Impl implements IInterface2 { 
    String c; 
    String d; 

    public Interface2Impl() { 
    } 

    public String getC() { 
     return c; 
    } 

    public void setC(String c) { 
     this.c = c; 
    } 

    public String getD() { 
     return d; 
    } 

    public void setD(String d) { 
     this.d = d; 
    } 
} 
関連する問題