Существует старая открытая проблема , которая, похоже, задает аналогичный вопрос, когда один из авторов предлагает
вам необходимо создать собственный десериализаторили сериализатор
, который заставляет это звучать, нет готового способа изменить поведение по умолчанию.
Метод 1: Запрещать форматы по умолчанию через Scalastyle
Попробуйте запретить импорт org.json4s.DefaultFormats
, используя Scalastyle IllegalImportsChecker
<check level="error" class="org.scalastyle.scalariform.IllegalImportsChecker" enabled="true">
<parameters>
<customMessage>Import from illegal package: Please use example.DefaultFormats instead of org.json4s.DefaultFormats</customMessage>
<parameter name="illegalImports"><![CDATA[org.json4s.DefaultFormats]]></parameter>
</parameters>
</check>
и предоставьте пользовательские DefaultFormats
, например,
package object example {
val DefaultFormats = Serialization.formats(NoTypeHints) + FooSerializer
}
, которые позволят намчтобы сериализовать ADT следующим образом:
import example.DefaultFormats
implicit val formats = DefaultFormats
case class Bar(foo: Foo)
println(Serialization.write(Bar(X)))
println(Serialization.write(X))
println(Serialization.write(Y))
, который должен вывести
{"foo":"x"}
"x"
"y"
Если мы попытаемся импортировать org.json4s.DefaultFormats
, то Scalastyle должен вызвать следующую ошибку:
Import from illegal package: Please use example.DefaultFormats instead of org.json4s.DefaultFormats
Метод 2: Запекание в сериализации для не вложенных значений
Возможно, мы могли бы "запекать" форматирование в объекты, определив метод write
в Foo
, который делегирует Serialization.write
как
sealed trait Foo {
object FooSerializer extends CustomSerializer[Foo](_ =>
({
case JString("x") => X
case JString("y") => Y
}, {
case X => JString("x")
case Y => JString("y")
})
)
def write: String =
Serialization.write(this)(DefaultFormats + FooSerializer)
}
case object X extends Foo
case object Y extends Foo
Обратите внимание, как мы жестко закодировали передачу формата FooSerializer
в write
.Теперь мы можем сериализовать с
println(X.write)
println(Y.write)
, который должен вывести
"x"
"y"
Метод 3: Предоставить пользовательский DefaultFormats
наряду с org.json4s.DefaultFormats
Мы также можем попробовать определить пользовательскийDefaultFormats
в нашем собственном пакете, например,
package example
object DefaultFormats extends DefaultFormats {
override val customSerializers: List[Serializer[_]] = List(FooSerializer)
}
, который позволил бы нам сериализовать ADT, например, так:
import example.DefaultFormats
implicit val formats = DefaultFormats
case class Bar(foo: Foo)
println(Serialization.write(Bar(X)))
println(Serialization.write(X))
println(Serialization.write(Y))
, который должен выдавать
{"foo":"x"}
"x"
"y"
, имея дваформаты по умолчанию, org.json4s.DefaultFormats
и example.DefaultFormats
, по крайней мере, заставят пользователя выбирать между двумя, если, скажем, они используют IDE для их автоматического импорта.