Json4s Serialize and Deserialize a Generic Type

Since I am dealing with a generic type, so I cannot use specific case classes. Then I created a shared resource that serializes and deserializes the shared object.

import org.json4s import org.json4s.Formats._ import org.json4s.native.JsonMethods._ object JsonHelper { def json2Object[O](input: String) : O = { parse(json4s.string2JsonInput(input)).asInstanceOf[O] } def object2Json[O](input: O) : String = { write(input).toString } } 

The compiler throws an error:

A serial JSON parser was not found for type O. Try to implement an implicit Writer or JsonFormat for this type. record (input) .ToString

This should be thrown at runtime, but why was it chosen at compile time?

+5
source share
3 answers

In the commentary above, you asked: “How can Jackson work with a java object? Does it use reflection correctly and why is it different from Scala?”, Which goes to the bottom of this question.

The original json4s serializer you imported uses compile-time reflection to create Writer .

Jackson uses reflection at run time to do the same.

The compile-time version is more efficient; Runtime version is more flexible.

To use the compilation time version, you must provide the compiler with enough information to select the correct Writer based on the declared type of object to be serialized. This will rule out very general writer methods, like the one you suggest. See @TimP's answer for fixing the code for this version.

To use the run-time version, you can use Jackson through the org.json4s.jackson.JsonMethods._ package. See https://github.com/json4s/json4s#jackson

+7
source

The compiler error you posted comes from this location in json4s code . The write function that you call accepts an implicit JSON Writer , so the method can accept arbitrary types. It got during compilation because the implicit arguments were compiled the same as the explicit ones - as if you had:

 def f(a: Int, b: Int) = a + b f(5) // passed the wrong number of arguments 

I'm having problems with exactly which write method you are calling here - the json4s library is quite large and things are overloaded. Can you insert the declared write method that you use? It almost certainly has this signature:

 def write[T](value: T)(implicit writer: Writer[T]): JValue 

If it looks like this, try including the implicit writer option in your method like this:

 object JsonHelper { def json2Object[O](input: String)(implicit reader: Reader[O]) : O = { parse(json4s.string2JsonInput(input)).asInstanceOf[O] } def object2Json[O](input: O)(implicit writer: Writer[O]) : String = { write(input).toString } } 
+5
source

In this example, you have a deal with generic types, Scala, like other jvm languages, has a type erasing mechanism at compile time (an error message at compile time may not contain a message about the general as a whole), so try adding this snippet to the signature both methods:

 (implicit tag: ClassTag[T]) 

it looks like your example with generic but with jackson. NTN

+1
source

Source: https://habr.com/ru/post/1257813/


All Articles