This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Boot 3.5.5! |
JSON
Spring Boot provides integration with three JSON mapping libraries:
-
Gson
-
Jackson 3
-
JSON-B
-
Kotlin Serialization
Jackson is the preferred and default library.
Jackson
Auto-configuration for Jackson is provided and Jackson is part of spring-boot-starter-json
.
When Jackson is on the classpath a JsonMapper
bean is automatically configured.
Several configuration properties are provided for customizing the configuration of the JsonMapper
.
Custom Serializers and Deserializers
If you use Jackson to serialize and deserialize JSON data, you might want to write your own ValueSerializer
and ValueDeserializer
classes.
Custom serializers are usually registered with Jackson through a module, but Spring Boot provides an alternative @JsonComponent
annotation that makes it easier to directly register Spring Beans.
You can use the @JsonComponent
annotation directly on ValueSerializer
, ValueDeserializer
or KeyDeserializer
implementations.
You can also use it on classes that contain serializers/deserializers as inner classes, as shown in the following example:
-
Java
-
Kotlin
import tools.jackson.core.JsonGenerator;
import tools.jackson.core.JsonParser;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.SerializationContext;
import tools.jackson.databind.ValueDeserializer;
import tools.jackson.databind.ValueSerializer;
import org.springframework.boot.jackson.JsonComponent;
@JsonComponent
public class MyJsonComponent {
public static class Serializer extends ValueSerializer<MyObject> {
@Override
public void serialize(MyObject value, JsonGenerator jgen, SerializationContext context) {
jgen.writeStartObject();
jgen.writeStringProperty("name", value.getName());
jgen.writeNumberProperty("age", value.getAge());
jgen.writeEndObject();
}
}
public static class Deserializer extends ValueDeserializer<MyObject> {
@Override
public MyObject deserialize(JsonParser jsonParser, DeserializationContext ctxt) {
JsonNode tree = jsonParser.readValueAsTree();
String name = tree.get("name").stringValue();
int age = tree.get("age").intValue();
return new MyObject(name, age);
}
}
}
import tools.jackson.core.JsonGenerator
import tools.jackson.core.JsonParser
import tools.jackson.databind.DeserializationContext
import tools.jackson.databind.JsonNode
import tools.jackson.databind.SerializationContext
import tools.jackson.databind.ValueDeserializer
import tools.jackson.databind.ValueSerializer
import org.springframework.boot.jackson.JsonComponent
@JsonComponent
class MyJsonComponent {
class Serializer : ValueSerializer<MyObject>() {
override fun serialize(value: MyObject, jgen: JsonGenerator, serializers: SerializationContext) {
jgen.writeStartObject()
jgen.writeStringProperty("name", value.name)
jgen.writeNumberProperty("age", value.age)
jgen.writeEndObject()
}
}
class Deserializer : ValueDeserializer<MyObject>() {
override fun deserialize(jsonParser: JsonParser, ctxt: DeserializationContext): MyObject {
val tree = jsonParser.readValueAsTree<JsonNode>()
val name = tree["name"].stringValue()
val age = tree["age"].intValue()
return MyObject(name, age)
}
}
}
All @JsonComponent
beans in the ApplicationContext
are automatically registered with Jackson.
Because @JsonComponent
is meta-annotated with @Component
, the usual component-scanning rules apply.
Spring Boot also provides ObjectValueSerializer
and ObjectValueDeserializer
base classes that provide useful alternatives to the standard Jackson versions when serializing objects.
See ObjectValueSerializer
and ObjectValueDeserializer
in the API documentation for details.
The example above can be rewritten to use ObjectValueSerializer
and ObjectValueDeserializer
as follows:
-
Java
-
Kotlin
import tools.jackson.core.JsonGenerator;
import tools.jackson.core.JsonParser;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.SerializationContext;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.boot.jackson.ObjectValueDeserializer;
import org.springframework.boot.jackson.ObjectValueSerializer;
@JsonComponent
public class MyJsonComponent {
public static class Serializer extends ObjectValueSerializer<MyObject> {
@Override
protected void serializeObject(MyObject value, JsonGenerator jgen, SerializationContext context) {
jgen.writeStringProperty("name", value.getName());
jgen.writeNumberProperty("age", value.getAge());
}
}
public static class Deserializer extends ObjectValueDeserializer<MyObject> {
@Override
protected MyObject deserializeObject(JsonParser jsonParser, DeserializationContext context, JsonNode tree) {
String name = nullSafeValue(tree.get("name"), String.class);
int age = nullSafeValue(tree.get("age"), Integer.class);
return new MyObject(name, age);
}
}
}
import tools.jackson.core.JsonGenerator
import tools.jackson.core.JsonParser
import tools.jackson.databind.DeserializationContext
import tools.jackson.databind.JsonNode
import tools.jackson.databind.SerializationContext
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.boot.jackson.ObjectValueDeserializer
import org.springframework.boot.jackson.ObjectValueSerializer
@JsonComponent
class MyJsonComponent {
class Serializer : ObjectValueSerializer<MyObject>() {
override fun serializeObject(value: MyObject, jgen: JsonGenerator, context: SerializationContext) {
jgen.writeStringProperty("name", value.name)
jgen.writeNumberProperty("age", value.age)
}
}
class Deserializer : ObjectValueDeserializer<MyObject>() {
override fun deserializeObject(jsonParser: JsonParser, context: DeserializationContext,
tree: JsonNode): MyObject {
val name = nullSafeValue(tree["name"], String::class.java) ?: throw IllegalStateException("name is null")
val age = nullSafeValue(tree["age"], Int::class.java) ?: throw IllegalStateException("age is null")
return MyObject(name, age)
}
}
}
Mixins
Jackson has support for mixins that can be used to mix additional annotations into those already declared on a target class.
Spring Boot’s Jackson auto-configuration will scan your application’s packages for classes annotated with @JsonMixin
and register them with the auto-configured JsonMapper
.
The registration is performed by Spring Boot’s JsonMixinModule
.
Gson
Auto-configuration for Gson is provided.
When Gson is on the classpath a Gson
bean is automatically configured.
Several spring.gson.*
configuration properties are provided for customizing the configuration.
To take more control, one or more GsonBuilderCustomizer
beans can be used.
JSON-B
Auto-configuration for JSON-B is provided.
When the JSON-B API and an implementation are on the classpath a Jsonb
bean will be automatically configured.
The preferred JSON-B implementation is Eclipse Yasson for which dependency management is provided.
Kotlin Serialization
Auto-configuration for Kotlin Serialization is provided.
When kotlinx-serialization-json
is on the classpath a Json bean is automatically configured.
Several spring.kotlin.serialization.*
configuration properties are provided for customizing the configuration.