【问题标题】:Gson how to get serialized nameGson如何获取序列化名称
【发布时间】:2014-06-09 05:51:43
【问题描述】:

当我们定义一个如下格式的类时

public class Field {
    @SerializedName("name")
    public String name;
    @SerializedName("category")
    public String category;

}

对于JsonObject 内容

{
    "name" : "string",
    "category" : "string",
}

并使用Gson解析内容

Field field = new GsonBuilder().create().fromJson(
                content, Field.class);

所以,我的问题是我们可以使用Gson 来获取@Serialized 名称。因为在这种情况下,我想知道 @Serialized 名称用于 field.name,即 namefield.category,即 category

根据@Sotirios Delimanolis 的建议,使用Reflection 我们可以获得Serialized 名称

java.lang.reflect.Field fields = Field.class.getDeclaredField("name");             
SerializedName sName =fields.getAnnotation(SerializedName.class);            
System.out.println(sName.value()); 

【问题讨论】:

  • 如果我们有"name",那么就不需要使用反射和获取值。有没有办法只从字段中获取,比如只使用变量name,而不实际使用字符串“name”

标签: java gson


【解决方案1】:

使用反射来检索您想要的Field 对象。然后,您可以使用Field#getAnnotation(Class) 获取SerializedName 实例,您可以在该实例上调用value() 来获取名称。

【讨论】:

  • 我正在使用这样的field 是我的ObjectField。我正在使用field.name.getClass().getAnnotation(SerializedName.class).value()。但它给了我NullPointer Exception
  • @laaptu 你的班级被命名为Field 并没有帮助。我的意思是java.lang.reflect.Field。获取 your Field 类的 Class 对象并使用 getDeclaredField() 获取 Field 对象用于您的 name 字段。
  • java.lang.reflect.Field fields = Field.class.getDeclaredField("name"); SerializedName sName =fields.getAnnotation(SerializedName.class); System.out.println(sName.value()); 谢谢。但是没有reflection 就没有其他方法可以实现,因为我听说reflection 是CPU 密集型的。我正在为Android 开发这个
  • @laaptu 不,反射是做你所要求的唯一方法。你到底需要这个做什么?
  • @Solitrious Delimanolis:我想要的是使用我使用Gsonlibrary 解析的值向服务器发出POST 请求。意思是,我想将POST 参数发送为{"name":"userInputValue","category":"userInputCategory"}i.e。使用相同的 @Serialized("name") 名称值作为 POST 键。
【解决方案2】:

不是用Field.class 解析,你不能把它解析成JsonObject.class 吗?然后使用JsonObject.get():

import com.google.gson.JsonObject;

Gson gson = new GsonBuilder().create();
JsonObject jsonObject = gson.fromJson(content, JsonObject.class);
String serializedName = jsonObject.get("name").getAsString();

请注意,.getAsString() 会将其作为不带嵌入双引号的字符串返回,将其与调用 toString() 时进行比较。


我试图做的一件事是序列化一个枚举字段,它不是一个对象。在这种情况下,您可以使用JsonElement.class 进行序列化,因为它只是一个原语:

import com.google.gson.JsonElement;

Gson gson = new GsonBuilder().create();
JsonElement jsonElement = gson.fromJson("\"a\"", JsonElement.class);
String serializedName = jsonElement.getAsString();

【讨论】:

    【解决方案3】:

    这是alternate 的一种方式,例如更复杂的示例

    枚举类

    public enum SomeStatusCd {
    
        @SerializedName(
            value = "status_1",
            alternate = {"an alternate 1", "an alternate 2"}
        )
        STATUS_1("status_1")
        ....
    }
    

    从备用获取枚举

    public static SomeStatusCd getFromAlternate(String alternateFieldName){
        SomeStatusCd result = null;
        Field[] statusDeclaredFields = SomeStatusCd.class.getDeclaredFields();
        String foundEnumName = null;
        for (Field statusDeclaredField : statusDeclaredFields) {
            SerializedName annotation = statusDeclaredField.getAnnotation(SerializedName.class);
            if (annotation != null){
                String[] declaredFieldAlternates = annotation.alternate();
                for (String declaredFieldAlternate : declaredFieldAlternates) {
                    if (declaredFieldAlternate.equals(alternateFieldName)){
                        foundEnumName = statusDeclaredField.getName();
                    }
                }
            }
        }
        if (foundEnumName != null){
            for (SomeStatusCd enumConstant : SomeStatusCd.class.getEnumConstants()) {
                if (enumConstant.name().equals(foundEnumName)){
                    result = enumConstant;
                }
            }
        }
    
        return result;
    }
    

    测试一下

        SomeStatusCd fromAlternate = getFromAlternate("an alternate 1");
        assertSame(fromAlternate, SomeStatusCd.STATUS_1);
    

    【讨论】:

      猜你喜欢
      • 2012-09-13
      • 1970-01-01
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-19
      • 1970-01-01
      相关资源
      最近更新 更多