【问题标题】:java.lang.NumberFormatException: For input string: "2017-01-28 13:28:20"java.lang.NumberFormatException:对于输入字符串:“2017-01-28 13:28:20”
【发布时间】:2017-01-28 10:01:52
【问题描述】:

在我的 java 项目中,有一个 gson 反序列化器函数会导致以下错误。

java.lang.NumberFormatException: For input string: "2017-01-28 13:28:20"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:589)
at java.lang.Long.parseLong(Long.java:631)
at com.google.gson.JsonPrimitive.getAsLong(JsonPrimitive.java:238)
at com.example.myproject.controller.MyController$1.deserialize(MyController.java:222)
at com.example.myproject.controller.MyController$1.deserialize(MyController.java:1)
at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58)
at com.google.gson.internal.bind.TypeAdapters$22$1.read(TypeAdapters.java:526)
at com.google.gson.internal.bind.TypeAdapters$22$1.read(TypeAdapters.java:524)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
at com.google.gson.Gson.fromJson(Gson.java:803)
at com.google.gson.Gson.fromJson(Gson.java:768)
at com.google.gson.Gson.fromJson(Gson.java:717)
at com.google.gson.Gson.fromJson(Gson.java:689)

我在反序列化下面的 json 字符串时收到此错误。

jsonString = {"repList":[{"createdOn":"2017-01-28 13:28:20","date":"2016-11-17 00:00:00","description":"","id":45,"userId":10}],"subList":[{"attachmentCount":0,"dateOn":"2017-01-28 13:28:20","id":86,"screenId":1,"sync":"1","repId":45,"userId":10}]}

下面是我完成 gson 反序列化的函数。

SimpleDateFormat dtf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.ENGLISH);
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {

    @Override
    public Date deserialize(JsonElement json, Type type, JsonDeserializationContext deserializationContext) throws JsonParseException {

        String frStr = dtf.format(new Date(json.getAsJsonPrimitive().getAsLong()));
        dtf.setTimeZone(TimeZone.getDefault());
        Date retDate =null;
            try {
                retDate = dtf.parse(frStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        return retDate;
    }
});
gson = builder.create();
MainAccounts mainAcc = gson.fromJson(jsonString, MainAccounts.class);

我注意到当我将 json 原语转换为 long 时出现异常

json.getAsJsonPrimitive().getAsLong()

在反序列化方法中。我该如何解决这个问题?请帮助我。

【问题讨论】:

    标签: java json date gson


    【解决方案1】:

    您需要直接获取JsonElement 的值,因为它实际上是:String 而不是long,通过调用方法getAsString() 否则您将获得NumberFormatException,正如您已经注意到的那样,所以你的JsonDeserializer 应该是:

    new JsonDeserializer<Date>() {
        private SimpleDateFormat dtf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        {
            // Indicate the time zone of the input date
            dtf.setTimeZone(TimeZone.getTimeZone("Asia/Dubai"));
        }
        @Override
        public Date deserialize(JsonElement json, Type type, 
            JsonDeserializationContext deserializationContext) throws JsonParseException {
            try {
                // Get the json element as a String and parse it to get a Date
                return dtf.parse(json.getAsString());
            } catch (ParseException e) {
                // Throw a JsonParseException in case of a parsing error
                throw new JsonParseException(e);
            }
        }
    }
    

    注意: 实际上,上面提出的JsonDeserializer 类型的匿名内部类不是线程安全的,因为SimpleDateFormat 本身不是线程安全的,因此请避免共享它,只要你想反序列化你的 JSON 内容,就创建一个新实例。

    【讨论】:

    • 好的。它现在可以工作了。此外,上面的 json 字符串附带的日期值对应于迪拜时区,现在我需要将其转换为服务器时区(即在印度),以便日期值更改为印度时间。我怎样才能与格式一起做到这一点?
    • @KJEjava48 解析时重要的是输入时区,因为 java.util.Date 与时区无关(它实际上是 UTC 中的时间戳),请查看 this 了解更多详细信息。另见stackoverflow.com/questions/7670355/…
    • @LyubomyrShaydariv 是的,它不是用来分享的,所以这不是一个真正的问题,但我确实应该提一下
    • @NicolasFilotto 我不明白你在说什么。我需要为上述 json 序列化和反序列化创建一个类并将这个类与 GsonBuilder 一起使用吗??
    • 在你的代码中调用方法registerTypeAdapter时,第一个参数是Date.class,我的回答中提出的匿名内部类应该是第二个参数
    【解决方案2】:

    我认为问题在于该值不是表示 long 的字符串,因此您不能这样解析它。您可能应该使用String frStr = dtf.parse(json.getAsJsonPrimitivie().getAsString())

    【讨论】:

    • 当我打印 json.getAsJsonPrimitive() 的值时,这是我得到的值“2017-01-28 13:28:20”
    猜你喜欢
    • 1970-01-01
    • 2012-12-05
    • 2013-09-04
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    相关资源
    最近更新 更多