Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   AS3 -> Java, writeObject (http://www.flasher.ru/forum/showthread.php?t=159697)

C4Grey 04.07.2011 15:42

AS3 -> Java, writeObject
 
Приветствую.
Пытаюсь отправить объект на Java-сервер. Со стандартными типами работает нормально, но с классами начинаются проблемы. Класс сериализирован(и в Java, и в AS), клиент на Java успешно отправляет объект, сервер принимает. При отправке же объекта с Flash-клиента получаю на сервере ошибку:

Код:

java.io.StreamCorruptedException: invalid stream header: 0A071744
Ошибку получаю при попытке создания входного потока:
Код:

try
{
  objectIn = new ObjectInputStream(socket.getInputStream());                               
}
catch(StreamCorruptedException e)
{
  System.out.println("Input Error: " + e.toString());
}

Подскажите, пожалуйста, в чем может быть проблема.

terbooter 04.07.2011 15:54

Похоже они сериализованы разными способами.

t4arty 04.07.2011 16:42

кодировка?

C4Grey 04.07.2011 18:32

2terbooter

Со связкой Java+Flash я первый раз имею дело, так что вполне возможно, что где-то у меня есть ошибка. Вот исходники:

Flash:

Код AS3:

package  
{       
        import flash.utils.IExternalizable;
        import flash.utils.IDataInput;
        import flash.utils.IDataOutput;       
 
        [RemoteClass(alias="DataMessage")]       
        public class DataMessage implements IExternalizable
        {               
                public var Message: String; 
                public var X:int;
                public var Y:int;
                private var _id:String;
 
                public function DataMessage()
                {
                }
 
                public function get id():String
                {
                        return _id;
                }
 
                public function readExternal(input:IDataInput):void
                {
                        _id = input.readObject() as String;
                        Message = input.readObject() as String;
                        X = input.readInt();
                        Y = input.readInt();
                }
 
                public function writeExternal(output:IDataOutput):void
                {
                        output.writeObject(id);
                        output.writeObject(Message);
                        output.writeInt(X);
                        output.writeInt(Y);
                }
        }       
}

Регистрирую в главном классе:

Код AS3:

private static const REG:* = registerClassAlias("DataMessage", DataMessage);

Java:

Код:

package FlashServer;

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

public class DataMessage implements Serializable
{
        private static final long serialVersionUID = 1L;
    public String Message;
    public int X;
    public int Y;
    private String id;
   
        public DataMessage()
        {
                id = hashCode() + "X" + System.currentTimeMillis();
        }
       
    public String getId()
    {
        return id;
    }

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
    {
        id = (String)in.readObject();
        Message = (String)in.readObject();
        X = (int)in.readInt();
        Y = (int)in.readInt();
    }       
   
    public void writeExternal(ObjectOutput out) throws IOException
    {
        out.writeObject(id);
        out.writeObject(Message);
        out.writeInt(X);
        out.writeInt(Y);
    }       

}

serialVersionUID пробовал также генерировать рандомный(Eclipse предлагает генерацию или использование такого ID по умолчанию), ошибка остается.

2t4arty
Насколько я понял мануалы, в Java кодировку можно указывать для BufferedReader, а он со строками рабоатет.

gloomyBrain 04.07.2011 18:42

Эмм... Actionscript записывает объекты в формате AMF, а java читает их по своим понятиям о сериализации... Разве это должно работать?
Я думаю, нужно либо писать свой формат и реализовать его и на сервере, и на клиенте, или прикрутить AMF к java - BlazeDS, например

C4Grey 04.07.2011 19:00

2gloomyBrain
C хелпа BlazeDS:
Цитата:

For Java objects that BlazeDS does not handle implicitly, values found in public bean properties with get/set methods and public variables are sent to the client as properties on an Object. Private properties, constants, static properties, and read-only properties, and so on, are not serialized. For ActionScript objects, public properties defined with the get/set accessors and public variables are sent to the server.

BlazeDS uses the standard Java class, java.beans.Introspector, to get property descriptors for a Java bean class. It also uses reflection to gather public fields on a class. It uses bean properties in preference to fields. The Java and ActionScript property names should match. Native Flash Player code determines how ActionScript classes are introspected on the client.

In the ActionScript class, you use the [RemoteClass(alias=" ")] metadata tag to create an ActionScript object that maps directly to the Java object. The ActionScript class to which data is converted must be used or referenced in the MXML file for it to be linked into the SWF file and available at run time.
Отсюда: http://livedocs.adobe.com/blazeds/1/...ze_data_3.html

Vier 04.07.2011 22:59

Кодировки бывают только у текста, вам передается в любом случае бинарник. serialVersionUID у сериализованного файла по идее должен совпадать. Если бинов не много я бы не морочился и передавал все, как HashMap (если коллекции корректно работают).

terbooter 05.07.2011 10:24

Java сериализация - AMF сериализация
Нужен парсер, чтобы перегонять один формат в другой.
Так ли вам важно маппить классы с помощью registerClassAlias?
Может проще использовать свой формат?

C4Grey 05.07.2011 12:06

2Vier
Вот в этом багтреке: http://bugs.sun.com/bugdatabase/view...bug_id=4968673 описывается решение похожей проблемы, но там потоки работают через ByteArray, в одном и том же приложении. Причиной возникновения ошибки называют как раз несовпадение кодировок, если я верно понял. Да, и можно ли конкретнее, как работать с HashMap?
2terbooter
Ну, в общем-то сервер-клиент у меня уже написаны, так сказать, одноразовая реализация, для конкретного проекта...а сейчас на эксперемнты потянуло, как прочитал о возможности подобной передачи объектов. Согласитесь, было бы удобно.

Vier 05.07.2011 12:50

Цитата:

Сообщение от C4Grey (Сообщение 1008835)
2Vier
Вот в этом багтреке: http://bugs.sun.com/bugdatabase/view...bug_id=4968673 описывается решение похожей проблемы, но там потоки работают через ByteArray, в одном и том же приложении. Причиной возникновения ошибки называют как раз несовпадение кодировок, если я верно понял. Да, и можно ли конкретнее, как работать с HashMap?

C4Grey, давно ничего не сериализовал в яве, но как видно ObjectInput у вас, это поток байт, у них нет кодировки как таковой ) А по ссылке бинарник с сериализованным классом представляют в виде строки, а потом делают обратное преобразование. Такой маневр в яве:
String serialized = baos.toString();
byte[] b = serialized.getBytes();
Действительно может убить кодировку.


Кодировка могла слететь только на конкретных полях, где пишется out.writeObject(Message); и читается Message = (String)in.readObject();. В общем, у вас скорее всего проблема с форматом сериализации. Просто сериализуйте класс в яве и во флеше и сравните байты )

Насчет HashMap'а вы сказали, что со стандартными типами все ок. Не очень понятно, что такое стандартные типы, возможно коллекции входят в них ))


Часовой пояс GMT +4, время: 19:31.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.