【问题标题】:Customize JSON parsing (Gson)自定义 JSON 解析 (Gson)
【发布时间】:2015-04-19 14:05:00
【问题描述】:

如何自定义特定字段的序列化/反序列化?

这是我的 json:

[{
"Short Name": "X",
"Address": "X Address",
"Latitude": 40.739982,
"Longitude": -73.978053,
"Type": "A, B"
},
{
"Short Name": "Y",
"Address": "Y Address",
"Latitude": 40.852856,
"Longitude": -73.938098,
"Type": "A, B, C, D"
}]

使用 Gson,现在我可以解析 json 并获得一个 JAVA 对象 String type; 但我想拆分 Type 字符串并得到一个类型 String[]

public class MyClass {
    @SerializedName("Short Name")
    @Expose
    private String ShortName;

    @Expose
    private String Address;

    @Expose
    private Double Latitude;

    @Expose
    private Double Longitude; 

    @Expose
    private String Type; 
    // how can I split the string 
    // and get private String[] Type;
    // when deserializing
}

【问题讨论】:

    标签: java json gson


    【解决方案1】:

    您需要实现一个自定义类型适配器。

    你可以这样做:

    JsonDeserializer<String[]> deserializer = new JsonDeserializer<String[]>() {
    
        @Override
        public String[] deserialize(JsonElement jsonElem, Type type,
                JsonDeserializationContext context) throws JsonParseException {
    
            if(jsonElem == null) {
                return null;
            }
    
            return jsonElem.getAsString().split(", ");
        }
    
    };
    
    Gson gson = new GsonBuilder()
                        .registerTypeAdapter(String[].class, deserializer)
                        .create();
    
    Type listType = new TypeToken<ArrayList<MyClass>>() {}.getType();
    List<MyClass> t = gson.fromJson(json, listType);
    

    并从以下位置修改您的 MyClass bean:

    @Expose
    private String Type;
    

    到:

    @Expose
    private String[] Type;
    

    如果您需要序列化 ​​MyClass 对象以将“Type”数组转换为逗号分隔的字符串,则可以使用相同的方式添加序列化程序!

    【讨论】:

    • 谢谢。我会试试这个并告诉你。
    【解决方案2】:

    简单。 Json 允许您使用数字(Int/Long/Double)、字符串、列表或对象。你需要的是一个清单。

    JSON:

    “类型”:{ “类型”:“数组”, “项目”:{“类型”:“字符串”} }

    例如"类型" : ["A","B","C","D"]

    JAVA:

    List<String> Type;
    

    稍后您可以使用任何 Java List 实现,例如 ArrayList。

    例如类型 = 新的 ArrayList();

    【讨论】:

    • 这不是问题的解决方案。他需要反序列化以逗号分隔的数组中的值字符串。这不是一个 json 数组:"Type": "A, B, C, D"
    • 我认为关键是他应该更改他的 JSON,以便“Type”实际上是一个 JSON 数组。这将给他一个更清晰的实现,而不是将本质上是一个数组的东西隐藏在一个逗号分隔的字符串中。
    【解决方案3】:

    您可以为此使用 JsonAdapter。 这是来自文档的示例。

    Here is an example of how this annotation is used:
       @JsonAdapter(UserJsonAdapter.class)
       public class User {
         public final String firstName, lastName;
         private User(String firstName, String lastName) {
           this.firstName = firstName;
           this.lastName = lastName;
         }
       }
       public class UserJsonAdapter extends TypeAdapter<User> {
         @Override public void write(JsonWriter out, User user) throws IOException {
           // implement write: combine firstName and lastName into name
           out.beginObject();
           out.name("name");
           out.value(user.firstName + " " + user.lastName);
           out.endObject();
           // implement the write method
         }
         @Override public User read(JsonReader in) throws IOException {
           // implement read: split name into firstName and lastName
           in.beginObject();
           in.nextName();
           String[] nameParts = in.nextString().split(" ");
           in.endObject();
           return new User(nameParts[0], nameParts[1]);
         }
       }
       
    

    由于User类在@JsonAdapter注解中指定了UserJsonAdapter.class,它会自动被调用来序列化/反序列化User实例。 以下是如何将此注释应用于字段的示例。

       private static final class Gadget {
         @JsonAdapter(UserJsonAdapter2.class)
         final User user;
         Gadget(User user) {
           this.user = user;
         }
       }
       
    

    可以在字段、该字段的类型以及 com.google.gson.GsonBuilder 中指定不同的类型适配器。字段注释优先于 GsonBuilder 注册的类型适配器,后者又优先于带注释的类型。

    此注解引用的类必须是 TypeAdapter 或 TypeAdapterFactory,或者必须实现 JsonDeserializer 或 JsonSerializer 之一或两者。使用 TypeAdapterFactory 可以委托给封闭的 Gson 实例。

    【讨论】:

      猜你喜欢
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-14
      • 1970-01-01
      • 2019-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多