Jacksonの使い方
依存の取得
Gradleの場合は以下。Java8のOptionalを使う場合は、jackson-datatype-jdk8を入れる。
dependencies {
/* Jackson */
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.9.1'
// which depends on
// implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.9'
// implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.0'
/* Supports Optional */
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version: '2.9.9'
/* for Unit test */
testImplementation group: 'junit', name: 'junit', version: '4.12'
基本的な使い方
以下のユニットテストを起動してみれば一目瞭然と思う。
import java.util.*;
import java.util.stream.*;
import org.junit.*;
import static org.junit.Assert.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.type.*;
import com.fasterxml.jackson.databind.*;
public class SimpleTest {
String DATA = "{\r\n" +
" \"id\": 1,\r\n" +
" \"name\": \"鈴木\",\r\n" +
" \"hoby\": [\r\n" +
" \"fishing\",\r\n" +
" \"映画\"\r\n" +
" ]\r\n" +
"}";
String DATA_ARRAY = "[" + DATA + "," + DATA + "]";
@Test
public void readTest1() throws Exception {
ObjectMapper mapper = new ObjectMapper();
assertEquals("id:1, name:鈴木, hoby:fishing,映画",
mapper.readValue(DATA, Person1.class).toString());
try {
mapper.readValue(DATA, Person2.class);
fail();
} catch (Exception ex) {
}
mapper.readValue(DATA, Person3.class);
assertEquals("id:1, name:鈴木, hoby:fishing,映画",
mapper.readValue(DATA, Person4.class).toString());
}
@Test
public void readTest2() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.readValue(DATA, Person1.class);
mapper.readValue(DATA, Person2.class);
mapper.readValue(DATA, Person3.class);
}
@Test
public void readTest3() throws Exception {
ObjectMapper mapper = new ObjectMapper();
List<Person1>list = mapper.readValue(DATA_ARRAY, new TypeReference<List<Person1>>() {});
assertEquals(
"id:1, name:鈴木, hoby:fishing,映画\n" +
"id:1, name:鈴木, hoby:fishing,映画",
list.stream().map(p->p.toString()).collect(Collectors.joining("\n")));
}
@Test
public void writeTest1() throws Exception {
Person1 p = new Person1();
p.id = 123;
p.name = null;
ObjectMapper mapper = new ObjectMapper();
assertEquals("{\"id\":123,\"name\":null,\"hoby\":null}", mapper.writeValueAsString(p));
}
static class Person1 {
public int id;
public String name;
public List<String> hoby;
@Override
public String toString() {
return "id:" + id +
", name:" + name +
", hoby:" + hoby.stream().collect(Collectors.joining(","));
}
}
static class Person2 {
public int id;
public String name;
}
@JsonIgnoreProperties(ignoreUnknown=true)
static class Person3 {
public int id;
public String name;
}
static class Person4 {
public int id;
public String name;
public String[]hoby;
@Override
public String toString() {
return "id:" + id +
", name:" + name +
", hoby:" + Arrays.stream(hoby).collect(Collectors.joining(","));
}
}
}
Optionalを使う場合
import static org.junit.Assert.*;
import java.util.*;
import java.util.stream.*;
import org.junit.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jdk8.*;
public class OptionalTest {
String DATA = "{\r\n" +
" \"id\": 1,\r\n" +
" \"name\": \"鈴木\",\r\n" +
" \"hoby\": [\r\n" +
" \"fishing\",\r\n" +
" \"映画\"\r\n" +
" ]\r\n" +
"}";
@Test
public void test() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
Person1 p = mapper.readValue(DATA, Person1.class);
assertEquals("id:1, name:Optional[鈴木], hoby:fishing,映画",
p.toString());
assertEquals("null", "" + p.remarks1);
assertEquals("Optional.empty", "" + p.remarks2);
}
static class Person1 {
public int id;
public Optional<String> name;
public List<String> hoby;
public Optional<String>remarks1;
public Optional<String>remarks2 = Optional.empty();
@Override
public String toString() {
return "id:" + id +
", name:" + name +
", hoby:" + hoby.stream().collect(Collectors.joining(","));
}
}
}
まとめ
不明プロパティへの対応
将来的にプロパティが増えても困らないように、ObjectMapper自体に指定しておいた方がよい。
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
もちろん、「フィールド名を勘違いしていた」場合に無視されてしまうのだが、テスト段階で気づけばよいことだ。
Optionalへの対応
Java8のOptionalを使う場合には、Optionalは必ずOptional.empty()で初期化しておかないといけない。フィールドが存在しなくても勝手にOptional.empty()を入れてはくれない。
ディスカッション
コメント一覧
まだ、コメントがありません