java 如何使用Gson将HashMap转换为JSON并返回?

yhqotfr8  于 5个月前  发布在  Java
关注(0)|答案(1)|浏览(90)

后台

我只想保存和加载一些JSON作为字符串,起源于<LocalDate,Int>的HashMap
问题所在
虽然我成功地从HashMap生成了JSON字符串,但我没有做相反的事情,从JSON字符串生成HashMap。

我所尝试的

这就是我转换为JSON字符串的方法:

val gson = Gson()
val type = object:TypeToken<Map<LocalDate, Int>>(){}.type
val map: HashMap<LocalDate, Int> = HashMap()
val today = LocalDate.now()
map[today] = 1
val jsonStr = gson.toJson(map, type) // example of what this has: "{"2024-01-01":1}"

字符串
我也可以用它来证明解析字符串是可行的:

val jsonObject = JSONObject(jsonStr)


并检查它的值:
瓦尔countForToday = jsonObject.getInt(today.toString())
然而,当我使用这个(在查看here之后):

var newMap: Map<LocalDate, Int> = gson.fromJson(jsonStr, object : TypeToken<Map<LocalDate, Int>>() {}.type)


我得到这个例外:

Method threw 'com.google.gson.JsonSyntaxException' exception.
IllegalStateException: Expected BEGIN_OBJECT but was STRING at line...


我尝试过,但都失败了,基于我从其他例子中看到的:
1.我尝试使用GsonBuilder().create()而不是Gson(),我认为这不重要,尽管Gson()可能是一个可以在任何地方使用的单例,甚至可能是线程安全的。
1.使用Map代替HashMap,使用Any代替Int,使用?(可空)。所有各种组合我可以想到...
现在我使用这个解决方案,不使用Gson转换回HashMap:

val jsonObject = JSONObject(jsonStr)
val hashHap = HashMap<LocalDate, Int>()
jsonObject.keys().forEach { key: String ->
    val date = LocalDate.parse(key)
    val value = jsonObject.getInt(key)
    hashHap[date] = value
}


这个可以,但我想知道为什么Gson失败了。
问题
这是怎么回事?为什么我不能做这个简单的转换回HashMap/Map(使用Gson)?

vwkv1x7d

vwkv1x7d1#

看起来你在转换LocalDate时遇到了问题。问题是GSON似乎无法识别LocalDate对象。你需要有一个自定义的Date序列化器和Date转换器。它看起来像这样:

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 *
 * @author asgar
 */
public class LocalDateConverter implements JsonSerializer<LocalDate>, JsonDeserializer<LocalDate> {

    @Override
    public JsonElement serialize(LocalDate src, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(DateTimeFormatter.ISO_LOCAL_DATE.format(src));
    }

    @Override
    public LocalDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {
        return DateTimeFormatter.ISO_LOCAL_DATE.parse(json.getAsString(), LocalDate::from);
    }
}

字符串
然后你就可以使用它了。下面是一个示例代码:

public static void main(String[] args) {
        
        GsonBuilder builder = new GsonBuilder();

        builder.registerTypeAdapter(new TypeToken<LocalDate>() {}.getType(), new LocalDateConverter());
        
        Gson gson1 = builder.create();

        String jsonString = "{\"2023-01-01\":10,\"2023-02-15\":20,\"2023-05-08\":15,\"2023-08-20\":30}";
        
        Type type = new TypeToken<HashMap<LocalDate, Integer>>() {}.getType();
        
        Map<LocalDate, Integer> map = gson1.fromJson(jsonString, type);

        System.out.println("HashMap1: " + map);
    }


有关更多信息,请参阅this

相关问题