首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >GSON java如何在映射和打印之间创建不同的名称?

GSON java如何在映射和打印之间创建不同的名称?
EN

Stack Overflow用户
提问于 2016-07-12 19:29:41
回答 2查看 5.2K关注 0票数 4

我有一个这样的JSON:

代码语言:javascript
复制
{
  "aggregation": {
    "CityAgg" : {
      "key" : "Paris"
    }
  }
}

我创建了映射,并为每个字段添加了一个@SerializedName,因为我想为变量创建自定义名称。

例如,在JSON中,有一个键名为key,但我希望我在Java语言中的变量是cityName

所以,我这样做:

代码语言:javascript
复制
@SerializedName("key")
public String cityName

我可以动态地将响应JSON映射到我的对象,如下所示:

代码语言:javascript
复制
Gson gson = new Gson();
Query2 query2 = gson.fromJson(response, Query2.class);

它工作得很完美。

但是,当我想要打印映射的对象时,我会这样做:

代码语言:javascript
复制
String query2String = gson.toJson(query2);
Gson gsonPretty = new GsonBuilder().setPrettyPrinting().create();
String prettyJson = gsonPretty.toJson(query2String);

问题是,在prettyJson中,我可以看到key,而不是cityName

我想知道是否有定制的方法。我不想见key

EN

回答 2

Stack Overflow用户

发布于 2016-07-12 20:08:49

您可以使用Custom Deserializer,也可以使用反射更改注释值。

更新:最糟糕的解决方案

使用反射看起来像这样

代码语言:javascript
复制
    ClassLoader classLoader = URLClassLoader.newInstance(new URL[]{YourClass.class.getResource("YourClass.class")});
    Class locAnnotation = classLoader.loadClass("yourPackage.Query2");

    Field field = locAnnotation.getDeclaredField("cityName");
    final Annotation fieldAnnotation = field.getAnnotation(SerializedName.class);
    changeAnnotationValue(fieldAnnotation, "oldValue", "newValue");


public static Object changeAnnotationValue(Annotation annotation, String key, Object newValue) {
    Object handler = Proxy.getInvocationHandler(annotation);
    Field f;
    try {
        f = handler.getClass().getDeclaredField("memberValues");
    } catch (NoSuchFieldException | SecurityException e) {
        throw new IllegalStateException(e);
    }
    f.setAccessible(true);
    Map<String, Object> memberValues;
    try {
        memberValues = (Map<String, Object>) f.get(handler);
    } catch (IllegalArgumentException | IllegalAccessException e) {
        throw new IllegalStateException(e);
    }
    Object oldValue = memberValues.get(key);
    if (oldValue == null || oldValue.getClass() != newValue.getClass()) {
        throw new IllegalArgumentException();
    }
    memberValues.put(key, newValue);
    return oldValue;
}
票数 0
EN

Stack Overflow用户

发布于 2016-07-12 21:05:19

如果您不想像Viswanath Lekshmanan提到的那样编写自定义序列化程序/反序列化程序类,则始终可以创建某种DTO对象。

您的域类:

代码语言:javascript
复制
class CityAgg {
    @SerializedName("key")
    protected String cityName;

    public String getCityName() {
        return cityName;
    }
}

class Aggregation {
    @SerializedName("CityAgg")
    protected CityAgg cityAgg;

    public CityAgg getCityAgg() {
        return cityAgg;
    }
}

class Query2 {
    @SerializedName("aggregation")
    protected Aggregation aggregation;

    public Aggregation getAggregation() {
        return aggregation;
    }
}

示例DTO类:

代码语言:javascript
复制
class CityAggDto {
    protected String cityName;

    public CityAggDto(CityAgg query2) {
        this.cityName = query2.getCityName();
    }
}

示例用法:

代码语言:javascript
复制
String response = "{ \"aggregation\": { \"CityAgg\": { \"key\": \"value\" } } }";

Gson gson = new Gson();
Gson gsonPretty = new GsonBuilder().setPrettyPrinting().create();

Query2 query2 = gson.fromJson(response, Query2.class);
CityAggDto cityAggDto = new CityAggDto(query2.getAggregation().getCityAgg());

String cityAggDtoJson = gson.toJson(cityAggDto);
String cityAggDtoPrettyJson = gsonPretty.toJson(cityAggDto);

Log.d(TAG, "onCreate: " + cityAggDtoJson);
Log.d(TAG, "onCreate: " + cityAggDtoPrettyJson);

结果:

@SerializationName注释用于两个操作-序列化和反序列化-这就是为什么您的JSON字符串包含key键。

令人遗憾的是,尽管@SerializationName注释可以与方法一起使用-使用不同的getter和setter值将无法工作,因为GSON仅基于字段:

使用字段与getter来指示Json元素

一些Json库使用类型的getter来推导Json元素。我们选择使用所有非瞬态、静态或合成的字段(在继承层次结构中向上)。我们这样做是因为并不是所有的类都是用适当命名的getter编写的。此外,getXXX或isXXX可能是语义的,而不是指示属性。

然而,也有很好的论据来支持属性。我们打算在较新版本中增强Gson,以支持属性作为指示Json字段的替代映射。目前,Gson是基于字段的。

来源:https://github.com/google/gson/blob/master/GsonDesignDocument.md

这就是为什么我换成了杰克逊。:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38327636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档