Пользовательский преобразователь Simple XML не сериализуется из xml в объект java

У меня есть аннотированный класс Simple XML, который я хочу использовать для сериализации/десериализации. У меня есть массив byte[], который я использую с пользовательским конвертером, но он не работает при методе чтения.

Вот мой аннотированный объект Simple XML

@Root
public class Device implements Serializable
{
    @Element
    @Convert(ByteArrayConverter.class)
    protected byte[] imageRef;
...
}

Вот мой преобразователь

import org.simpleframework.xml.convert.Converter;
import org.simpleframework.xml.stream.InputNode;
import org.simpleframework.xml.stream.OutputNode;

public class ByteArrayConverter implements Converter<byte[]>
{

    @Override
    public byte[] read(InputNode node) throws Exception 
    {
        String value = node.getValue();
        //return value.getBytes();
                return new byte[]{1,2,3,4,5};
    }

    @Override
    public void write(OutputNode node, byte[] byteArray) throws Exception 
    {       
        node.setValue("something");     
    }         
}

Вот мой XML с именем device.xml

<device>
    <imageRef>AQIDBAU=</imageRef>
</device>

Вот мой код сериализации, который терпит неудачу

Strategy strategy = new AnnotationStrategy();
Serializer serializer = new Persister(strategy);
File file = new File("device.xml");     
Device device = serializer.read(Device.class, file);

Я поставил точку останова в методе ByteArrayConverter.read() и сказал, что он выполняется правильно и возвращает массив байтов. Однако после этого где-то в Simple XML я получаю это

Исключение в потоке «основной» org.simpleframework.xml.core.InstantiationException: несовместимый класс [B для поля «imageRef», защищенный байт [] com.test.Device.imageRef в строке 4 в org.simpleframework.xml.core.Factory. getOverride(Factory.java:147) в org.simpleframework.xml.core.PrimitiveFactory.getInstance(PrimitiveFactory.java:82) в org.simpleframework.xml.core.Primitive.readElement(Primitive.java:186) в org.simpleframework .xml.core.Primitive.read(Primitive.java:124) в org.simpleframework.xml.core.Composite.readVariable(Composite.java:623) в org.simpleframework.xml.core.Composite.readInstance(Composite.java :573) в org.simpleframework.xml.core.Composite.readUnion(Composite.java:549) в org.simpleframework.xml.core.Composite.readElement(Composite.java:532) в org.simpleframework.xml.core. Composite.readElements(Composite.java:445) на org.simpleframework.xml.core.Composite.access$400(Composite.java:59) на org.simplefra mework.xml.core.Composite$Builder.read(Composite.java:1383) в org.simpleframework.xml.core.Composite.read(Composite.java:201) в org.simpleframework.xml.core.Composite.read( Composite.java:148) в org.simpleframework.xml.core.Traverser.read(Traverser.java:92) в org.simpleframework.xml.core.Persister.read(Persister.java:625) в org.simpleframework.xml .core.Persister.read(Persister.java:606) в org.simpleframework.xml.core.Persister.read(Persister.java:584) в org.simpleframework.xml.core.Persister.read(Persister.java:543 ) в org.simpleframework.xml.core.Persister.read(Persister.java:521) в org.simpleframework.xml.core.Persister.read(Persister.java:426)

Любые указатели будут полезны.


person lazyguy    schedule 10.07.2013    source источник


Ответы (1)


Вы используете массив примитивного типа, это может вызвать исключение. Закодирован ли ваш массив байтов (например, base64)? Если вы используете кодировку, вы должны позаботиться об этом и в read() / write().

Converter здесь не лучший выбор, лучше взять Transform. С ними вы можете самостоятельно реализовать преобразование Object ‹-> String.

Вот очень простой пример:

public class ByteArrayTransformer implements Transform<byte[]>
{
    @Override
    public byte[] read(String value) throws Exception
    {
        /*
         * TODO: Implement proper encoding
         */
        return value.getBytes();
    }


    @Override
    public String write(byte[] value) throws Exception
    {
        /*
         * TODO: Implement proper encoding
         */
        return new String(value);
    }

}

Это позволяет удалить конвертор (аннотация поля @Convert и AnnotationStrategy).

И, наконец, вот как связать трансформатор:

RegistryMatcher m = new RegistryMatcher();
m.bind(byte[].class, new ByteArrayTransformer());

Serializer ser = new Persister(m);

Device d = ser.read(Device.class, f);
person ollo    schedule 15.07.2013
comment
Дело в том, что объекты Transform можно зарегистрировать только глобально (как в вашем примере, через реестр). В некоторых случаях наличие аннотации @Convert действительно полезно. Между прочим, я слишком застрял с конвертером, который не работает на моей стороне. - person SRG; 24.10.2013