【问题标题】:Parsing single JSON element as array将单个 JSON 元素解析为数组
【发布时间】:2018-05-04 21:20:00
【问题描述】:

当包含多个元素时,我的 JSON 响应中的一个字段是 String[],而当它只有一个时是 String。像这样:

"assets": [
  "0901d196804adc1c",
  "0901d196804ebd93",
  "0901d196804ea5e2"
]

"assets": "0901d196804adc1c"

理想情况下,我希望始终获得一个 String[],因此如果元素的 JSON 类型是 String,则将其转换为一个包含一个元素的 String[]。

我该怎么做?

【问题讨论】:

  • 如果您可以更改 api 响应而不是单个元素,您可以发送“assets”:[“0901d196804adc1c”]
  • 这是你完整的 json 响应?

标签: java android gson retrofit retrofit2


【解决方案1】:

如果你无法在服务器端编辑回复:请参考this问答,看起来和你的情况差不多。

如果您可以编辑响应,只需始终使用字符串数组进行回复(例如"assets": ["0901d196804adc1c"])。

【讨论】:

  • 使用评论部分引用一些链接。
  • 当我的声望达到 50 时,我会 :)
【解决方案2】:

你有两个选择:

1) 为 gson 实现自定义type adapter 以处理此类情况(首选解决方案)。

2) 定义 Object 类型的字段,并在运行时将其转换为适当的类型

public static class AssetsContainer{
        private Object assets;

        public List<String> getAssets() {
            if(assets instanceof List<?>) {
                return (List<String>) assets;
            } else if(assets instanceof String){
                return Arrays.asList((String) assets);
            } else {
                //TODO: handle
                return null;
            }
        }
    }

【讨论】:

    【解决方案3】:

    使用 TypeAdapter API 怎么样?

    Gson gson = new GsonBuilder()
        .registerTypeAdapterFactory(SingletonListTypeAdapter.FACTORY)
        .create();
    

    以下将在需要数组类型时检查非数组 JSON 类型,并尝试将它们变成单例 Java 列表。 (请注意,这里使用的是列表,而不是数组。您可以根据需要对其进行调整,但 Effective Java 指出,应用层代码应该更喜欢 Collections API 而不是数组。)

    final class SingletonListTypeAdapter<T> extends TypeAdapter<List<T>> {
      static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
        @SuppressWarnings("unchecked")
        @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
          if (type.getRawType() != List.class) {
            return null;
          }
          TypeToken<?> collectionElementType = TypeToken.get(
              getCollectionElementType((ParameterizedType) type.getType()));
          TypeAdapter<List<Object>> delegate = (TypeAdapter<List<Object>>)
              gson.getDelegateAdapter(this, collectionElementType);
          return (TypeAdapter<T>) new SingletonListTypeAdapter<>(delegate);
        }
      };
    
      private final TypeAdapter<T> delegate;
    
      SingletonListTypeAdapter(TypeAdapter<T> delegate) {
        this.delegate = delegate;
      }
    
      @Override public void write(JsonWriter out, List<T> value) throws IOException {
        out.beginArray();
        for (int i = 0, size = value.size(); i < size; i++) {
          delegate.write(out, value.get(i));
        }
        out.endArray();
      }
    
      @Override public List<T> read(JsonReader in) throws IOException {
        if (in.peek() != BEGIN_ARRAY) {
          return Collections.singletonList(delegate.read(in));
        }
        in.beginArray();
        List<T> expanding = new ArrayList<>();
        while (in.hasNext()) {
          expanding.add(delegate.read(in));
        }
        in.endArray();
        return Collections.unmodifiableList(expanding);
      }
    
      static Type getCollectionElementType(ParameterizedType type) {
        Type[] types = type.getActualTypeArguments();
        Type paramType = types[0];
        if (paramType instanceof WildcardType) {
          return ((WildcardType) paramType).getUpperBounds()[0];
        }
        return paramType;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-17
      相关资源
      最近更新 更多