Moshi: Do I Have to implement Adapter to serialize every object

Created on 24 Jun 2018  路  7Comments  路  Source: square/moshi

it's impossible just to implement Any.toJson() with moshi,

it fails on every new class, eg every type of Exceptions require it's own adapter, while other libraries able to serialize any class to json without any problems

Platform class java.io.EOFException (with no annotations) requires explicit JsonAdapter to be registered

Most helpful comment

Try this adapter:

val adapter = moshi.adapter<Any>(Object::class.java)

It鈥檒l work on JSON value types: lists, maps, strings, numbers, booleans and nulls.

All 7 comments

Subtypes will work fine. For serializing all exceptions you can use Throwable as the base type you write a serializer for.

But in general, yes, Moshi won't silently encode the implementation details of types which you don't own (i.e., are part of the JDK).

also it does not support kotlin\java collections.

class JsonAdapterFactory : JsonAdapter.Factory {
    override fun create(type: Type?, annotations: MutableSet<out Annotation>?, moshi: Moshi?): JsonAdapter<*>? {
        if (type === LinkedHashMap::class.java) return HashMapAdapter()
        if (type === LinkedHashSet::class.java) return HashSetAdapter()

        if (type !is ParameterizedType) return null

        if (type.rawType === Id::class.java) return IdJsonAdapter()
        if (type.rawType === kotlin.collections.LinkedHashMap::class.java) return HashMapAdapter()
        if (type.rawType === kotlin.collections.LinkedHashSet::class.java) return HashSetAdapter()

        return null
    }
}

and my adapters file keeps growing. Any chance that reflection can be used to support other types?

The Map and Set interfaces are supported.

maybe I'm stupid, but

val moshi = Moshi.Builder()
        .add(JsonAdapterFactory)
        .add(Throwable::class.java, ThrowableAdapter)
        .add(Date::class.java, DateJsonAdapter)
        .add(com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory())
        .build()!!`

val Any?.json: String?
    get() = this?.let { moshi.adapter<Any>(it::class.java).toJson(it) }

val test = listOf<Int>().json       

throws

"Platform class kotlin.collections.EmptyList (with no annotations) requires explicit JsonAdapter to be registered"

@veonua that won鈥檛 work. You need to tell Moshi the complete type that you鈥檇 like to encode as JSON.

Your approach returns kotlin.collections.EmptyList which is the implementation type, but you need the API type (kotlin.collections.List). Your approach also drops the type argument so you get List instead of List<Int>.

but I do not know complete type, I need general function that supports Any like in python.

Gson().toJson(listOf()) works correctly, returns "[]"

Try this adapter:

val adapter = moshi.adapter<Any>(Object::class.java)

It鈥檒l work on JSON value types: lists, maps, strings, numbers, booleans and nulls.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ayedo picture ayedo  路  4Comments

PaulWoitaschek picture PaulWoitaschek  路  4Comments

cdongieux picture cdongieux  路  4Comments

Speedrockracer picture Speedrockracer  路  4Comments

rephiscorth picture rephiscorth  路  5Comments