简体   繁体   English

自定义 JSON 解析 (Gson)

[英]Customize JSON parsing (Gson)

How can I customize serialization/deserialization of a specific field?如何自定义特定字段的序列化/反序列化?

Here's my json:这是我的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"
}]

Using Gson, now I can parse the json and get a JAVA object with String type;使用Gson,现在我可以解析json并得到一个String type;的JAVA对象String type; but I want to split the Type string and get a type String[] .但我想拆分 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
}

You need to implement a custom Type Adapter.您需要实现自定义类型适配器。

You can do in this way:你可以这样做:

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);

And modify your MyClass bean from:并从以下位置修改您的 MyClass bean:

@Expose
private String Type;

to:到:

@Expose
private String[] Type;

In the same way you can add a serializer if you need to serialize MyClass object in order to convert the "Type" array to String comma separed!如果您需要序列化 ​​MyClass 对象以将“类型”数组转换为以逗号分隔的字符串,则可以以同样的方式添加序列化程序!

Easy.简单。 Json allows you to use Numbers(Int/Long/Double), Strings, Lists or Objects. Json 允许您使用数字(整数/长/双)、字符串、列表或对象。 What you need is a list.你需要的是一个清单。

JSON: JSON:

"Type" : { "type": "array", "items" : {"type": "string"} } “类型”:{“类型”:“数组”,“项目”:{“类型”:“字符串”}}

eg "Type" : ["A","B","C","D"]例如“类型”:[“A”,“B”,“C”,“D”]

JAVA:爪哇:

List<String> Type;

Later on you can use any Java List implementation such as ArrayList.稍后您可以使用任何 Java List 实现,例如 ArrayList。

eg Type = new ArrayList();例如 Type = new ArrayList();

You can use JsonAdapter for that.您可以为此使用 JsonAdapter。 Here is example from ducumentation.这是来自文档的示例。

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]);
     }
   }
   

Since User class specified UserJsonAdapter.class in @JsonAdapter annotation, it will automatically be invoked to serialize/deserialize User instances.由于 User 类在 @JsonAdapter 注解中指定了 UserJsonAdapter.class,因此会自动调用它来序列化/反序列化 User 实例。 Here is an example of how to apply this annotation to a field.以下是如何将此注释应用于字段的示例。

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

It's possible to specify different type adapters on a field, that field's type, and in the com.google.gson.GsonBuilder.可以在一个字段、该字段的类型和 com.google.gson.GsonBuilder 中指定不同的类型适配器。 Field annotations take precedence over GsonBuilder-registered type adapters, which in turn take precedence over annotated types.字段注释优先于 GsonBuilder 注册的类型适配器,而后者又优先于带注释的类型。

The class referenced by this annotation must be either a TypeAdapter or a TypeAdapterFactory, or must implement one or both of JsonDeserializer or JsonSerializer.此注解引用的类必须是 TypeAdapter 或 TypeAdapterFactory,或者必须实现 JsonDeserializer 或 JsonSerializer 之一或两者。 Using TypeAdapterFactory makes it possible to delegate to the enclosing Gson instance.使用 TypeAdapterFactory 可以委托给封闭的 Gson 实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM