gson 将特定字段解释为大写

rpe*_*yng 5 java enums serialization json gson

我有一个包含一些字段的类,例如

public class Message {

    public Enum Type {
        TEXT,
        PICTURE;
    }

    private Type type;
    private String text;
    private int id;
}
Run Code Online (Sandbox Code Playgroud)

假设我有一个如下所示的 json

[ { "id" : "1",
    "data" : "hello",
    "type" : "text",
  },
  { "id" : "2",
    "data" : "<someImageUrl>",
    "type" : "picture",
  },
]
Run Code Online (Sandbox Code Playgroud)

我可以通过调用轻松反序列化它

Gson gson = new Gson();
ArrayList<Message> messages = gson.fromJson(jsonResult, new TypeToken<List<Message>>() {}.getType());
Run Code Online (Sandbox Code Playgroud)

凉爽的。不幸的是,由于 json 对象和枚举中定义的实例之间的大小写差异,Type 字段仍然为空。如何更改 gson 的行为,以便它将 json Type 对象解释为大写。

我想到的潜在解决方法:

  • 将序号值分配给将匹配 json 中给出的内容的枚举类型(即 TEXT("text")
  • 用分隔符“}”分割json结果,
  • 用 -SOMEE​​NUMTYPE- 替换所有出现的 -someEnumType-

就像是

public enum Type {
    TEXT("text"),
    PICTURE("picture");

    private final String value

    private MessageType(String value) {
        this.value = value;
    }

    public String getValue() {
        return value
    }
}
...

   String[] jsonResultSplit = StringUtils.split(jsonResult, "},") 
   for (String jsonMessage : jsonResultSplit) {
        for (MessageType messageType : MessageType.values()) {
            if (jsonMessage.contains("\"type:\" : \"" + messageType.getValue() + "\"")) {
                jsonMessage.replace(
                        "\"type:\" : \"" + messageType.getValue() + "\"",
                        "\"type:\" : \""
                                + StringUtils.capitalize(messageType.getValue() + "\""));
            }
        }
    }
    jsonResult = StringUtils.join(jsonResultSplit);
    Gson gson = new Gson();
    ArrayList<Message> messages = gson.fromJson(jsonResult, new TypeToken<List<Message>>() {}.getType());
Run Code Online (Sandbox Code Playgroud)

然而,这似乎有点麻烦,如果消息包含“}”或其他内容,则字符串将被错误地拆分。

Pur*_*ham 6

最简单的方法是对 Enum 使用 @SerializedName 注释。

public Enum Type {
    @SerializedName("text")
    TEXT,

    @SerializedName("picture")
    PICTURE
}
Run Code Online (Sandbox Code Playgroud)

@SerializedName 例如,不仅可以用于大写,还可以用于更改枚举或变量的名称

public enum Gender {
    @SerializedName("boy")
    MALE,

    @SerializedName("girl")
    FEMALE
}
Run Code Online (Sandbox Code Playgroud)

参考

同样如@Sotirios 所建议的那样,您需要注释text以将 json 键映射到您的变量。

 @SerializedName("data")
 private String text;
Run Code Online (Sandbox Code Playgroud)

您现在可以像之前一样使用 Gson 反序列化您的 json

Gson gson = new Gson();
ArrayList<Message> messages = gson.fromJson(jsonResult, new TypeToken<List<Message>>() {}.getType());
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助...


Sot*_*lis 2

您必须注册自己的TypeAdapter才能进行转换

Gson gson = new GsonBuilder().registerTypeAdapter(Type.class,
            new TypeAdapter<Type>() {

                @Override
                public void write(JsonWriter out, Type value)
                        throws IOException {
                    out.value(value.name().toLowerCase());
                }

                @Override
                public Type read(JsonReader in) throws IOException {
                    return Type.valueOf(in.nextString().toUpperCase());
                }
            }).create();
Run Code Online (Sandbox Code Playgroud)

请注意,您还应该注释

private String text;
Run Code Online (Sandbox Code Playgroud)

因为@SerializedName("data")它与 JSON 名称不匹配。

"data" : "hello",
Run Code Online (Sandbox Code Playgroud)