我想使用GSON将下面的Example类序列化为JSON。
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.LinkedHashMap;
public class Example
{
private LinkedHashMap<String,Object> General;
private static final String VERSION="Version";
private static final String RANGE="Range";
private static final String START_TIME="Start_Time";
private static final String END_TIME="End_Time";
public Example() {
General = new LinkedHashMap<String,Object>();
General.put(VERSION, "0.1");
LinkedHashMap<String,String> Range = new LinkedHashMap<String, String>();
Range.put(START_TIME, "now");
Range.put(END_TIME, "never");
General.put(RANGE, Range);
}
public String toJSON() {
Gson gson = new GsonBuilder().serializeNulls().create();
return gson.toJson(this);
}
}
我希望得到以下输出:
{"General":{"Version":"0.1","Range":{"Start_Time":"now","End_Time":"never"}}}
但是调用函数toJSON()
会返回
{"General":{"Version":"0.1","Range":{}}}
似乎GSON无法序列化地图Range
内的地图General
。这是GSON的限制还是我在这里做错了什么?
答案 0 :(得分:8)
Nishant's answer的工作原因是因为Gson的默认构造函数默认启用了所有类型的东西,否则你必须手动使用GsonBuilder。
来自JavaDocs:
使用默认配置构造Gson对象。默认配置具有以下设置:
- toJson方法生成的JSON是紧凑的表示形式。这意味着删除了所有不需要的空白区域。您可以使用GsonBuilder.setPrettyPrinting()更改此行为。
- 生成的JSON省略了所有null的字段。请注意,由于数组是有序列表,因此数组中的空值保持不变。此外,如果字段不为null,但其生成的JSON为空,则保留该字段。您可以通过设置GsonBuilder.serializeNulls()将Gson配置为序列化空值。
- Gson为Enums,Map,java.net.URL,java.net.URI,java.util.Locale,java.util.Date,java.math.BigDecimal和java.math.BigInteger提供默认序列化和反序列化类。如果您希望更改默认表示,可以通过GsonBuilder.registerTypeAdapter(Type,Object)注册类型适配器来实现。
- 默认日期格式与java.text.DateFormat.DEFAULT相同。此格式忽略序列化期间日期的毫秒部分。您可以通过调用GsonBuilder.setDateFormat(int)或GsonBuilder.setDateFormat(String)来更改此内容。
- 默认情况下,Gson会忽略com.google.gson.annotations.Expose注释。您可以通过GsonBuilder.excludeFieldsWithoutExposeAnnotation()启用Gson仅序列化/反序列化用此注释标记的字段。
- 默认情况下,Gson会忽略com.google.gson.annotations.Since注释。您可以通过GsonBuilder.setVersion(double)使Gson使用此批注。
- 输出Json的默认字段命名策略与Java中的相同。因此,Java类字段versionNumber将输出为&#34; versionNumber @ quot;在Json。应用相同的规则将传入的Json映射到Java类。您可以通过GsonBuilder.setFieldNamingPolicy(FieldNamingPolicy)更改此策略。
- 默认情况下,Gson会排除考虑序列化和反序列化的瞬态或静态字段。您可以通过GsonBuilder.excludeFieldsWithModifiers(int)更改此行为。
childGenericType
被设置为类型java.lang.Object
,因此值的运行时类型是从未分析过。
我猜两种解决方案:
使用更复杂的方法版本,如下所示:
public String toJSON(){
final Gson gson = new Gson();
final JsonElement jsonTree = gson.toJsonTree(General, Map.class);
final JsonObject jsonObject = new JsonObject();
jsonObject.add("General", jsonTree);
return jsonObject.toString();
}
答案 1 :(得分:4)
试试这个:
Gson gson = new Gson();
System.out.println(gson.toJson(General));
不确定您是否仍在寻找解决方案,这对我有用:
import java.util.LinkedHashMap;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Example {
// private static LinkedHashMap<String,Object> General;
private ImmutableMap General;
private static final String VERSION="Version";
private static final String RANGE="Range";
private static final String START_TIME="Start_Time";
private static final String END_TIME="End_Time";
public Example() {
LinkedHashMap<String,String> Range = new LinkedHashMap<String, String>();
Range.put(START_TIME, "now");
Range.put(END_TIME, "never");
// General.put(RANGE, Range);
General = ImmutableMap.of(VERSION, "0.1", RANGE, Range);
}
public String toJSON() {
// Gson gson = new GsonBuilder().serializeNulls().create();
Gson gson = new Gson();
return gson.toJson(this);
}
}
返回:{“常规”:{“版本”:“0.1”,“范围”:{“Start_Time”:“now”,“End_Time”:“never”}}}
显然,您可以使用ImmutableMap.copyOf(your_hashmap)
here代替
答案 2 :(得分:1)
更简单的替代方法是使用Jackson而不是GSON,嵌套地图的序列化开箱即用:
LinkedHashMap<String, Object> general;
general = new LinkedHashMap<String, Object>();
general.put("Version", "0.1");
LinkedHashMap<String, String> Range = new LinkedHashMap<String, String>();
Range.put("Start_Time", "now");
Range.put("End_Time", "never");
general.put("Range", Range);
// Serialize the map to json using Jackson
ByteArrayOutputStream os = new ByteArrayOutputStream();
new org.codehaus.jackson.map.ObjectMapper().writer().writeValue(os,
general);
String json = os.toString();
os.close();
System.out.println(json);
输出:
{&#34;版本&#34;:&#34; 0.1&#34;&#34;范围&#34; {&#34; START_TIME&#34;:&#34;现在&#34; &#34; END_TIME&#34;:&#34;从未&#34;}}