#scala #serialization #optional #json4s
#scala #сериализация #тип параметра #json4s
Вопрос:
Я знаю, что Json4s обрабатывает Option
s самостоятельно, и большую часть времени это отлично работает — Option[T]
он сериализует None
пропущенное значение и считывает пропущенное значение как None
, автоматически используя правильный сериализатор / десериализатор для T
в противном случае.
Моя проблема в том, что у меня есть база данных, в которой пустые строки использовались как отсутствующие значения, поэтому я хочу прочитать их как None
. Простой пример:
case class Example(a: Option[Number])
val inputJson = """ {"a": ""} """
Serialization.read[Example](inputJson) // I want Example(None)
Я думал, что смогу сделать это довольно легко с помощью пользовательского сериализатора, например:
case object EmptyValueSerializer extends CustomSerializer[Option[_]](_ => (
{case JString("") => None},
{PartialFunction.empty}
))
Это работает для чтения пустых строк как None
, однако, если значение JSON не является пустой строкой, это приведет к ошибкам (т. Е. в предыдущем примере это выдало бы ошибку {"a": "5"}
).). Как я могу заставить Json4s продолжить разбор значения, используя его поведение по умолчанию, если это не пустая строка?
Теоретически я думал об использовании typetag T
и добавлении регистра по умолчанию, подобного case v => Serialization.write[T](v)
, но я не уверен, что это лучший способ, и я также не могу понять, как это будет выглядеть в коде.
Комментарии:
1. Хотя я не использовал Json4s, но я вижу, что вы просто ловите
""
bycase JString("") => None
в своей пользовательской сериализации. Как насчет другого? Я думаю, вам также нужныcase x@_:JsString => ???
и другие типы перехвата.2. @MHJ я знаю, как перехватывать другие значения (
case _ => ???
) проблема в том, что я не знаю, есть ли какой-то способ заставить Json4s продолжать попытки с другими сериализаторами.3. Есть ли причина, по которой вам нужно использовать Json4s конкретно? Это действительно довольно ужасная библиотека по сравнению, например, с circe.
4. @MatthiasBerndt Это то, что используется — у меня нет возможности изменить это.
Ответ №1:
Немного поздновато для прохождения, но вам просто нужно еще одно заявление по делу
case object EmptyValueSerializer extends CustomSerializer[Option[_]](_ => (
{
case JString("") => None
case JString(s) => Option(s)
},
{PartialFunction.empty}
))