【问题标题】:Java Gson to Json ConversionJava Gson 到 Json 的转换
【发布时间】:2022-01-17 06:11:47
【问题描述】:

我有一个具有以下属性的类,

public AnalyticsEventProperty(String eventID, String key, Object value, EventPropertyValueType valueType) {
        this.eventID = eventID;
        this.key = key;
        this.value = value;
        this.type = valueType();
}

创建此对象并将其传递给事件属性数组,当我进行 Json 转换时,我得到以下输出:

{"eventID":"afc970ef-80cf-4d6e-86e6-e8f3a56f26f5","name":"app_start","propertyArrayList":[{"eventID":"afc970ef-80cf-4d6e-86e6-e8f3a56f26f5","key":"session_id","value":"69200430-95a0-4e14-9a36-67942917573d"}

我正在使用“键和值”,我明白为什么,但是如何使用键和值作为键和值,即“session_id”:“69200430-95a0-4e14-9a36-67942917573d”,轴承请记住,这些键和值可能具有不同的属性名称,具体取决于构造函数中传递的内容。

当我创建字符串时,我只是在调用

String text_to_send = new Gson().toJson(events);

其中 events 是 ArrayList。

【问题讨论】:

  • 您是否期望 JSON Map<String, String> 其中每个事件的键都映射到值(并且所有其他属性都被忽略),或者您是否期望事件对象仍然具有它们的其他属性和只更改了keyvalue
  • 是的,谢谢,我需要事件对象具有 eventID,它们所映射的类型确定,因为属性名称是键,然后正如您建议的那样,只需将键值替换为传递的值。

标签: java json gson


【解决方案1】:

您可以通过编写自定义TypeAdapterFactory 来解决此问题,该TypeAdapterFactory 为您的类获取默认适配器(即基于反射的适配器)并使用它以JsonObject 的形式创建内存中的JSON 表示。然后可以修改 JsonObject 以获得您期望的结构;之后必须将其写入JsonWriter:

class RewritingEventPropertyAdapterFactory implements TypeAdapterFactory {
  public static final RewritingEventPropertyAdapterFactory INSTANCE = new RewritingEventPropertyAdapterFactory();

  private RewritingEventPropertyAdapterFactory() {}

  @Override
  public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
    // Only consider AnalyticsEventProperty or subtypes
    if (!AnalyticsEventProperty.class.isAssignableFrom(type.getRawType())) {
      return null;
    }

    TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
    TypeAdapter<JsonObject> jsonObjectAdapter = gson.getAdapter(JsonObject.class);

    return new TypeAdapter<T>() {
      @Override
      public T read(JsonReader in) throws IOException {
        throw new UnsupportedOperationException("Deserialization is not supported");
      }

      @Override
      public void write(JsonWriter out, T value) throws IOException {
        if (value == null) {
          out.nullValue();
          return;
        }

        JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject();

        // Remove "key" and "value"
        String eventKey = jsonObject.remove("key").getAsString();
        JsonElement eventValue = jsonObject.remove("value");

        // Add back an entry in the form of `"key": "value"`
        jsonObject.add(eventKey, eventValue);

        // Write the transformed JsonObject
        jsonObjectAdapter.write(out, jsonObject);
      }
    };
  }
}

然后您必须使用GsonBuilder register the factory

另一种方法是通过直接将属性写入JsonWriter 来手动执行类的完整序列化。这很可能会更高效,但也更容易出错。

【讨论】:

    猜你喜欢
    • 2012-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多