JsonProperty is ignored on data class properties with names starting with
  • 30-May-2023
Lightrun Team
Author Lightrun Team
Share
JsonProperty is ignored on data class properties with names starting with

@JsonProperty is ignored on data class properties with names starting with “is”

Lightrun Team
Lightrun Team
30-May-2023

Explanation of the problem

The issue at hand involves a data class with a boolean property named isPublic that needs to be serialized exactly as “isPublic” in JSON. However, due to the property name starting with “is,” the “is” prefix is stripped from the name during serialization. The attempted solution of annotating the property with @JsonProperty("isPublic") did not resolve the issue. The problem manifests when using the Jackson library for JSON serialization in a Kotlin test class.

data class MyClass(
    @JsonProperty("isPublic")
    val isPublic: Boolean
)

Troubleshooting with the Lightrun Developer Observability Platform

Getting a sense of what’s actually happening inside a live application is a frustrating experience, one that relies mostly on querying and observing whatever logs were written during development.
Lightrun is a Developer Observability Platform, allowing developers to add telemetry to live applications in real-time, on-demand, and right from the IDE.

  • Instantly add logs to, set metrics in, and take snapshots of live applications
  • Insights delivered straight to your IDE or CLI
  • Works where you do: dev, QA, staging, CI/CD, and production

Start for free today

Problem solution for @JsonProperty is ignored on data class properties with names starting with “is”

To address the issue of the property name being incorrectly serialized in JSON, a workaround involves renaming the field in the data class and using the @JsonProperty annotation to expose it with the desired name. For example, by renaming the isConnected property to connected and annotating it with @JsonProperty("isConnected"), the serialization process can be adjusted to correctly include the desired field name in the JSON output.

data class MyDTO(
    @JsonProperty("isConnected")
    val connected: Boolean
)

By applying this workaround, the issue of the incorrect field name in the JSON output can be resolved. It is important to note that the original property should not be named isConnected to avoid conflicts with the naming conventions used by the serialization process. Instead, the property should be renamed to a different name (e.g., connected) and then exposed with the desired name using the @JsonProperty annotation.

It is worth mentioning that the effectiveness of this workaround may vary depending on the specific use case and the libraries or frameworks being used. Therefore, it is recommended to test and verify the solution in the context of the project at hand. By renaming the property and applying the @JsonProperty annotation, you can achieve the desired field name in the JSON output, resolving the issue of incorrect serialization.

Please note that the provided code block represents an example of the workaround proposed in the answers. The actual implementation may vary based on the specific requirements and context of your project.

Other popular problems with jackson-module-kotlin

Problem: Serializing Null Values

By default, FasterXML Jackson omits properties with null values during serialization. This can lead to unexpected behavior, especially when working with REST APIs.

Solution:

To force Jackson to include null values in serialized JSON, you can set the SerializationFeature.WRITE_NULL_MAP_VALUES feature to true on the ObjectMapper used for serialization.

val mapper = ObjectMapper().apply {
    enable(SerializationFeature.WRITE_NULL_MAP_VALUES)
}

Problem: Handling Polymorphic Types

When working with polymorphic types (i.e. classes that have multiple subclasses), you need to specify how Jackson should determine the correct type to use during serialization and deserialization.

Solution:

To handle polymorphic types with Jackson, you can use the @JsonTypeInfo and @JsonSubTypes annotations to specify the type information to include in the serialized JSON, and how to map the type information to the corresponding class.

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes(
    JsonSubTypes.Type(value = Square::class, name = "square"),
    JsonSubTypes.Type(value = Circle::class, name = "circle")
)
sealed class Shape

data class Square(val sideLength: Double) : Shape()

data class Circle(val radius: Double) : Shape()

Problem: Handling Dates and Times

By default, FasterXML Jackson uses the default java.util.Date type to represent dates and times, which can lead to issues with time zones and format.

Solution:

To handle dates and times in a more robust manner, you can use the java.time package introduced in Java 8 and configure Jackson to use these classes for serialization and deserialization.

You can use the JSR310Module from the jackson-datatype-jsr310 module to register the Java 8 date and time classes with the ObjectMapper:

val mapper = ObjectMapper().apply {
    registerModule(JavaTimeModule())
}

And then, annotate the date and time properties in your class with the appropriate Jackson annotations, such as @JsonFormat to specify the format of the serialized string:

data class Event(
    @get:JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
    val timestamp: LocalDateTime
)

A brief introduction to jackson-module-kotlin

FasterXML jackson-module-kotlin is a Java library for processing JSON data. It is a module for FasterXML Jackson, a widely used and high-performance JSON processing library. The jackson-module-kotlin module provides specific support for the Kotlin programming language, making it easy to serialize and deserialize Kotlin objects to and from JSON.

FasterXML jackson-module-kotlin provides a variety of features to make it easy to work with JSON data in a Kotlin environment. For example, it supports the serialization and deserialization of Nullable types, using the ? operator in Kotlin. It also provides support for the serialization and deserialization of data classes, making it easy to serialize and deserialize complex data structures. Additionally, the library provides support for custom serialization and deserialization logic, so you can define custom behavior for serializing and deserializing specific types or properties.

Most popular use cases for jackson-module-kotlin

  1. JSON Processing: FasterXML jackson-module-kotlin can be used to parse and generate JSON data. It provides a simple and efficient API for converting between JSON data and Kotlin objects.
val mapper = ObjectMapper()
val jsonString = """
    {
        "name": "John Doe",
        "age": 35
    }
"""
val user = mapper.readValue(jsonString, User::class.java)
  1. Data Binding: FasterXML jackson-module-kotlin can be used to bind JSON data to Kotlin objects and vice versa. The library provides support for a wide range of data types, including nullables, arrays, and complex data structures.
data class User(val name: String, val age: Int)

val mapper = ObjectMapper()
val user = User("John Doe", 35)
val json = mapper.writeValueAsString(user)
  1. Custom Serialization and Deserialization: FasterXML jackson-module-kotlin can be used to customize the serialization and deserialization process for specific types and properties. This allows you to define custom behavior for serializing and deserializing specific types or properties, for example, to handle custom date formats or to map JSON properties to different Kotlin properties.
data class User(
    @get:JsonProperty("full_name") val name: String,
    val age: Int
)
Share

It’s Really not that Complicated.

You can actually understand what’s going on inside your live applications.

Try Lightrun’s Playground

Lets Talk!

Looking for more information about Lightrun and debugging?
We’d love to hear from you!
Drop us a line and we’ll get back to you shortly.

By submitting this form, I agree to Lightrun’s Privacy Policy and Terms of Use.