【Spring Boot】JacksonによるJSON変換
Jackson とは
Spring Boot における REST API では、戻り値に設定したクラスのインスタンスを JSON に変換してレスポンスを返します。
また、リクエストボディの JSON は、@RequestBody
を付与することで引数に設定したクラスのインスタンスに変換します。
インスタンスから JSON へ変換することを「シリアライズ」、JSON からインスタンスへ変換することを「デシリアライズ」といいます。
@RestController
public class SampleController {
//SampleDataをJSONに変換して返す
@GetMapping
public SampleData get() {
return new SampleData();
}
//JSONデータを受け取り、SampleDataに変換する
@PostMapping
public void post(@RequestBody SampleData sampleData) {
//...
}
}
これらの JSON の変換は、Jackson というライブラリによって行われており、Spring Boot では標準で搭載されています。 この Jackson について知ることにより、より柔軟に JSON を扱うことができるようになります。
プロパティの変更
@JsonProperty
対応するプロパティ名を変更します。 これはシリアライズ、デシリアライズともに適用されます。
public class SampleData {
private String id;
@JsonProperty("first_name")
private String firstName;
@JsonProperty("last_name")
private String lastName;
}
{
"id": "0001",
"first_name": "Taro",
"last_name": "Yamada"
}
@JsonPropertyOrder
シリアライズした JSON のプロパティの出力順を設定します。
@JsonPropertyOrder({"firstName", "lastName", "id"})
public class SampleData {
private String id;
private String firstName;
private String lastName;
}
{
"first_name": "Taro",
"last_name": "Yamada",
"id": "0001"
}
プロパティの除外
@JsonIgnore
指定したプロパティをシリアライズ、デシリアライズの対象外とします。
public class SampleData {
private String id;
@JsonIgnore
private String firstName;
private String lastName;
}
{
"id": "0001",
"lastName": "Yamada"
}
@JsonIgnoreProperties
@JsonIgnore
を一括で設定します。
@JsonIgnoreProperties({"firstName", "lastName"})
public class SampleData {
private String id;
private String firstName;
private String lastName;
}
{
"id": "0001"
}
@JsonInclude
シリアライズで対象外にするプロパティの条件を設定します。 設定できる条件には、以下のようなものがあります。
条件 | 説明 |
---|---|
Include.NON_NULL | null の場合に対象外とする |
Include.NON_EMPTY | 空文字の場合に対象外とする |
Include.NON_DEFAULT | デフォルト値の場合に対象外とする |
NON_NULL
@JsonInclude(Include.NON_NULL) public class SampleData { private String id; private String firstName; private String lastName; }
new SampleData("0001", null, "Yamada");
JSON{ "id": "0001", "lastName": "Yamada" }
NON_EMPTY
@JsonInclude(Include.NON_EMPTY) public class SampleData { private String id; private String firstName; private String lastName; }
new SampleData("0001", "", "Yamada");
JSON{ "id": "0001", "lastName": "Yamada" }
NON_DEFAULT
@JsonInclude(Include.NON_DEFAULT) public class SampleData { private String id = ""; private String firstName = "Taro"; private String lastName = ""; }
new SampleData("0001", "Taro", "Yamada");
JSON{ "id": "0001", "lastName": "Yamada" }
例ではクラスに付与していますが、フィールド単位でも設定できます。
プロパティの出力・設定
@JsonGetter
シリアライズに使用するゲッターを、別のメソッドに変更します。
public class SampleData {
private String id;
private String firstName;
private String lastName;
@JsonGetter("firstName")
public String getTheFirstName() {
return fristName;
}
}
@JsonSetter
デシリアライズに使用するセッターを、別のメソッドに変更します。
public class SampleData {
private String id;
private String firstName;
private String lastName;
@JsonSetter("firstName")
public void setTheFirstName(String firstName) {
this.firstName = firstName;
}
}
@JsonAnyGetter
Map
のゲッターに付与することで、階層を無視してシリアライズします。
public class SampleData {
private String id;
private Map<String, String> name;
@JsonAnyGetter
public Map<String, String> getName() {
return name;
}
}
{
"id": "0001",
"name": {
"firstName": "Taro",
"lastName": "Yamada"
}
}
{
"id": "0001",
"first_name": "Taro",
"last_name": "Yamada"
}
@JsonFormat
シリアライズ、デシリアライズの型とフォーマットパターンを設定します。
public class SampleData {
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy/MM/dd HH:mm:ss")
private Date date;
}
{
"date": "2021/05/01 12:34:56"
}
変換
@JsonValue
シリアライズの処理を指定します。
public class SampleData {
private String id;
private String firstName;
private String lastName;
@JsonValue
public Map<String, Object> toJson() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", id);
map.put("name", firstName + lastName);
return map;
}
}
{
"id": "0001",
"name": "TaroYamada"
}
@JsonCreator
デシリアライズの処理(コンストラクタ)を指定します。
public class SampleData {
private String id;
private String name;
@JsonCreator
public SampleData(String id, String firstName, String lastName) {
this.id = id;
this.name = firstName + lastName;
}
}
{
"id": "0001",
"firstName": "Taro",
"lastName": "Yamada"
}
列挙型の JSON 化
列挙型をシリアライズするには、@JsonValue
を使用します。
public enum EnumSample {
STATE1(1, "0001"),
STATE2(2, "0002");
private int id;
private String name;
private EnumSample(int code, String name) {
this.id = id;
this.name = name;
}
@JsonValue
public Map<String, Object> toJson() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", id);
map.put("name", name);
return map;
}
}
{
"id": 1,
"name": "0001"
}
また、@JsonFormat
を使用しても同じ結果が得られます。
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum EnumSample {
STATE1(1, "0001"),
STATE2(2, "0002");
private int id;
private String name;
private EnumSample(int code, String name) {
this.id = id;
this.name = name;
}
}