欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

java.util.Map is an interface, and JAXB can't handle interfaces 解决方法,java.util.mapjaxb,如果在类中定义了接口类型

来源: javaer 分享于  点击 12776 次 点评:233

java.util.Map is an interface, and JAXB can't handle interfaces 解决方法,java.util.mapjaxb,如果在类中定义了接口类型


如果在类中定义了接口类型,然后去序列化时会出现标题的异常,堆栈如下:

Exception in thread "main" javax.xml.bind.DataBindingException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptionsJAXB annotation is placed on a method that is not a JAXB property    this problem is related to the following location:        at @javax.xml.bind.annotation.XmlTransient()        at cn.outofmemory.stable.STableMgrjava.util.Map is an interface, and JAXB can't handle interfaces.    this problem is related to the following location:        at java.util.Map        at public java.util.Map cn.outofmemory.stable.STableMgr.getsTables()        at cn.outofmemory.stable.STableMgrjava.util.Map does not have a no-arg default constructor.    this problem is related to the following location:        at java.util.Map        at public java.util.Map cn.outofmemory.stable.STableMgr.getsTables()        at cn.outofmemory.stable.STableMgr    at javax.xml.bind.JAXB._marshal(JAXB.java:549)    at javax.xml.bind.JAXB.marshal(JAXB.java:307)    at cn.outofmemory.stable.STableMgr.main(STableMgr.java:53)Caused by: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions.....

要解决这个问题需要自定义XmlAdapter,假定我们要序列化的类如下,该类有一个Map的属性。

package cn.outofmemory.stable;import java.io.File;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.xml.bind.JAXB;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlRootElement;import javax.xml.bind.annotation.XmlTransient;import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;import cn.outofmemory.pojo.Table;@XmlRootElementpublic class STableMgr {    private Map<String, List<Table>> sTables;    @XmlElement(name="sTableMap")    @XmlJavaTypeAdapter(MapAdapter.class)     public Map<String, List<Table>> getsTables() {        return sTables;    }    public void setsTables(Map<String, List<Table>>  sTables) {        this.sTables = sTables;    }    public boolean hasMTable(String srcTableName) {        if (this.sTables == null) {            return false;         }        String lowerCase = srcTableName.toLowerCase();        return this.sTables.containsKey(lowerCase);    }    public List<Table> getTables (String srcTableName) {        return this.sTables.get(srcTableName.toLowerCase());    }    public static void main (String[] args) {        STableMgr instance = new STableMgr();        Map<String, List<Table>> tableMap  = new HashMap<String, List<Table>>();        List<Table> tables = new ArrayList<Table>();        tables.add(new Table());        tableMap.put("testSrcTableKey", tables);        tableMap.put("testSrcTableKeyq", tables);        instance.setsTables(tableMap);        String tableListPath = "d:\\s-tables.xml";        File tableMgrSaveAsFile = new File(tableListPath);        JAXB.marshal(instance, tableMgrSaveAsFile);    }}

需要自己实现的Map接口的XmlAdapter实现如下:

package cn.outofmemory.stable;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.xml.bind.annotation.XmlAccessType;import javax.xml.bind.annotation.XmlAccessorType;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlElementWrapper;import javax.xml.bind.annotation.XmlTransient;import javax.xml.bind.annotation.XmlType;import javax.xml.bind.annotation.adapters.XmlAdapter;import cn.outofmemory.pojo.Table;public class MapAdapter extends XmlAdapter<MapAdapter.Converter, Map<String, List<Table>>>  {    @XmlType(name = "Converter")      @XmlAccessorType(XmlAccessType.FIELD)      public static class Converter {        @XmlTransient        private List<MapEntry> entries = new ArrayList<MapEntry>();          public void addEntry(MapEntry entry) {              entries.add(entry);          }  //      @XmlElementWrapper(name = "tableMaps")        @XmlElement(name = "entry")        public List<MapEntry> getEntries() {              return entries;          }          public static class MapEntry {              private String key;              private List<Table> value;              public MapEntry() {                  super();              }              public MapEntry(Map.Entry<String, List<Table>> entry) {                  super();                  this.key = entry.getKey();                  this.value = entry.getValue();              }              public MapEntry(String key, List<Table> value) {                  super();                  this.key = key;                  this.value = value;              }              @XmlElement(name="srcTableName")            public String getKey() {                  return key;              }              public void setKey(String key) {                  this.key = key;              }              @XmlElementWrapper(name = "sTables")            @XmlElement(name = "table")            public List<Table> getValue() {                  return value;              }              public void setValue(List<Table> value) {                  this.value = value;              }          }      }    @Override    public Map<String, List<Table>> unmarshal(Converter v) throws Exception {        Map<String, List<Table>> result = new HashMap<String, List<Table>>();          for (Converter.MapEntry e : v.getEntries()) {              result.put(e.getKey(), e.getValue());          }          return result;      }    @Override    public Converter marshal(Map<String, List<Table>> map) throws Exception {        Converter convertor = new Converter();          for (Map.Entry<String, List<Table>> entry : map.entrySet()) {              Converter.MapEntry e = new Converter.MapEntry(entry);              convertor.addEntry(e);          }          return convertor;      }}

通过自定义的MapAdapter就可以正常的使用jaxb序列化Map接口类型了。

相关栏目:

用户点评