2016-03-15 3 views
1

Я выполнил свой предыдущий вопрос Spring Cloud Stream message from/to JSON conversion configuration и сконфигурировал поток, как описано, но я не могу заставить его работать правильно.Spring Cloud Stream сообщение JSON преобразование не работает

Моя установка выглядит следующим образом. У меня есть два приложения: A и B. Приложение A использует входной канал one, выход two. Приложение B использует вход two. Канал two настроен с типом контента application/json.

App A. Свойства.

spring.cloud.stream.bindings.input.destination=one 
spring.cloud.stream.bindings.input.group=default 

spring.cloud.stream.bindings.output.destination=two 
spring.cloud.stream.bindings.output.content-type=application/json 

Метод приемника.

@ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT) 
public Dto handle(byte[] payload) throws IOException { 
    final Dto dto = new ObjectMapper().readValue(payload, Dto.class); 
    logger.info("{}", dto); 
    dto.setId(dto.getId() + 1000); 
    return dto; 
} 

App B. Свойства.

spring.cloud.stream.bindings.input.destination=two 
spring.cloud.stream.bindings.input.group=default 
spring.cloud.stream.bindings.input.content-type=application/json 

Метод приемника.

@ServiceActivator(inputChannel = Sink.INPUT) 
public void handle(Dto dto) throws IOException { 
    logger.info("DTO {}", dto); 
} 

Когда я вручную отправить сообщение с надлежащей строкой JSON к каналу one, он правильно обработан и отправить на канал two в виде сообщения JSON (заголовки точно так же, как описано в упомянутом выше вопросе). После этого он получил на канале two на App B и исключение: Method handle(java.lang.String) cannot be found

Конечно, когда я создаю оба метода, обработки DTO и строку в качестве входных данных, он работает, но всегда метод Строки вызывается и должен десериализация полезная нагрузка.

Я где-то ошибаюсь? Как настроить метод с такой подписью: public Dto handle(Dto incoming)?

+0

Почему вы не использовали 'StreamListener' вместо' ServiceActivator' для вашего приложения B? Я не уверен на 100%, но я думаю, что ваша проблема могла быть исправлена ​​с помощью 'StreamListener' вместо изменения свойства' content-type'. – Gooseman

+0

В то время такой вариант недоступен. Но, да, это хороший совет. – waste

ответ

1

Вы должны изменить тип содержимого декларации ввода AppB в

application/x-java-object;type=your.package.Dto.

Как указано в вашем вопросе, конечно, вы принимаете только строки JSON.

+0

Мне не нужна сериализация Java. Взгляните на тему - мне нужны сообщения JSON. – waste

+0

Правда, вы должны оставить объявление типа содержимого вывода AppA для вывода JSON, но AppB следует сообщить через это объявление типа контента, что соответствующий MessageConverter должен преобразовать полезную нагрузку в объект Dto. Сообщения на канале будут JSON, как можно видеть во время отладки. – Alexander

+0

Это действительно работает, спасибо. Невероятно неинтуитивно, учитывая, как работают другие компоненты Spring (AMQP или Rest). – waste

Смежные вопросы