Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Gson:如何从序列化更改特定字段键_Java_Gson_Pojo - Fatal编程技术网

Java Gson:如何从序列化更改特定字段键

Java Gson:如何从序列化更改特定字段键,java,gson,pojo,Java,Gson,Pojo,我正在使用Gson进行序列化,并且正在努力动态更改字段名。这是我的班级: 公众课堂反应 { 私有字符串状态; 私有字符串消息; 私有T数据; 公共响应集数据 { 这是setDatadata; } 公共字符串getStatus{ 返回状态; } public void setStatusString状态{ 这个状态=状态; } 公共字符串getMessage{ 返回消息; } 公共void setMessageString消息{ this.message=消息; } 公共获取数据{ 返回数据; }

我正在使用Gson进行序列化,并且正在努力动态更改字段名。这是我的班级:

公众课堂反应 { 私有字符串状态; 私有字符串消息; 私有T数据; 公共响应集数据 { 这是setDatadata; } 公共字符串getStatus{ 返回状态; } public void setStatusString状态{ 这个状态=状态; } 公共字符串getMessage{ 返回消息; } 公共void setMessageString消息{ this.message=消息; } 公共获取数据{ 返回数据; } 公共无效setDataT数据{ 这个数据=数据; } }
我必须根据资源动态更改字段名。有什么方法可以更改此项吗?

如果您需要更改字段名称,而这意味着您不需要类型安全性,那么以下操作可以完成:

Map<String, Object> response = new LinkedHashMap<>();
response.put("message", message);
response.put("status", status);
response.put(dynamicFieldName, dynamicFieldValue);
String json = gson.toJson(response);

您仍然可以在这个低级代码之上包装一个方便的库来解释常见的用例。

为什么不在这些用例中使用HashMap

private HashMap<String, String> data;

public HashMap<String, String> getData() {
    return this.data;
}

public void setDataValue(String key, String value) {
    data.put(key, value);
}

请注意,数据字段可以是或的HashMap,以保存子对象,从而接受Gson支持的所有类型的结构

使用映射可能不是最佳选择,因为您的响应类可能具有特殊的Gson注释,这些注释将在响应对象转换为映射后被忽略

假设以下简单响应类:

最后的课堂反应{ @Exposeserialize=true 最终字符串状态=状态; @Exposeserialize=true 最终字符串消息=消息; @Exposeserialize=true 最终T数据; @Exposeserialize=false,反序列化=false 最后一个字符串whatever=whatever; 响应最终T数据{ 这个数据=数据; } } 为了简单起见,此响应不使用其他Gson注释。临时使用动态字段重命名:

最终Gson Gson=新的GsonBuilder .ExcludeFields未显示符号 // ... 这里的任何Gson配置。。。 创造 最终响应响应=新响应IMmutableList.offoo,bar; final JsonElement jsonTree=gson.toJsonTreeresponse,stringListResponseTypeToken.getType; 最终JsonObject responseJson=jsonTree.getAsJsonObject; 最终JsonElement dataPropertyJson=responseJson.getdata; Reponsejson.removedata; responseJson.addresponse.getClass.getSimpleName,dataPropertyJson; gson.toJsonresponseJson,System.out; 注意,这里的主要技巧是创建一个中间JSON树并替换动态属性名。不幸的是,此解决方案需要一个中间JSON树。另一个更具Gson风格的解决方案是创建一个特殊类型的适配器,以避免每次需要时都重新映射响应对象

final Gson gson = new GsonBuilder()
        .excludeFieldsWithoutExposeAnnotation()
        // ... any Gson configuration here ...
        .registerTypeAdapterFactory(getDynamicPropertyResponseTypeAdapterFactory())
        .create();
final Response<List<String>> response = new Response<>(ImmutableList.of("foo", "bar"));
gson.toJson(response, stringListResponseTypeToken.getType(), System.out);
上面使用了同样的不太便宜的技巧,但现在它作为Gson实例的一部分工作。对于这两种情况,输出如下:

{状态:状态,消息:消息,响应:[foo,bar]}

您可能需要考虑的另一个选项是:

使响应类抽象,并允许子类通过@SerializedName定义自己的数据字段名称(如果名称应该是硬编码的)。 创建您的实现ReflectTypeAdapterFactory请参阅Gson源代码,并在不创建中间JSON树的情况下使字段名称动态。