moshi自定义限定符批注仅在一个属性上序列化null [英] moshi custom qualifier annotation to serialise null on one property only

查看:237
本文介绍了moshi自定义限定符批注仅在一个属性上序列化null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只想为要进行PUT的JSON正文中的一个属性序列化null.我不想为对象中的任何其他类型序列化null.模型类就是这样

I'd like to serialise null for only one property in my JSON body that is going on a PUT. I don't want to serialize null for any other types in the object. Model class is like this

@Parcel
class User @ParcelConstructor constructor(var college: College?,
                                          var firstname: String?,
                                          var lastname: String?,
                                          var email: String?,
                                          var active: Boolean = true,
                                          var updatedAt: String?,
                                          var gender: String?,
                                          var picture: String?,
                                          var id: String?,
                                          @field: [CollegeField] var collegeInput: String?,
                                          @field: [CollegeField] var otherCollege: String?,)

如果它们中的任何一个为null,我只想序列化CollegeInput和otherCollege字段.例如

I only want to serialise collegeInput and otherCollege fields if either of them are null. For example

val user = User(firstname = "foo", lastname=null, collegeInput="abcd", otherCollege = null)

Json看起来像这样:

Json will look something like this:

{"user":{
  "firstname": "foo",
  "collegeInput": "abcd",
  "otherCollege": null
}}

otherCollege为null的情况下,对象会省略姓氏,因为默认情况下,moshi不会序列化我想要的null,但是应将qualifer字段序列化为null值

Where otherCollege is null, lastname is omitted from the object as by default moshi does not serialise nulls which is what I want, but qualifer fields should be serialized with null values

我尝试使用

class UserAdapter {
@FromJson
@CollegeField
@Throws(Exception::class)
fun fromJson(reader: JsonReader): String? {
    return when (reader.peek()) {
        JsonReader.Token.NULL ->
            reader.nextNull()
        JsonReader.Token.STRING -> reader.nextString()
        else -> {
            reader.skipValue() // or throw
            null
        }
    }
}

@ToJson
@Throws(IOException::class)
fun toJson(@CollegeField b: String?): String? {
    return b
}


@Retention(AnnotationRetention.RUNTIME)
@JsonQualifier
annotation class CollegeField

我将适配器添加到了moshi,但是它从未被调用

I added the adapter to moshi but it never gets called

@Provides
@Singleton
fun provideMoshi(): Moshi {
    return Moshi.Builder()
            .add(UserAdapter())
            .build()
}

@Provides
@Singleton
fun provideRetrofit(client: OkHttpClient, moshi: Moshi, apiConfig: ApiConfig): Retrofit {
    return Retrofit.Builder()
            .baseUrl(apiConfig.baseUrl)
            .client(client)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(ScalarsConverterFactory.create())
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .build()
}

推荐答案

当限定的字符串值为null时,您的toJson适配器方法将返回null,并且JsonWriter不会写入该null值.

Your toJson adapter method will return null when the qualified string value is null, and the JsonWriter will not write the null value.

这里是要安装的限定符和适配器工厂.

Here is a qualifier and adapter factory to install that will work.

@Retention(RUNTIME)
@JsonQualifier
public @interface SerializeNulls {
  JsonAdapter.Factory JSON_ADAPTER_FACTORY = new JsonAdapter.Factory() {
    @Nullable @Override
    public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) {
      Set<? extends Annotation> nextAnnotations =
          Types.nextAnnotations(annotations, SerializeNulls.class);
      if (nextAnnotations == null) {
        return null;
      }
      return moshi.nextAdapter(this, type, nextAnnotations).serializeNulls();
    }
  };
}

现在,以下内容将通过.

Now, the following will pass.

class User(
  var firstname: String?,
  var lastname: String?,
  @SerializeNulls var collegeInput: String?,
  @SerializeNulls var otherCollege: String?
)

@Test fun serializeNullsQualifier() {
  val moshi = Moshi.Builder()
      .add(SerializeNulls.JSON_ADAPTER_FACTORY)
      .add(KotlinJsonAdapterFactory())
      .build()
  val userAdapter = moshi.adapter(User::class.java)
  val user = User(
      firstname = "foo",
      lastname = null,
      collegeInput = "abcd",
      otherCollege = null
  )
  assertThat(
      userAdapter.toJson(user)
  ).isEqualTo(
      """{"firstname":"foo","collegeInput":"abcd","otherCollege":null}"""
  )
}

请注意,您应该使用 Moshi中的Kotlin支持,以避免@field:奇怪.

Note that you should use the Kotlin support in Moshi to avoid the @field: oddities.

这篇关于moshi自定义限定符批注仅在一个属性上序列化null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆