Spring Cloud Netflix и HystrixObservable -> JsonMappingException
Для кода, смотрите мой крошечный проект 4 класса GitHub
Я использую Spring FeignClients для подключения к службе отдыха. Вот как выглядит клиент Feign в его основной (не асинхронной) форме:
@FeignClient(value="localhost:8080/products", decode404 = true)
public interface ProductClient {
@RequestMapping(value="/{id}")
Product getById(@PathVariable("id") String id);
}
Теперь я хотел сделать это асинхронно, используя Observable. Информация об этом остро отсутствует в документах Spring, есть только небольшой абзац, который говорит вам об использовании HystrixCommand. Это все, без объяснений, без кода sampe.
В другом сообщении в блоге мне сказали использовать вместо этого HystrixObservable. И вот я попробовал это:
@FeignClient(value="localhost:8080/products", decode404 = true)
public interface ProductClient {
@RequestMapping(value="/{id}")
HystrixObservable<Product> getById(@PathVariable("id") String id);
}
В любом случае, с HystrixCommand или HystrixObservable, он выдает мне ошибку: com.fasterxml.jackson.databind.JsonMappingException: Невозможно создать экземпляр com.netflix.hystrix.HystrixObservable
Я понимаю, почему он выдает эту ошибку, поскольку Spring Boot автоматически присоединяет декодер к FeignClient для десериализации ответа с использованием Jackson. И тип для десериализации ответа получен из возвращаемого значения.
Я мог бы попытаться настроить обычный декодер или вручную собрать клиенты Feign, но это как бы сводит на нет всю цель Spring Boot: то, что он работает автоматически (хотя и с небольшой настройкой здесь и там).
И вот мой вопрос: как это должно работать?
2 ответа
Если вы указываете тип возвращаемого значения как HystrixCommand<Product>
или любой из RxJava Observable<Product>
или же Single<Product>
а не HystrixObservable<Product>
он должен работать.
Я считаю, что причина использования HystrixObservable
это не работает, потому что это интерфейс, и Джексон не будет отображать абстрактные типы, такие как интерфейсы по умолчанию, как вы можете видеть в трассировке стека:
> abstract types either need to be mapped to concrete types, have custom
> deserializer, or contain additional type information
HystrixCommand
тем не менее, является реализацией HystrixObservable
интерфейс, так что Джексон может легко сопоставить его.
Если вы проверите HystrixInvocationHandler
в модуле Feign Hystrix вы увидите другие типы, которые он может возвращать; те, которые я перечислил выше, а также RxJava Completable
, В документации, на которую ссылается Tassos Bassoukos, также перечислены типы.
Если вы ищете что-то асинхронное и неблокирующее, возможно, стоит попробовать Feign Vertx, так как я считаю, что Feign может быть асинхронным, но блокирующим. Дискуссия о неблокирующем Feign здесь.
Надеюсь, это поможет!
Если кто-нибудь начнет получать эту ошибку после обновления до spring-cloud:1.3.+ Убедитесь, что у вас включена функция hystrix-feign.
feign.hystrix.enabled=true
Это было добавлено, так что по умолчанию feign не переносит вызовы в командах Hystrix.
https://github.com/spring-cloud/spring-cloud-netflix/issues/1277