我有一个这样的JSON:
{
"aggregation": {
"CityAgg" : {
"key" : "Paris"
}
}
}我创建了映射,并为每个字段添加了一个@SerializedName,因为我想为变量创建自定义名称。
例如,在JSON中,有一个键名为key,但我希望我在Java语言中的变量是cityName。
所以,我这样做:
@SerializedName("key")
public String cityName我可以动态地将响应JSON映射到我的对象,如下所示:
Gson gson = new Gson();
Query2 query2 = gson.fromJson(response, Query2.class);它工作得很完美。
但是,当我想要打印映射的对象时,我会这样做:
String query2String = gson.toJson(query2);
Gson gsonPretty = new GsonBuilder().setPrettyPrinting().create();
String prettyJson = gsonPretty.toJson(query2String);问题是,在prettyJson中,我可以看到key,而不是cityName。
我想知道是否有定制的方法。我不想见key。
发布于 2016-07-12 20:08:49
您可以使用Custom Deserializer,也可以使用反射更改注释值。
更新:最糟糕的解决方案
使用反射看起来像这样
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;
}发布于 2016-07-12 21:05:19
如果您不想像Viswanath Lekshmanan提到的那样编写自定义序列化程序/反序列化程序类,则始终可以创建某种DTO对象。
您的域类:
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类:
class CityAggDto {
protected String cityName;
public CityAggDto(CityAgg query2) {
this.cityName = query2.getCityName();
}
}示例用法:
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
这就是为什么我换成了杰克逊。:)
https://stackoverflow.com/questions/38327636
复制相似问题