【Spring】JSONリクエストのBoolean型以外のパラメータを暗黙的にBooleanに変換させない
Spring2ではJSONリクエスト/レスポンスボディのマッピングの際、Boolean型メンバに非Booleanの値をマッピングしようとしたときに正常に処理を終えてしまいます。
例えば、"1" や "true" という文字列を渡してもtrueに変換され、 "0" や "false" 文字列を渡すとfalseに変換されるといった塩梅です。
これは fasterxml/Jacksonのデフォルト仕様で 、このマッピングを防ぐにはSpringで使用されるObjectMapperの設定を修正する必要があります。
環境
- Kotlin: 1.3.21
- Spring: 2.1.4 RELEASE
- JDK : OpenJDK11.0.2
ソースはKotlinです。
Deserializerを定義
JSONリクエストパラメータをKotlin内オブジェクトにマッピングする際の規則を明示的に記述する Deserializer
クラスを定義します。
BooleanDeserializer
class BooleanDeserializer : JsonDeserializer<Boolean>() { // JSONパラメータをBooleanにマッピングしようとすると呼ばれる override fun deserialize(jsonParser: JsonParser, ctxt: DeserializationContext): Boolean { return jsonParser.booleanValue // booleanValue : booleanでない値のときに参照されるとJsonParseError } }
deserialize
メソッドはJSONパラメータをBooleanにマッピングしようとすると呼ばれます。このとき、 booleanでない値をマッピングしようとするとJsonParseErrorが呼ばれるので、制御したい場合は適宜ハンドリングしてください。
DeserializerをObjectMapperに適用する
次に作成したDeserializerをSpringが使用するObjectMapperに設定し、前述の変換規則が適用されるようにします。
JsonConfig
@Configuration class JsonConfig { @Bean fun objectMapperBuilder(): Jackson2ObjectMapperBuilder { val builder = Jackson2ObjectMapperBuilder() return builder } @Bean fun objectMapper(): ObjectMapper { val objectMapper = objectMapperBuilder().build<ObjectMapper>() objectMapper.registerModule(createModule()) return objectMapper } private fun createModule(): Module { val module = SimpleModule() // boolean型以外を暗黙的に許可しない module.addDeserializer(Boolean::class.java, BooleanDeserializer()) return module } }
Springで使用される ObjectMapper
及び ObjectMapperBuilder
を、@Bean
宣言したメソッドで上書きしています。
さらに createModule()
内で BooleanDecelializer
を登録した Module
オブジェクトを生成し、それを ObjectMapper
に登録しました。