gson Google Cloud Functions -实时数据库触发器-如何将JSON数据反序列化为POJO?

pgpifvop  于 2022-11-06  发布在  Go
关注(0)|答案(1)|浏览(77)

如Google Cloud Functions文档所述,可根据Firebase实时数据库事件(写入/创建/更新/删除)触发功能。
以下文档示例说明了如何获取delta快照。

public class FirebaseRtdb implements RawBackgroundFunction {
  private static final Logger logger = Logger.getLogger(FirebaseRtdb.class.getName());

  // Use GSON (https://github.com/google/gson) to parse JSON content.
  private static final Gson gson = new Gson();

  @Override
  public void accept(String json, Context context) {
    logger.info("Function triggered by change to: " + context.resource());

    JsonObject body = gson.fromJson(json, JsonObject.class);

    boolean isAdmin = false;
    if (body != null && body.has("auth")) {
      JsonObject authObj = body.getAsJsonObject("auth");
      isAdmin = authObj.has("admin") && authObj.get("admin").getAsBoolean();
    }

    logger.info("Admin?: " + isAdmin);

    if (body != null && body.has("delta")) {
      logger.info("Delta:");
      logger.info(body.get("delta").toString());
    }
  }
}

该示例运行良好,但问题是:如何将此增量反序列化为POJO?
我试探着:

val mObject = gson.fromJson(body.get("delta").toString(), MyCustomObject::class.java)

但我得到:
List<T>
据我所知,这是因为MyObject类有一个List<T>字段,而Firebase数据库总是用整数键将List转换为Map。
我最好不要将每个List<T>都更改为Map<Int,T>,因为我有很多类:(
提前感谢!

yzckvree

yzckvree1#

所以,这是我最后做的 (也许不是最好的解决方案!)

**1)**为即将到来的Firebase列表创建一个自定义的Json反序列化程序:

class ListFirebaseDeserializer<T> : JsonDeserializer<ArrayList<T>> {
    override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): ArrayList<T> {
        val result = ArrayList<T>()
        val typeOfElement = (typeOfT as ParameterizedType).actualTypeArguments[0]

        json?.let {
            json.asJsonObject.entrySet().forEach {
                entry->
                result.add(Gson().fromJson(entry.value, typeOfElement))
            }
        }
        return result
    }
}

这将把Firebase转换成Map的列表转换回实际的列表。

**2)**使用@JsonAdapter(ListFirebaseDeserializer::class)注解POJO中的每个列表,例如:

class MyCustomObject {

    @JsonAdapter(ListFirebaseDeserializer::class)
    var myPaymentList = ArrayList<Payment>()
}

如果你已经有很多列表需要注解,这可能会很痛苦,但这比不得不使用Map要好。

  • 希望能有所帮助 *

相关问题