Error parsing field as object or array

后端 未结 1 1069
闹比i
闹比i 2021-01-20 08:23

i have the following Json string, which I\'m suppose to deserialize. The problem is: since this string comes from a server I can\'t change it and I need to deserialize as PO

相关标签:
1条回答
  • 2021-01-20 09:00

    You can use TypeAdapterFactory to do the conversion. Here is a factory that will add that functionality to all of your List member types --

    import com.google.gson.Gson;
    import com.google.gson.TypeAdapter;
    import com.google.gson.TypeAdapterFactory;
    import com.google.gson.reflect.TypeToken;
    import com.google.gson.stream.JsonReader;
    import com.google.gson.stream.JsonToken;
    import com.google.gson.stream.JsonWriter;
    import java.io.IOException;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.Collections;
    import java.util.List;
    
    public class SingletonListTypeAdapterFactory implements TypeAdapterFactory {
         public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
    
           Type type = typeToken.getType();
           if (typeToken.getRawType() != List.class
               || !(type instanceof ParameterizedType)) {
             return null;
           }
           Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
           TypeAdapter<?> elementAdapter = gson.getAdapter(TypeToken.get(elementType));
           TypeAdapter<T> arrayAdapter = gson.getDelegateAdapter(this, typeToken);
           return (TypeAdapter<T>) newSingtonListAdapter((TypeAdapter<Object>) elementAdapter, (TypeAdapter<List<Object>>) arrayAdapter);
         }
    
         private <E> TypeAdapter<List<E>> newSingtonListAdapter(
             final TypeAdapter<E> elementAdapter,
             final TypeAdapter<List<E>> arrayAdapter) {
           return new TypeAdapter<List<E>>() {
    
             public void write(JsonWriter out, List<E> value) throws IOException {
               if(value == null || value.isEmpty()) {
                 out.nullValue();
               } else if(value.size() == 1) {
                elementAdapter.write(out, value.get(0));
               } else {
                 arrayAdapter.write(out, value);
               }
             }
    
             public List<E> read(JsonReader in) throws IOException {
               if (in.peek() != JsonToken.BEGIN_ARRAY) {
                 E obj = elementAdapter.read(in);
                 return Collections.singletonList(obj);
               }
               return arrayAdapter.read(in);
             }
           };
         }
       }
    

    As bonus, it also serializes in the same way, if needed. If you also want to serialize as array, replace the write method with a call to arrayAdapter.write.

    To you, add to your gson when building --

    Gson gson = new GsonBuilder().registerTypeAdapterFactory(new SingletonListTypeAdapterFactory())
            .create();
    
    0 讨论(0)
提交回复
热议问题