2010-10-29 3 views
6

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

Мы проводим довольно много расчетов по дате, поэтому мы широко используем Joda Time во всем коде и в нашей модели домена.

Теперь мы пытаемся выяснить, как мы можем продолжать использовать Joda Time в наших DTO, которые отправляются обратно и вперед с интерфейсом Flex через BlazeDS.

Наша цель состоит в том, чтобы использовать тип Date Actionscript 3 данных на стороне Flex и иметь эту карту для нашего использования DateTime, LocalDate и LocalTime Joda времени по типам на стороне Java.

Мы можем решить проблему преобразования типа ActionScript 3 Date при вызове Java с маршаллером настраиваемого типа, подключенным к BlazeDS, но это, похоже, вызывается только для направления Flex-> Java/BlazeDS, а не для Java/BlazeDS -> Гибкое направление.

Теперь я смотрю на пользовательские версии PropertyProxy для BlazeDS, но это тоже не так.

Другая идея состояла в том, чтобы реализовать Externalizable на наших Java DTO, но это похоже на слишком много работы, особенно когда я смотрю на конкурента BlazeDS GraniteDS и демонстрирует подключение поддержки Joda Time в своей документации с помощью простого преобразователя типов!

Любые идеи оценили.

ответ

15

OK - Я нашел ответ на мой собственный. Это связано с написанием моего собственного класса конечных точек AMF + связанных классов сериализации. Я должен сказать, что ребята в http://flexblog.faratasystems.com были отличным источником вдохновения для взлома BlazeDS.

Этот код действительно должен быть включен в сам BlazeDS или какой-либо проект расширения с открытым исходным кодом - это так просто.

Channel Definition

<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel"> 
     <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" class="ch.hedgesphere.core.blazeds.endpoint.AMFEndpoint"/> 

     <properties> 
      <serialization> 
       <type-marshaller>ch.hedgesphere.core.blazeds.translator.HedgesphereASTranslator</type-marshaller> 
      </serialization> 
     </properties> 

    </channel-definition> 

Пользовательские AMF Endpoint

package ch.hedgesphere.core.blazeds.endpoint; 

import ch.hedgesphere.core.blazeds.serialization.Serializer; 

    public class AMFEndpoint extends flex.messaging.endpoints.AMFEndpoint { 

    @Override 
    protected String getSerializerClassName() { 
     return Serializer.class.getName(); 
     } 

    } 

Пользовательские Serializer

package ch.hedgesphere.core.blazeds.serialization; 

import java.io.OutputStream; 

import flex.messaging.io.MessageIOConstants; 
import flex.messaging.io.SerializationContext; 
import flex.messaging.io.amf.AmfMessageSerializer; 
import flex.messaging.io.amf.AmfTrace; 

public class Serializer extends AmfMessageSerializer { 

    @Override 
    public void initialize(SerializationContext context, OutputStream out, AmfTrace trace) 
    { 
     amfOut = new AMF0Output(context); 
     amfOut.setOutputStream(out); 
     amfOut.setAvmPlus(version >= MessageIOConstants.AMF3); 

     debugTrace = trace; 
     isDebug = trace != null; 
     amfOut.setDebugTrace(debugTrace); 
    } 
} 

Пользовательские AMF 0 Обработка

package ch.hedgesphere.core.blazeds.serialization; 

import flex.messaging.io.SerializationContext; 

public class AMF0Output extends flex.messaging.io.amf.Amf0Output { 

public AMF0Output(SerializationContext context) { 
    super(context); 
} 

@Override 
    protected void createAMF3Output() 
    { 
     avmPlusOutput = new AMF3Output(context); 
     avmPlusOutput.setOutputStream(out); 
     avmPlusOutput.setDebugTrace(trace); 
    } 
} 

Пользовательские AMF 3 Обработка

package ch.hedgesphere.core.blazeds.serialization; 

import java.io.IOException; 

import org.joda.time.DateTime; 
import org.joda.time.LocalDate; 
import org.joda.time.LocalTime; 

import flex.messaging.io.SerializationContext; 

public class AMF3Output extends flex.messaging.io.amf.Amf3Output { 

public AMF3Output(SerializationContext context) { 
    super(context); 
} 

@Override 
public void writeObject(Object value) throws IOException { 
    if(value instanceof DateTime) { 
     value = convertToDate((DateTime)value); 
    } 
    if(value instanceof LocalDate) { 
     value = convertToDate((LocalDate)value); 
    } 
    if(value instanceof LocalTime) { 
    value = convertToDate((LocalTime)value); 
    } 
    super.writeObject(value); 
} 

private Object convertToDate(LocalTime time) { 
    return time.toDateTimeToday().toDate(); 
} 

private Object convertToDate(LocalDate date) { 
    return date.toDateMidnight().toDate(); 
} 

private Object convertToDate(DateTime dateTime) { 
    return dateTime.toDate(); 
} 
} 

Пользовательские ИАС для Flex-> Java Вызов

package ch.hedgesphere.core.blazeds.translator; 

import org.joda.time.DateTime; 
import org.joda.time.LocalDate; 
import org.joda.time.LocalTime; 

import flex.messaging.io.amf.translator.ASTranslator; 


public class HedgesphereASTranslator extends ASTranslator { 

@SuppressWarnings({"rawtypes"}) 
@Override 
public Object convert(Object originalValue, Class type) { 
    if(type.equals(DateTime.class)) { 
     return convertToDateTime(originalValue); 
    } 
    if(type.equals(LocalDate.class)) { 
    return convertToLocalDate(originalValue); 
    } 
    if(type.equals(LocalTime.class)) { 
     return convertToLocalTime(originalValue); 
    } 

    return super.convert(originalValue, type); 
} 

private Object convertToLocalTime(Object originalValue) { 
    return originalValue == null ? null : new LocalTime(originalValue); 
} 

private Object convertToLocalDate(Object originalValue) { 
    return originalValue == null ? null : new LocalDate(originalValue); 
} 

private Object convertToDateTime(Object originalValue) { 
    return originalValue == null ? null : new DateTime(originalValue); 
} 

@SuppressWarnings({"rawtypes"}) 
@Override 
public Object createInstance(Object source, Class type) { 
    return super.createInstance(source, type); 
} 
} 
0

Вы пробовали пользовательские marshallers подход, описанный в этом блоге:

http://flexblog.faratasystems.com/index.php/custom-type-masrhaller-in-blazeds

+0

Этот marshalling предназначен для ActionScript-> Java-направления, и это то, что я Используется при вызове Java, но это не используется для сортировки результатов вызова службы. – SteveD

1

Для Java-приложений с использованием Spring-BlazeDS интеграции проекта с SpringSource, существует гораздо более простой способ обработки этого :

  • Написать реализацию GenericConverter, который обрабатывает отображение ReadableDateTime в/из java.util.Date.

  • Создайте подкласс AbstractAmfConversionServiceConfigProcessor и переопределите configureConverters, добавив реализацию конвертера в реестр.

  • Обновление вашей конфигурации Spring путем создания экземпляра вашего ConfigProcessor и подключение его:

XML:

<flex:message-broker> 
    <flex:config-processor ref="customConfigProcessor"/> 
</flex:message-broker> 

Больше информации здесь:

http://static.springsource.org/spring-flex/docs/1.5.x/reference/html/index.html#amf-custom-converters

+0

Это выглядит интересно. С тех пор мы добавили реализацию BigDecimal и дали код, который нам нужен для написания (материал низкого уровня), я был бы удивлен, если он подключится к Springs impl. – SteveD

+0

Если у вас есть какие-либо вопросы, не стесняйтесь пишите мне на Twitter. Я был удивлен, как легко было это сделать. –