如何使用jaxb将对象的地图编组到另一个地图

时间:2017-04-24 14:00:54

标签: java xml java-8 jaxb

我是JAXB的新手,所以我甚至不知道我在做什么是可能的。 这是我的代码(这是故意不干净的代码:)):

Main.java:

package jaxb;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class MainTest {

    public static void main(String[] args) throws JAXBException {

        Type pt = Type.getType();

        Map<Type, TreeMap<Integer, Double>> dens = new HashMap<Type, TreeMap<Integer, Double>>();

        TreeMap<Integer, Double> ds = new TreeMap<Integer,Double>();
        ds.put(0, 10.0);
        ds.put(1, 11.0);
        ds.put(2, 4.5);

        dens.put(pt, ds);

        CloudCell cc = new CloudCell (19.9, 6, dens);

        JAXBContext context = JAXBContext.newInstance(CloudCell.class);

        Marshaller m = context.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        m.marshal(cc, System.out);
    }

}

这是Type类:

package jaxb;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
public class Type {

    @XmlElement
    private Integer stuffI;

    @XmlElement 
    private Double stuffD;

    public Integer getStuffI() {
        return stuffI;
    }

    public void setStuffI(Integer stuffI) {
        this.stuffI = stuffI;
    }

    public Double getStuffD() {
        return stuffD;
    }

    public void setStuffD(Double stuffD) {
        this.stuffD = stuffD;
    }

    public List<Double> getSizes() {
        return sizes;
    }

    public void setSizes(List<Double> sizes) {
        this.sizes = sizes;
    }

    @XmlElement
    private List<Double> sizes = new ArrayList<Double>();

    public Type(){

    }

    public Type (List<Double> sizes, double stuffD, int stuffI ){
        this.sizes.addAll(sizes);
        this.stuffD = stuffD;
        this.stuffI = stuffI;
    }

    public static Type getType(){
        double sD = 0.0;
        int sI = 1;
        List<Double> ss = new ArrayList<Double>(Arrays.asList(0.0,10.0,9.0));
        return new Type (ss, sD, sI);
    }
}

这是CloudCell条目:

package jaxb;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso(Type.class)
public class CloudCell {

    @XmlElement
    private double db;

    @XmlElement
    private int di;

    @XmlElement
    @XmlJavaTypeAdapter (MyMapAdapter.class)
    private HashMap<Type, TreeMap<Integer, Double>> densities = new HashMap<Type, TreeMap<Integer, Double>>();

    public double getDb() {
        return db;
    }

    public void setDb(double db) {
        this.db = db;
    }

    public int getDi() {
        return di;
    }

    public void setDi(int di) {
        this.di = di;
    }

    public HashMap<Type, TreeMap<Integer, Double>> getDensities() {
        return densities;
    }

    public void setDensities(HashMap<Type, TreeMap<Integer, Double>> densities) {
        this.densities = densities;
    }

    public CloudCell(){

    }

    public CloudCell (double d, int i, Map<Type, TreeMap<Integer, Double>> mp){
        this.db = d;
        this.di = i;
        densities.putAll(mp);
    }
}

以下代码是我认为适用于编组的适配器。 unmarshal仍然返回null,因为我现在没有使用它。

这是适配器:

package jaxb;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;

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

public class MyMapAdapter extends XmlAdapter<MyMapType, HashMap<Type, TreeMap<Integer, Double>>> {

    @Override
    public MyMapType marshal(HashMap<Type, TreeMap<Integer, Double>> arg0) throws Exception {
        MyMapType mt = new MyMapType();
        for (Entry<Type, TreeMap<Integer, Double>> entryMp:arg0.entrySet()){
            MyMapEntryType mmet = new MyMapEntryType();
            TreeMap<Integer, Double> dens = entryMp.getValue();
            List<DEntryType> det = new ArrayList<DEntryType>();
            for (Entry<Integer, Double> de:dens.entrySet()){
                DEntryType dt = new DEntryType();
                dt.key = de.getKey();
                dt.value = de.getValue();
                det.add(dt);
            }
            mmet.key = entryMp.getKey();
            mmet.value = det;
        }
        return mt;
    }

    @Override
    public HashMap<Type, TreeMap<Integer, Double>> unmarshal(MyMapType arg0) throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

}

和MyMapType:

package jaxb;

import java.util.ArrayList;
import java.util.List;

public class MyMapType {

    public List<MyMapEntryType> entry = new ArrayList<MyMapEntryType>();
}

MyMapEntryType:

package jaxb;

import java.util.List;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlValue;

@XmlSeeAlso(Type.class)
public class MyMapEntryType {

    @XmlAttribute
    public Type key;

    @XmlValue
    public List<DEntryType> value;
}

最后是DEntryType:

package jaxb;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlValue;

public class DEntryType {

    @XmlAttribute
    public Integer key;

    @XmlValue
    public Double value;
}

当我运行main.java时,我收到以下错误

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
@XmlAttribute/@XmlValue need to reference a Java type that maps to text in XML.
    this problem is related to the following location:
        at public jaxb.Type jaxb.MyMapEntryType.key
        at jaxb.MyMapEntryType
        at public java.util.List jaxb.MyMapType.entry
        at jaxb.MyMapType
        at private java.util.HashMap jaxb.CloudCell.densities
        at jaxb.CloudCell
@XmlAttribute/@XmlValue need to reference a Java type that maps to text in XML.
    this problem is related to the following location:
        at public java.util.List jaxb.MyMapEntryType.value
        at jaxb.MyMapEntryType
        at public java.util.List jaxb.MyMapType.entry
        at jaxb.MyMapType
        at private java.util.HashMap jaxb.CloudCell.densities
        at jaxb.CloudCell

    at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(Unknown Source)
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at javax.xml.bind.ContextFinder.newInstance(Unknown Source)
    at javax.xml.bind.ContextFinder.newInstance(Unknown Source)
    at javax.xml.bind.ContextFinder.find(Unknown Source)
    at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
    at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
    at jaxb.MainTest.main(MainTest.java:28)

0 个答案:

没有答案