マイナー・マイナー

隠れた名作の発掘が生きがい。

【Java】日付のフォーマットが異なるJSONデータをオブジェクトに変換する


スポンサードリンク

日付のフォーマットが異なるJSONデータをDTOなどにしたい場合もあったりします。下記のようなJSONデータをGsonライブラリを利用してデータオブジェクトに変換する処理をメモしました。

{
     "date": "2013-09-17",
     "created_at": "2013-09-16T22:32:36Z",
     "msg":"hello"
}

モデルの定義

下記のようなモデルクラスを考えます。


Foo.java

package test.codes._Sample;

import java.io.Serializable;
import java.util.Date;

public class Foo implements Serializable {
    private static final long serialVersionUID = 1L;
   
    Date date;
    Date created_at;
    String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Date getCreated_at() {
        return created_at;
    }

    public void setCreated_at(Date created_at) {
        this.created_at = created_at;
    }

    public Foo() {
    }

    public Foo(Date date, Date created_at) {
        this.date = date;
        this.created_at = created_at;
    }

    @Override
    public String toString() {
        return "Foo [date=" + date + ", created_at=" + created_at + ", msg=" + msg + "]";
    }
}

dateとcreated_atが同じフォーマットの場合

GsonBuilderのsetDateFormatに日付のフォーマットを指定してGsonオブジェクトを作成し、そのオブジェクトのデシリアライザを呼び出すことでモデルオブジェクトができます。


App.java

package test.codes._Sample;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class App
{
    public static void main( String[] args )
    {
        String jsonData = "{\"date\": \"2013-09-17\", \"created_at\": \"2013-09-16\", \"msg\":\"hello\"}";

        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
        Foo myObject = gson.fromJson(jsonData, Foo.class);

        System.out.println("Result: "+myObject);
    }
}


出力結果:

Result: Foo [date=Tue Sep 17 00:00:00 JST 2013, created_at=Mon Sep 16 00:00:00 JST 2013, msg=hello]


もし、setDateFormatがない場合は、デシリアライズ時にcom.google.gson.JsonSyntaxExceptionがスローされます。

dateとcreated_atが同じフォーマットの場合

GsonBuilderに、日付フォーマットごとのデシリアライズ処理を記述したデシリアライザを登録します。そのGsonBuilderよりGsonオブジェクトを作成してデシリアライズします。


メイン処理は下記のようになります。
App.java

package test.codes._Sample;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class App
{
    public static void main( String[] args )
    {
        String jsonData = "{\"date\": \"2013-09-17\", \"created_at\": \"2013-09-16T22:32:36Z\", \"msg\":\"hello\"}";

        GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(Foo.class, new FooDeserializer());

        Gson gson = builder.create();
        Foo myObject = gson.fromJson(jsonData, Foo.class);

        System.out.println("Result: "+myObject);
    }
}


デシリアライザでは、Json項目がdateであれば"yyyy-MM-dd"に、created_atであれば"yyyy-MM-dd'T'HH:mm:ss'Z'"のように変換してFooオブジェクトを作成するように記述します。

FooDeserializer.java

package test.codes._Sample;

import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;

public class FooDeserializer implements JsonDeserializer<Foo> {

    public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        String strDate = json.getAsJsonObject().get("date").getAsString();
        String strDateTime = json.getAsJsonObject().get("created_at").getAsString();

        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

        Date date, dateTime;
        try {
            date = sdfDate.parse(strDate);
            dateTime = sdfDateTime.parse(strDateTime);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        Foo deserializedFoo = new Foo();
        deserializedFoo.setDate(date);
        deserializedFoo.setCreated_at(dateTime);

        String msg = json.getAsJsonObject().get("msg").getAsString();
        deserializedFoo.setMsg(msg);

        return deserializedFoo;
    }

}


出力結果:

Result: Foo [date=Tue Sep 17 00:00:00 JST 2013, created_at=Mon Sep 16 22:32:36 JST 2013, msg=hello]