[英]JodaTime LocalDate/LocalTime not Parsing with custom JSON Serializer classes
我有稱為對象ReportEvent
這需要在一個LocalTime
,以及一個LocalDate
從JodaTime
API /框架。 此ReportEvent
可以通過Google的GSON
轉換API寫入JSON
。 但是,在反序列化JodaTime partial
會導致問題。
Logcat錯誤報告:
10-16 13:23:01.812: E/AndroidRuntime(8884): FATAL EXCEPTION: main
10-16 13:23:01.812: E/AndroidRuntime(8884): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nanospark.cnc/com.nanospark.cnc.MainActivity}: java.lang.IllegalArgumentException: Invalid format: "{"iChronology":{"iBase":{"iMinDa..."
10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread.access$600(ActivityThread.java:141)
10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
10-16 13:23:01.812: E/AndroidRuntime(8884): at android.os.Handler.dispatchMessage(Handler.java:99)
10-16 13:23:01.812: E/AndroidRuntime(8884): at android.os.Looper.loop(Looper.java:137)
10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread.main(ActivityThread.java:5103)
10-16 13:23:01.812: E/AndroidRuntime(8884): at java.lang.reflect.Method.invokeNative(Native Method)
10-16 13:23:01.812: E/AndroidRuntime(8884): at java.lang.reflect.Method.invoke(Method.java:525)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-16 13:23:01.812: E/AndroidRuntime(8884): at dalvik.system.NativeStart.main(Native Method)
10-16 13:23:01.812: E/AndroidRuntime(8884): Caused by: java.lang.IllegalArgumentException: Invalid format: "{"iChronology":{"iBase":{"iMinDa..."
10-16 13:23:01.812: E/AndroidRuntime(8884): at org.joda.time.format.DateTimeFormatter.parseLocalDateTime(DateTimeFormatter.java:854)
10-16 13:23:01.812: E/AndroidRuntime(8884): at org.joda.time.format.DateTimeFormatter.parseLocalDate(DateTimeFormatter.java:798)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.nanospark.cnc.LocalDateSerializer.deserialize(LocalDateSerializer.java:32)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.nanospark.cnc.LocalDateSerializer.deserialize(LocalDateSerializer.java:1)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:95)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:183)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.Gson.fromJson(Gson.java:805)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.Gson.fromJson(Gson.java:770)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.google.gson.Gson.fromJson(Gson.java:719)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.nanospark.cnc.GlobalData.retrieveGlobalDataFromStorage(GlobalData.java:118)
10-16 13:23:01.812: E/AndroidRuntime(8884): at com.nanospark.cnc.MainActivity.onCreate(MainActivity.java:35)
10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.Activity.performCreate(Activity.java:5133)
10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
10-16 13:23:01.812: E/AndroidRuntime(8884): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
10-16 13:23:01.812: E/AndroidRuntime(8884): ... 11 more
代碼的相關部分:
LocalTime序列化器/反序列化器。
package com.nanospark.cnc;
import java.lang.reflect.Type;
import org.joda.time.LocalTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
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;
public class LocalTimeSerializer implements JsonDeserializer<LocalTime>, JsonSerializer<LocalTime>
{
private static final DateTimeFormatter TIME_FORMAT = ISODateTimeFormat.timeNoMillis();
@Override
public LocalTime deserialize(final JsonElement je, final Type type,
final JsonDeserializationContext jdc) throws JsonParseException
{
final String dateAsString = je.toString();
if (je.isJsonNull() || dateAsString.length() == 0)
{
return null;
}
else
{
return TIME_FORMAT.parseLocalTime(dateAsString);
}
}
@Override
public JsonElement serialize(final LocalTime src, final Type typeOfSrc,
final JsonSerializationContext context)
{
String retVal;
if (src == null)
{
retVal = "";
}
else
{
retVal = TIME_FORMAT.print(src);
}
return new JsonPrimitive(retVal);
}
}
LocalDate序列化器/反序列化器。
public class LocalDateSerializer implements JsonSerializer<LocalDate>, JsonDeserializer<LocalDate>
{
private static final String PATTERN = "yyyy-MM-dd";
final DateTimeFormatter fmt = DateTimeFormat.forPattern(PATTERN);
@Override
public JsonElement serialize(LocalDate src, Type typeOfSrc, JsonSerializationContext context)
{
String retVal = fmt.print(src);
Log.v("MY LOCALDATE SERIALIZED", retVal);
return new JsonPrimitive(retVal);
}
@Override
public LocalDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException
{
Log.v("MY LOCALDATE DESERIALIZED",json.toString());
return fmt.parseLocalDate(json.toString());
}
}
問題在於您擁有的序列化數據的代碼。
在您最初的問題中,當您要反序列化時有以下代碼( retrieveGlobalDataFromStorage
):
final GsonBuilder builder = new GsonBuilder()
.registerTypeAdapter(LocalDate.class, new LocalDateSerializer())
.registerTypeAdapter(LocalTime.class, new LocalTimeSerializer());
final Gson gson = builder.create();
但是,當您要序列化 ( storeGlobalData
)時,您只有:
Gson gson = new Gson();
您應該在兩個地方都注冊類型適配器。 我將代碼( Gson
初始化)提取到一個單獨的方法中,您可以從這兩個方法中調用該方法。
在使用deserialize()
時也要小心
return fmt.parseLocalDate(json.toString());
因為它會產生可能的意外引號""2014-10-28""
。
最好改用:
return fmt.parseLocalDate(json.getAsString());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.