3.7 Manual JSON Handling with ObjectMapper
While Spring Boot automates JSON processing through @RequestBody and @ResponseBody, in practice, you often need to manually parse JSON in your Java code for integrations with external APIs or complex logic. For this, we use ObjectMapper, the core object of the Jackson library.
1. Basic Usage
Converting Objects to JSON Strings (Serialization)
The process of turning a Java object into a JSON-formatted string is called serialization.
ObjectMapper mapper = new ObjectMapper();
User user = new User("hong", 20);
// Object -> JSON String
String json = mapper.writeValueAsString(user);
// Result: {"name":"hong","age":20}
Converting JSON Strings to Objects (Deserialization)
Conversely, the process of reading a JSON string to create a Java object is called deserialization.
String json = "{\"name\":\"hong\",\"age\":20}";
// JSON String -> Object
User user = mapper.readValue(json, User.class);
2. Handling Collections (List, Map)
ObjectMapper can easily handle collections like lists or maps, not just single objects.
Handling Lists
String jsonList = "[{\"name\":\"hong\"}, {\"name\":\"kim\"}]";
List<User> list = mapper.readValue(jsonList, new TypeReference<List<User>>() {});
Handling Maps
String json = "{\"name\":\"hong\", \"age\":20}";
Map<String, Object> map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {});
3. Key ObjectMapper Configuration Options
You can change the behavior of an ObjectMapper by applying various settings during its creation.
Deserialization Settings (DeserializationFeature)
FAIL_ON_UNKNOWN_PROPERTIES(Default: true):- Determines whether to throw an error if a field exists in the JSON but not in the Java class.
- In practice, this is often set to
falseto flexibly handle API spec changes.
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Serialization Settings (SerializationFeature)
WRITE_DATES_AS_TIMESTAMPS(Default: true):- Determines whether to send date objects as timestamps (numbers) or ISO-8601 strings.
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); // Outputs as string
Inclusion Policy (JsonInclude)
Include.NON_NULL:- Excludes fields with
nullvalues from the resulting JSON.
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);- Excludes fields with
4. Using Class-Level Annotations
You can also control behavior individually by declaring annotations directly on class fields.
@JsonProperty("custom_name"): Used to specify a JSON key name different from the Java field name.@JsonIgnore: Excludes specific fields (e.g., passwords) from JSON conversion.@JsonFormat: Specifies the date format.@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdAt;
5. Injecting ObjectMapper in Spring Boot
Spring Boot already registers a pre-optimized ObjectMapper as a Bean. Rather than creating a new one with new, it is better to use it through Dependency Injection (DI).
@Service
@RequiredArgsConstructor
public class MyService {
private final ObjectMapper objectMapper; // Inject bean managed by Spring
public void process(String json) throws JsonProcessingException {
User user = objectMapper.readValue(json, User.class);
// ...
}
}
ObjectMapper is expensive to create but is Thread-safe. Performance is significantly better when you share a single instance or inject the Spring Bean instead of creating a new instance every time.