Я пытаюсь написать специальные десериализаторы Jackson для классов в сторонней библиотеке. Я сделал один для одного из основных классов (Duration), но теперь я пытаюсь написать следующий для класса (RetryPolicy) с экземплярами Duration, и я не совсем уверен, как действовать. Я хотел бы использовать мой десериализатор продолжительности, поэтому мне не нужно повторять логику для него.Пользовательский десериализатор Jackson для сторонней библиотеки
Вот пример кода:
RetryPolicy rp =
new RetryPolicy()
.withRetryInterval(Duration.seconds(2))
.withBackoff(Duration.seconds(2), Duration.minutes(30), 2)
.withMaxDuration(Duration.hours(1))
.withMaxRetries(100);
Как я сказал, что уже есть десериализатор для продолжительности и если я создаю модуль и добавить мой класс DurationDeserializer к нему, а затем зарегистрировать эту модель в ObjectMapper, I кажется, почти в состоянии десериализатор следующий JSON:
{
"retryInterval": "2 seconds",
"backoff": {
"retryInterval": "2 seconds",
"maxRetryInterval": "5 minutes",
"retryIntervalMultiplier": 2
},
"maxDuration": "30 minutes",
"maxRetries": 100
}
исключение я получаю:
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "backoff" (class net.jodah.lyra.retry.RetryPolicy), not marked as ignorable (5 known properties: , "maxRetries", "maxDuration", "maxRetryInterval", "retryInterval", "retryIntervalMultiplier"])
Таким образом, на самом деле, похоже, он может заполнить все поля Duration и int самостоятельно (хотя этот класс использует шаблон построителя без метода build(). Единственное, с чем он сталкивается, это метод withBackoff (Duration, Duration, int).
Я не совсем уверен, куда идти отсюда. Я пишу собственный десериализатор для класса RetryPolicy? Если это так, как мне избежать необходимости разбирать все JSON (например, я просто хочу делегировать все переменные Duration для уже сделанного класса DurationDeserializer)?
Я должен отметить (хотя, вероятно, очевидно), что я не могу аннотировать библиотеку сторонних разработчиков (классы Duration и RetryPolicy), поэтому я перехожу к пользовательскому методу сериализации.
Я пытался понять это, но я все время натыкаюсь на что-то. Я применил десериализатор для класса RetryPolicy, который работает, но он действительно уродлив, так как он повторяет логику десериализации для Duration (это даже делает это не один раз). Вот код для этого: https://github.com/StFS/LyraJacksonDeserializers/blob/master/src/main/java/com/activitystream/lyra/jackson/LyraRetryPolicyDeserializer.java Остальная часть кода находится в этом тот же проект, и я бы очень хотел узнать, как избежать дублирования кода при создании этого десериализатора. – StFS
Да, общее правило состоит в том, что каждый уровень (и отдельный тип) должен обрабатываться одним (де) сериализатором; и что все делегировано. Это можно сделать, и основные типы все это делают. Но это не обязательно означает, что это тривиально. – StaxMan