Сериализация интерфейса JAXB для проблем XML (карта <String, ISomeInterface> не работает) - PullRequest
4 голосов
/ 10 февраля 2012

Я пытаюсь сериализовать интерфейс к XML с использованием JAXB 2.2.4, но когда у меня есть интерфейс внутри объекта Map <>, он взрывается и выдает мне ошибку:

com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 отсчета IllegalAnnotationExceptions com.test.IInterface2 - это интерфейс, и JAXB не может обрабатывать интерфейсы.эта проблема связана со следующим местоположением: на com.test.IInterface2 на общедоступной java.util.Map com.test.Interface1Impl.getI2 () на com.test.Interface1Impl com.test.IInterface2 не имеет значения по умолчанию без аргументовконструктор.эта проблема связана со следующим местоположением: на com.test.IInterface2 на общедоступной java.util.Map com.test.Interface1Impl.getI2 () на 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;
        }
    }

1 Ответ

5 голосов
/ 10 февраля 2012

Чтобы получить следующий вывод, вы можете сделать следующее (см. Ниже):

<?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 для обработкиMap<String, IInterface2>.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, удаленными из немодельных классов:

main

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);
}

Interface2Impl

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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...