2

currently I'm designing a domain model for an application. I created a simple value object that's basically just a wrapper around a string enhanced with some business logic.

Now the default behaviour of jackson is to render the object like

"routerId": {
    "routerId": "aa:aa:aa:aa:aa:aa"
}

for

@Embeddable
data class RouterId(val routerId: String) {

    init {
        val octets = routerId.split(":")

        if (octets.size != 6) {
            throw IllegalArgumentException("$routerId does not consist of 6 octets")
        }

        for (octet in octets) {
            Integer.parseInt(octet, 16)
        }
    }
}

I stumbeld accross http://docs.spring.io/spring-data/rest/docs/2.6.3.RELEASE/reference/html/#_adding_custom_de_serializers_to_jackson_s_objectmapper and tried to supply my custom jackson module to handle serialization with

class NicemediaModule : SimpleModule("NicemediaModule") {

    override fun setupModule(context: SetupContext?) {
        val serializers = SimpleSerializers()
        serializers.addSerializer(RouterId::class.java, RouterIdSerializer())

        context?.addSerializers(serializers)
    }
}

private class RouterIdSerializer : StdSerializer<RouterId>(RouterId::class.java) {

    override fun serialize(value: RouterId?, gen: JsonGenerator?, provider: SerializerProvider?) {
        gen?.writeString(value?.routerId)
    }
}

and

@Configuration
open class SpringDataRestConfiguration : RepositoryRestConfigurerAdapter() {

    override fun configureJacksonObjectMapper(objectMapper: ObjectMapper?) {
        objectMapper?.registerModule(NicemediaModule())
    }
}

but this only leads to

"routerId": {
    "content": "aa:aa:aa:aa:aa:aa"
}

Could anyone point out what I would have to do to serialize the RouterId just to a plain string like "routerId": "aa:aa:aa:aa:aa:aa"?

Edit: I added @Component to my SimpleModule so that Spring Boot loads it by default and wrote a litte test to see if the ObjectMapper works.

@SpringBootTest
@RunWith(SpringRunner::class)
class JsonSerializationTest {

    @Autowired
    private lateinit var mapper: ObjectMapper

    @Test
    fun serializeRouterId() {
        val routerId: String = "11:11:11:11:11:11"
        assertEquals("\"$routerId\"", mapper.writeValueAsString(RouterId(routerId)))
    }
}

works quite fine. This may be an indicator that my code is working the whole time but Spring Data REST fails to serialize my model at some point.

1 Answers1

0

Try implementing a custom BackendIdConverter SPI as suggested in this answer. Works like a charm!

wjans
  • 10,009
  • 5
  • 32
  • 43