search
LoginSignup
23

More than 5 years have passed since last update.

posted at

updated at

Jacksonを使ってみた

やりたいこと

  • JavaのオブジェクトをJSON文字列に簡単に変換したい
  • JSON文字列をJavaのオブジェクトに簡単に変換したい
  • JSONの要素名を小文字アンダーバー区切り(snake_case)にしたい
  • オブジェクトのメンバーにenumがある場合はenum列挙子固有の任意の整数値をvalueにしたい
    • 何種類もenumがあっても最小限のコード追加で同様のことができるようにしたい
  • 日付のフォーマットをISO8601にしたい
  • 改行・インデントがある形式のJSON文字列を作りたい
  • 単体オブジェクトとListオブジェクトに対応
JacksonTest.java
package sandbox;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;

public class JacksonTest {
    long id;
    String name;
    Type type;
    Date createdAt;
    @JsonIgnore boolean fooFlag;

    public JacksonTest() {
    }

    public JacksonTest(long id, String name, Type type, Date createdAt, boolean fooFlag) {
        this.id = id;
        this.name = name;
        this.type = type;
        this.createdAt = createdAt;
        this.fooFlag =fooFlag;
    }

    public long getId() {
        return id;
    }


    public void setId(long id) {
        this.id = id;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public Type getType() {
        return type;
    }


    public void setType(Type type) {
        this.type = type;
    }


    public Date getCreatedAt() {
        return createdAt;
    }


    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public boolean isFooFlag() {
        return fooFlag;
    }

    public void setFooFlag(boolean fooFlag) {
        this.fooFlag = fooFlag;
    }

    public static void main(String[] args) throws Exception {
        // 単体
        JacksonTest obj = new JacksonTest(1234L, "ガンダム", Type.ROBOT, new Date(), true);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"));// ISO8601

        String jsonStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        System.out.println(jsonStr);

        JacksonTest dest = mapper.readValue(jsonStr, JacksonTest.class);
        System.out.println(dest.id + ", " + dest.name + ", " + dest.type + ", " + dest.createdAt + ", " + dest.fooFlag);

        // List
        List<JacksonTest> list = new ArrayList<JacksonTest>() {{
            add(new JacksonTest(1234L, "ガンダム", Type.ROBOT, new Date(), true));
            add(new JacksonTest(1235L, "アベ総理", Type.HUMAN, new Date(), true));
            add(new JacksonTest(1236L, "猫ひろし", Type.ANIMAL, new Date(), true));
        }};

        jsonStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(list);
        System.out.println(jsonStr);

        List<JacksonTest> destList = mapper.readValue(jsonStr, new TypeReference<List<JacksonTest>>(){});
        System.out.println("size = " + destList.size());
        System.out.println(destList.get(1).getName());

    }
}

enum Type implements JsonEnumInt {
    HUMAN(1),
    ANIMAL(2),
    ROBOT(100);
    private int value;
    private Type(int value) {
        this.value = value;
    }

    @JsonValue
    @Override
    public int getValue() {
        return value;
    }

    @JsonCreator
    public static Type fromValue(int value) {
        return Util.getEnumFromValue(value, Type.class);
    }
}

interface JsonEnumInt {
    public int getValue();
}

class Util {
    public static <E extends JsonEnumInt> E getEnumFromValue(int value, Class<E> clazz) {
        try {
            Method method = clazz.getMethod("values");
            @SuppressWarnings("unchecked")
            E[] array = (E[]) method.invoke(null);
            for (E e : array) {
                if (e.getValue() == value) {
                    return e;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

結果

{
  "id" : 1234,
  "name" : "ガンダム",
  "type" : 100,
  "created_at" : "2013-06-03T14:42:55+09:00"
}
1234, ガンダム, ROBOT, Mon Jun 03 14:42:55 JST 2013, false
[ {
  "id" : 1234,
  "name" : "ガンダム",
  "type" : 100,
  "created_at" : "2013-06-03T14:42:55+09:00"
}, {
  "id" : 1235,
  "name" : "アベ総理",
  "type" : 1,
  "created_at" : "2013-06-03T14:42:55+09:00"
}, {
  "id" : 1236,
  "name" : "猫ひろし",
  "type" : 2,
  "created_at" : "2013-06-03T14:42:55+09:00"
} ]
size = 3
アベ総理

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
23