skip to content

Jackson Configuration

Configuring the ObjectMapper Spring uses: builder customization, spring.jackson properties, modules like JavaTimeModule, and annotations such as @JsonFormat and @JsonView. Date and null handling in JSON responses is a recurring practical question.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

How does Spring Boot set up Jackson's ObjectMapper for a REST controller, and how do you tweak its behavior without writing Java?

level: juniorimportance: must knowfreq 70%

answer

  1. JacksonAutoConfiguration -> Jackson2ObjectMapperBuilder -> ObjectMapper bean
  2. MappingJackson2HttpMessageConverter does @RequestBody/@ResponseBody
  3. spring.jackson.serialization/deserialization/mapper/*
  4. default-property-inclusion, property-naming-strategy
  5. One shared mapper = global config

basics

~10 s

Spring Boot auto-configures a Jackson ObjectMapper bean and uses it in MappingJackson2HttpMessageConverter to turn objects into JSON. You tweak it declaratively with spring.jackson.* properties in application.yml/properties.

solid answer

~30 s

The spring-boot-starter-web (via starter-json) pulls in Jackson. JacksonAutoConfiguration builds a Jackson2ObjectMapperBuilder, produces a shared ObjectMapper bean, and wires it into MappingJackson2HttpMessageConverter, which serializes @ResponseBody return values and deserializes @RequestBody. You customize it without code through spring.jackson.* keys: serialization/deserialization/mapper/parser/generator feature toggles (e.g. spring.jackson.serialization.indent-output=true, spring.jackson.deserialization.fail-on-unknown-properties=false), default-property-inclusion=non_null, property-naming-strategy=SNAKE_CASE, date-format, time-zone, and locale. These properties feed the auto-configured builder, so you keep all of Spring Boot's sensible defaults (like ISO-8601 dates) while overriding just the pieces you need.

code

yaml · 11 lines
yaml
spring:
  jackson:
    # global @JsonInclude(NON_NULL)
    default-property-inclusion: non_null
    property-naming-strategy: SNAKE_CASE
    time-zone: UTC
    serialization:
      indent-output: true
      write-dates-as-timestamps: false   # ISO-8601 strings (Boot default)
    deserialization:
      fail-on-unknown-properties: false  # ignore extra JSON fields

go deeper

for a junior

Know ObjectMapper does JSON<->object and Boot auto-configures it; know spring.jackson.* exists for simple toggles.

for a middle

Explain the converter wiring, the shared-bean nature, and the common properties (inclusion, naming strategy, feature toggles).

for a senior

Explain how properties feed Jackson2ObjectMapperBuilder, what backs off when you define your own bean, and Boot's non-default choices (no timestamps).

for a principal

Reason about global-config blast radius, keeping Boot defaults, and choosing declarative properties vs a customizer for maintainability.

## What ObjectMapper is `com.fasterxml.jackson.databind.ObjectMapper` is Jackson's central class for converting Java objects to JSON (serialization) and JSON back to Java objects (deserialization). In Spring MVC, JSON conversion happens through an `HttpMessageConverter` — specifically `MappingJackson2HttpMessageConverter` — which holds an `ObjectMapper` and is invoked automatically for `@ResponseBody`/`@RestController` return values and `@RequestBody` method parameters. ## Where the ObjectMapper comes from in Spring Boot You rarely create it yourself. When `jackson-databind` is on the classpath (transitively via `spring-boot-starter-web` -> `spring-boot-starter-json`), Spring Boot's `JacksonAutoConfiguration` runs and: 1. Creates a `Jackson2ObjectMapperBuilder` (Spring's fluent builder that applies opinionated defaults and auto-registers well-known Jackson modules found on the classpath). 2. Uses it to expose a single primary `ObjectMapper` bean. 3. `JacksonHttpMessageConvertersConfiguration` / `WebMvcAutoConfiguration` register a `MappingJackson2HttpMessageConverter` that uses that bean. Because there is one shared, application-wide `ObjectMapper` bean, configuring it once affects every controller. ## Notable Spring Boot defaults (differ from raw Jackson) - `SerializationFeature.WRITE_DATES_AS_TIMESTAMPS` is **disabled**, so `java.time` values serialize as readable ISO-8601 strings (`2026-07-22T10:15:30`) rather than numeric epochs. - Well-known modules on the classpath (e.g. `JavaTimeModule` from `jackson-datatype-jsr310`, `Jdk8Module`) are auto-registered. - Any Spring bean of type `com.fasterxml.jackson.databind.Module` is also registered automatically. ## Tuning with `spring.jackson.*` (no code) These properties are bound to the builder before the `ObjectMapper` is built, so they preserve Boot's defaults. Key groups: - `spring.jackson.serialization.<FEATURE>=true|false` — maps to `SerializationFeature` (e.g. `indent-output`, `write-dates-as-timestamps`, `fail-on-empty-beans`). - `spring.jackson.deserialization.<FEATURE>=...` — `DeserializationFeature` (e.g. `fail-on-unknown-properties=false`). - `spring.jackson.mapper.<FEATURE>=...` — `MapperFeature` (e.g. `default-view-inclusion`). - `spring.jackson.parser.*` / `spring.jackson.generator.*` — `JsonParser.Feature` / `JsonGenerator.Feature`. - `spring.jackson.default-property-inclusion=non_null|non_empty|non_absent|always` — global `@JsonInclude` behavior. - `spring.jackson.property-naming-strategy=SNAKE_CASE|...` — global naming (e.g. `firstName` -> `first_name`). - `spring.jackson.date-format`, `spring.jackson.time-zone`, `spring.jackson.locale`. - `spring.jackson.visibility.<scope>=...` — auto-detection of fields/getters. ## When to use properties vs code Use properties for simple, global toggles. Reach for a `Jackson2ObjectMapperBuilderCustomizer` bean (see the customization question) when you need to register custom serializers/modules or logic that properties can't express. ## Gotchas - Declaring your **own** `@Bean ObjectMapper` makes the auto-configuration back off — you then lose Boot's defaults unless you build it via `Jackson2ObjectMapperBuilder`. - `spring.jackson.*` applies to the auto-configured mapper; if you replace the mapper manually, those properties no longer apply to it. - These settings are global — for per-field overrides use annotations like `@JsonFormat`, `@JsonInclude`, `@JsonProperty`.

  • What happens if you declare your own @Bean ObjectMapper?
    JacksonAutoConfiguration backs off and stops creating its ObjectMapper. Your bean is used everywhere, but you lose Boot's defaults (ISO dates, module auto-registration) unless you build it with Jackson2ObjectMapperBuilder. Prefer a Jackson2ObjectMapperBuilderCustomizer instead.
  • Which property makes null fields disappear from all JSON responses?
    spring.jackson.default-property-inclusion=non_null (equivalent to a global @JsonInclude(Include.NON_NULL)).

saying these in an interview costs you the question

  • Thinking you must manually 'new ObjectMapper()' in every service
  • Believing spring.jackson.* still applies after you define your own ObjectMapper bean
  • Assuming each controller gets its own mapper rather than one shared bean
  • Confusing global spring.jackson.* toggles with per-field annotations

context

open as a page

How does Spring Boot serialize java.time types like LocalDateTime, and how do you control the exact format?

level: middleimportance: must knowfreq 68%

basics

~10 s

The JavaTimeModule (jackson-datatype-jsr310) handles java.time types, and Spring Boot disables WRITE_DATES_AS_TIMESTAMPS so they serialize as ISO-8601 strings. For a specific field, override with @JsonFormat(pattern = ...).

open as a page

What's the correct way to customize the ObjectMapper in Spring Boot, and what's the pitfall of defining your own ObjectMapper bean?

level: seniorimportance: must knowfreq 60%

basics

~10 s

Prefer a Jackson2ObjectMapperBuilderCustomizer bean or spring.jackson.* properties, which tweak the auto-configured mapper while keeping Boot's defaults. Defining your own @Bean ObjectMapper makes auto-config back off, so you lose those defaults.

open as a page

What is @JsonView and how do you use it in Spring MVC to expose different fields on different endpoints?

level: seniorimportance: should knowfreq 45%

basics

~10 s

@JsonView lets one class expose different field subsets per endpoint. You define marker (view) classes, tag fields with @JsonView(View.class), and put @JsonView on the controller method to pick which view serializes.

open as a page

Which Jackson serialization/mapper features matter for building a stable, resilient JSON API, and how do you configure them globally vs per field?

level: principalimportance: should knowfreq 40%

basics

~10 s

Set FAIL_ON_UNKNOWN_PROPERTIES=false for forward-compatible input, choose a global default-property-inclusion (e.g. non_null), disable FAIL_ON_EMPTY_BEANS, register JavaTimeModule, and use annotations like @JsonInclude/@JsonFormat/@JsonProperty for per-field overrides.

open as a page