3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Spring Boot(Jackson)でJsonの空文字をNULLで受け取る方法

Posted at

概要

Spring Bootで従来までのControllerをRestContorllerに変更した際に、これまでInitBinderで設定していたStringTrimmerEditorの設定が効かなくなってしまいました。
これは入力データを処理する仕組みがRestController(@RequestBody)ではJacksonで処理されるためです。

サンプルはKotlinで記述していますが、Javaでも基本的に同じです。

設定ファイル(application.yml)で設定を試みる

application.ymlにてそれっぽい設定項目を発見し、試してみました。

application.yml
  jackson:
    deserialization:
      ACCEPT_EMPTY_STRING_AS_NULL_OBJECT: true

が、、、いろいろ試しましたが、うまくいきませんでした。
変換先がPOJOじゃないとだめみたいです。

[参考]
https://stackoverflow.com/questions/22688713/jackson-objectmapper-deserializationconfig-feature-accept-empty-string-as-null-o

解決方法

結局設定ファイルではうまくいかず、Stringを変換する独自Deserializerを作成しObjectMapperに設定することにしました。

1. Deserializerクラスの作成

JsonDeserializerを継承してクラスを作成しても良かったのですが、標準で設定されているStringDeserializerの中身を見てみるとそれなりに処理が書かれていたので、StringDeserializerを継承してクラスを作成することにしました。

EmptyToNullStringDeserializer.kt

package ...

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.deser.std.StringDeserializer

class EmptyToNullStringDeserializer : StringDeserializer() {
    override fun deserialize(p: JsonParser, ctxt: DeserializationContext): String? {
        val result = super.deserialize(p, ctxt)
        return if(result.isNotEmpty()) result else null
    }
}

スーパークラスの返した値を最終行で空文字かチェックしているだけの処理となります。

2. ObjectMapperへの登録

適当なConfigクラスを生成(すでにあるものに追加してもOK)しObjectMapperのBeanを定義します。

JacksonConfig.kt
package ...

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder

@Configuration
class JacksonConfig {
    @Bean
    fun jacksonBuilder(): Jackson2ObjectMapperBuilder {
        return Jackson2ObjectMapperBuilder()
                .deserializerByType(String::class.java, EmptyToNullStringDeserializer())
    }
}

以上です。

まとめ

簡単な設定に見えて結構はまってしまいました。
普段は何も考えずにJacksonを使っているのですが、もう少し勉強が必要な気がします。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?