Kotlin + Spring Boot/ResponseEntityを使ったJSONレスポンスにJacksonの@JsonPropertyを有効にする


Spring Bootを使ってkotlinで書いています。サーバサイドでkotlinを使うと新たな発見があるのでいいですね。
ControllerのレスポンスにResponseEntityを使ったところdata classのプロパティを@JsonPropertyでリネームしたのに有効になりませんでした。
自分のググラビリティが低く解決方法が見つからず小一時間ほど費やしてしまいました。同じような人(いれば)のために解決方法をメモします。

こんな環境で試しました

次のようなdata classを用意します。

1
2
3
4
5
6
7
8
data class Member(
        val userId: Long,
        val name: String,
        @JsonIgnore
        val age: Int,
        @JsonProperty("isGold")
        val gold: Boolean = false
)

@JsonProperty(“isGold”)のようにJsonレスポンスではgoldのプロパティ名をisGoldにしたいです。次のようなコントローラーでMemberクラスを返します。

1
2
3
4
@RequestMapping(value = "/member/{id}", method = arrayOf(RequestMethod.GET))
open fun getUser(@PathVariable id: Long): ResponseEntity<Member> {
    return ResponseEntity(Member(id, "name", 20, true), HttpStatus.OK)
}

次のようなレスポンスになります

1
2
3
4
5
6
curl -X GET http://localhost:8080/test/member/1 | python -m json.tool
{
    "gold": true,
    "name": "name",
    "userId": 1
}

ageは @JsonIgnoreで隠れているのに、goldがisGoldではありません。
こんな状況でした。

kotlinモジュールを使う

kotolinモジュールを追加すると解決します。

Gradle:

1
compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.8.4"

kotlinモジュールを追加すると次のようなレスポンスになります

1
2
3
4
5
6
7
curl -X GET http://localhost:8080/test/member/1 | python -m json.tool
{
    "age": 20,
    "isGold": true,
    "name": "name",
    "userId": 1
}

isGoldになりました!!・・??、@JsonIgnoreしたageがignoreされていない。。kotlinモジュールを有効にしたら@JsonIgnoreの宣言は以下のように変える必要があります。

1
2
3
4
5
6
7
8
data class User(
        val userId: Long,
        val name: String,
        @get:JsonIgnore
        val age: Int,
        @JsonProperty("isGold")
        val gold: Boolean = false
)

data classを更新して再度レスポンスをとると

1
2
3
4
5
6
curl -X GET http://localhost:8080/test/member/1 | python -m json.tool
{
    "isGold": true,
    "name": "name",
    "userId": 1
}

期待する結果となりました👏kotlinで@JsonPropertyの使い方を調べていたら棚から牡丹餅のように@JsonIgnoreの使い方も学べました。

ソースを公開しています

ソースコードを公開しています。

https://github.com/soushin/kotlin-json-parse