json4s — игнорировать поле определенного типа во время сериализации

Допустим, у меня есть какой-то маркер trait Ignore Я хочу, чтобы все поля, помеченные этим трейтом, игнорировались при сериализации.

Итак, если у меня есть класс

case class A(a: Int) extends Ignore
case class B(f: String, a: A, d: Int)

json для B после сериализации не должен содержать поле a.

ПРИМЕЧАНИЕ: я знаю, что есть возможность игнорировать поле по имени, но это не то, что мне нужно.


person maks    schedule 31.03.2016    source источник


Ответы (1)


Вы можете использовать CustomSerializer. Вы можете настроить только сериализацию, указав пустой PartialFunction в качестве десериализатора:

trait Ignore
case class A(a: Int) extends Ignore
case class B(f: String, a: A, d: Int)

implicit val formats = DefaultFormats +
  new CustomSerializer[Ignore](formats => (
  PartialFunction.empty,
  { case _: Ignore => JNothing }
  ))

// prints "{"f":"x","d":2}"
println(Serialization.write(B("x", A(1), 2)))
// deserializes to B(x,A(1),2)
println(Serialization.read[B]("""{"f":"x","a":{"a":1},"d":2}"""))

редактировать: На момент написания (3.3.0) json4s-native имел ошибку, которая неправильно отображала сериализованный объект, если поле first игнорируется (например, case class B(a: A, ...). Я предлагаю использовать json4s-jackson пока проблема не решится

Использование первого Extraction.decompose и после Serialization, похоже, решает проблему:

trait Ignore
case class A(a: Int) extends Ignore
case class B(a: A, d: Int)

implicit val formats = DefaultFormats +
  new CustomSerializer[Ignore](formats => (
    PartialFunction.empty,
    { case _: Ignore => JNothing }
    ))

// prints {,"d":2}
println(Serialization.write(B(A(1), 2)))
// prints {"d":2}
println(Serialization.write(Extraction.decompose(B(A(1), 2))))
person Giovanni Caporaletti    schedule 31.03.2016
comment
Да, это работает, но если я помещу поле в начало полей B, оно создаст недопустимый json. Например: case class B(a: A, d: Int) производит "{,"d":2}" Как это исправить? - person maks; 31.03.2016
comment
@maks У меня работает: {"d":2}. Вы используете старую версию json4s? я на 3.3.0 - person Giovanni Caporaletti; 31.03.2016
comment
@maks Хорошо, я не проверял, но думаю, что мой код работает, потому что я использую json4s-jackson. Вы используете родной? - person Giovanni Caporaletti; 31.03.2016
comment
@maks Подтверждено, это проблема json4s. Это определенно ошибка, я открою проблему на github, я все равно предлагаю использовать jackson, потому что это быстрее - person Giovanni Caporaletti; 31.03.2016
comment
@maks Я нашел обходной путь, но вам нужно изменить код сериализации, пока (и если когда-либо) ошибка не будет решена - person Giovanni Caporaletti; 31.03.2016