簡體   English   中英

改裝GSON將json字符串中的Date序列化為long或java.lang.Long

[英]Retrofit GSON serialize Date from json string into long or java.lang.Long

我正在對我的REST調用使用Retrofit庫。 傳入的JSON如下所示。

{
    "created_at": "2013-07-16T22:52:36Z",
} 

如何告訴Retrofit或Gson將其轉換為long

您可以通過在改造實例上使用您自己的Gson對象設置自定義GsonConverter來輕松實現此目的。 在您的POJO中,您可以創建Date created_at; 而不是long或String。 在日期對象中,可以在需要時使用created_at.getTime()獲取時長。

Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssz")
.create();

RestAdapter.Builder builder = new RestAdapter.Builder();
// Use a custom GSON converter
builder.setConverter(new GsonConverter(gson));
..... create retrofit service.

您還可以通過在改造使用的gson實例上注冊自定義JsonDeserializer來支持多種Date字符串格式。

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Date.class, new DateTypeDeserializer());

public class DateTypeDeserializer implements JsonDeserializer<Date> {
    private static final String[] DATE_FORMATS = new String[]{
            "yyyy-MM-dd'T'HH:mm:ssZ",
            "yyyy-MM-dd'T'HH:mm:ss",
            "yyyy-MM-dd",
            "EEE MMM dd HH:mm:ss z yyyy",
            "HH:mm:ss",
            "MM/dd/yyyy HH:mm:ss aaa",
            "yyyy-MM-dd'T'HH:mm:ss.SSSSSS",
            "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS",
            "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'",
            "MMM d',' yyyy H:mm:ss a"
    };

    @Override
    public Date deserialize(JsonElement jsonElement, Type typeOF, JsonDeserializationContext context) throws JsonParseException {
        for (String format : DATE_FORMATS) {
            try {
                return new SimpleDateFormat(format, Locale.US).parse(jsonElement.getAsString());
            } catch (ParseException e) {
            }
        }
        throw new JsonParseException("Unparseable date: \"" + jsonElement.getAsString()
                + "\". Supported formats: \n" + Arrays.toString(DATE_FORMATS));
    }
}

在您的POJO中以字符串形式讀取它,然后使用getter將其返回很長一段時間:

String created_at;

public long getCreatedAt(){
    SimpleDateFormat formatter = new 
              SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    Date createDate = formatter.parse(created_at);

    return createDate.getTime();
 }

可以在此處引用SimpleDateFormat字符串

閱讀文檔后,我嘗試了一下。 它有效,但我不知道它是否會對其他類型產生影響。

我的POJO需要很長的時間,因為保存到db時我不想轉換。

我使用了自定義解串器

JsonDeserializer<Long> deserializer = new JsonDeserializer<Long>() {
    @Override
    public Long deserialize(JsonElement json, Type typeOfT,
        JsonDeserializationContext context) throws JsonParseException {
        try{
            if(json==null){
               return new Long(0);
            }
            else{
                String dateString = json.getAsString();
                long dateLong = DateFormatUtil.getLongServerTime(dateString);
                return new Long(dateLong);
            }
        }
        catch(ParseException e){
            return new Long(0);
        }
    }
};

並使用它

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .setDateFormat(patternFromServer)
    .registerTypeAdapter(Long.class, deserializer)
    .create();

您可以簡單地使用此setDateFormat()方法進行操作

public class RestClient
{
    private static final String BASE_URL = "your base url";
    private ApiService apiService;

    public RestClient()
    {
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'")
                .create();

        RestAdapter restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setEndpoint(BASE_URL)
                .setConverter(new GsonConverter(gson))
                .build();

        apiService = restAdapter.create(ApiService.class);
    }

    public ApiService getApiService()
    {
        return apiService;
    }
}

下面的代碼已經過測試,並且經過大量努力終於可以正常工作。 在創建改造對象之前,先創建Gson對象

 Gson gson = new GsonBuilder()
                .registerTypeAdapter(Date.class, new DateDeserializer())
                .registerTypeAdapter(Date.class, new DateSerializer())
                .create();

現在創建改造實例

 Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("URL")
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .build();

創建這兩個類以序列化和反序列化日期格式

static class DateDeserializer implements JsonDeserializer<Date> {

        private final String TAG = DateDeserializer.class.getSimpleName();

        @Override
        public Date deserialize(JsonElement element, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
            String date = element.getAsString();

            SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
            formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
            Date returnDate = null;
            try {
                returnDate = formatter.parse(date);
            } catch (ParseException e) {
                Log.e(TAG, "Date parser exception:", e);
                returnDate = null;
            }
            return returnDate;
        }
    }

    static class DateSerializer implements JsonSerializer<Date> {

        private final String TAG = DateSerializer.class.getSimpleName();

        @Override
        public JsonElement serialize(Date date, Type type, JsonSerializationContext jsonSerializationContext) {
            SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
            formatter.setTimeZone(TimeZone.getDefault());
            String dateFormatAsString = formatter.format(date);
            return new JsonPrimitive(dateFormatAsString);
        }

    }

您可以在GsonBuilder.setDateFormat()設置解析模式,並在POJO中設置Date對象,然后只需調用Date.getMillis()

setDateFormat()

您應該通過以下方式在Gson實例中使用類型適配器

new GsonBuilder()
    .registerTypeAdapter(Date.class, [date deserializer class here])
    .create

但我可以建議,而是采用了SimpleDateFormatter你看看從FasterXML /傑克遜-數據綁定實現這個實現在ISO8601日期處理這一類這一個 這在很大程度上取決於您是否要解析很多日期。

還要注意,我們在Android應用程序(我們使用Java和Android庫的組合)中使用SimpleDateFormatter時遇到問題,在Java和Android中進行解析的結果不同。 使用上述實現有助於解決此問題。

這是Java實現 ,這是Android實現 ,不是Java實現中ZX的定義以及Android中缺少的X實現

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM