やりたいこと
- 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
アベ総理