Пользовательская сериализация BlazeDS вызывает RangeError

Я использую BlazeDS для связи между Java и Flash/Flex. И все работает нормально, за исключением того, что Java Null Integer становится 0 на стороне Flex.

Чтобы решить проблему с передачей нулевого целого числа Java в целое число Flash/Flex, я реализовал пользовательскую сериализацию, которая работает на стороне Java и использует отрицательные значения для выражения нулевых значений.

После реализации этого я получаю

RangeError: Error #2006: Der angegebene Index liegt außerhalb des zulässigen Bereichs.
(in english: the index is out of range)
                at ObjectInput/readObject()
                at mx.collections::ArrayList/readExternal()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ArrayList.as:586]
                at mx.collections::ArrayCollection/readExternal()[E:\dev\4.x\frameworks\projects\framework\src\mx\collections\ArrayCollection.as:147]
                at ObjectInput/readObject()
                at mx.messaging.messages::AbstractMessage/readExternal()[E:\dev\4.x\frameworks\projects\rpc\src\mx\messaging\messages\AbstractMessage.as:486]
                at mx.messaging.messages::AsyncMessage/readExternal()[E:\dev\4.x\frameworks\projects\rpc\src\mx\messaging\messages\AsyncMessage.as:170]
                at mx.messaging.messages::AcknowledgeMessage/readExternal()[E:\dev\4.x\frameworks\projects\rpc\src\mx\messaging\messages\AcknowledgeMessage.as:95]

Исключение возникает на стороне Flex при десериализации результата Java. Это список сложных объектов, содержащих этот специальный класс с пользовательской сериализацией. Поскольку такой проблемы не было, пока я не добавил пользовательскую сериализацию, я думаю, что это должно быть связано с проблемой, но я понятия не имею, что вызывает исключение.

Это код объекта с пользовательской сериализацией:

package crux.domain.dto;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;

public class NullAbleID implements Serializable, Externalizable {

    private static final long serialVersionUID = 788620879056753289L;

    private Integer id;

    public NullAbleID() {
        super();
        this.id = null;
    }

    public NullAbleID(final Integer id) {
        this.id = id;
    }

    getter, setter for ID and hashCode and equals

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {        
        out.writeObject(this.nullToNegative(this.id));                
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException {
        this.id = this.negativeToNull(in.readInt());
    }

    private int nullToNegative(Integer id) {
        if (id == null) {
            return -1;
        } else {        
            return id.intValue();
        }
    }

    private Integer negativeToNull(int flashId) {
        if (flashId < 0) {
            return null;
        } else {
            return Integer.valueOf(flashId);
        }
    }
}

Flex: два класса, потому что мы используем генерацию кода Gas3 Granite Data Service:

/**
* Generated by Gas3 v2.1.0 (Granite Data Services).
*
*/
package crux.domain.dto {

    import flash.utils.IExternalizable;

    [Bindable]
    public class NullAbleIDBase {

        public function NullAbleIDBase() {}


        private var _id:Number;

        public function set id(value:Number):void {
            _id = value;
        }
        public function get id():Number {
            return _id;
        }
    }
}

Подкласс Flex с внешним чтением и записью

package crux.domain.dto {

      import flash.utils.IDataInput;
      import flash.utils.IDataOutput;
      import flash.utils.IExternalizable;

    [Bindable]
    [RemoteClass(alias="crux.domain.dto.NullAbleID")]
    public class NullAbleID extends NullAbleIDBase implements IExternalizable{

            public function readExternal(input:IDataInput):void {
                  id = input.readInt();
            }

            public function writeExternal(output:IDataOutput):void {
                  output.writeInt(id);
            }
    }
}

Я потратил несколько часов на эту проблему, но я понятия не имею, в чем проблема. Вы видите причину исключения?


person Ralph    schedule 11.02.2011    source источник


Ответы (1)


Не уверен, что это причина проблемы, потому что я не знаю BlazeDS, но методы readExternal и writeExternal вашего класса NullAbleID не являются симметричными: вы пишете объект типа Integer в writeExternal, и вы читаете int в readExternal.

person JB Nizet    schedule 11.02.2011
comment
Большое спасибо, я хотел бы дать вам два голоса, потому что вы спасли мой день и выходные (какая жалость, что это невозможно) - В любом случае: каждый, кто прочитал этот вопрос, проблема в том, что out.writeObject на стороне Java пишут внешний метод должен быть out.writeInt - person Ralph; 11.02.2011