Kotlin + Spring Boot/ResponseEntityを使ったJSONレスポンスにJacksonの@JsonPropertyを有効にする
Spring Bootを使ってkotlinで書いています。サーバサイドでkotlinを使うと新たな発見があるのでいいですね。
ControllerのレスポンスにResponseEntityを使ったところdata classのプロパティを@JsonPropertyでリネームしたのに有効になりませんでした。
自分のググラビリティが低く解決方法が見つからず小一時間ほど費やしてしまいました。同じような人(いれば)のために解決方法をメモします。
こんな環境で試しました
- Spring Bootは1.4.2
- kotlinは1.0.4
次のようなdata classを用意します。
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クラスを返します。
@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) }
次のようなレスポンスになります
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モジュールを追加すると解決します。
github.com
Gradle:
compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.8.4"
kotlinモジュールを追加すると次のようなレスポンスになります
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の宣言は以下のように変える必要があります。
data class User( val userId: Long, val name: String, @get:JsonIgnore val age: Int, @JsonProperty("isGold") val gold: Boolean = false )
data classを更新して再度レスポンスをとると
curl -X GET http://localhost:8080/test/member/1 | python -m json.tool { "isGold": true, "name": "name", "userId": 1 }
期待する結果となりました:clap:
kotlinで@JsonPropertyの使い方を調べていたら棚から牡丹餅のように@JsonIgnoreの使い方も学べました。
ソースを公開しています
ソースコードを公開しています。
github.com