JSON Serialization vs Deserialization
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
Serialization converts an in-memory Java value into JSON text or bytes. Deserialization moves in the opposite direction: it reads JSON and builds a value of the Java type the application requested. A REST response normally uses serialization, while a JSON request body normally uses deserialization. The same mapping library can perform both jobs, but each direction has different checks and risks.
For output, a call such as mapper.writeValueAsString(orderResponse) writes the properties visible on the response object. The response DTO should contain only the public fields the client needs. Serializing a persistence entity directly can expose an internal field, follow a cyclic relationship, or trigger a lazy database load, so the outgoing shape should be chosen rather than discovered by accident.
For input, mapper.readValue(json, CreateOrderRequest.class) asks Jackson to parse the JSON and build that target type. Invalid JSON or a value that cannot fit the declared type can fail during this step. A successful result only means mapping worked; @Valid constraints and service rules must still decide whether the request is allowed.
Consider POST /orders. The request JSON is deserialized into CreateOrderRequest, which may contain productId and quantity. After validation and service work, an OrderResponse is serialized with the new order ID, status, and total. The input and output do not need the same fields because they represent different moments and different permissions in the use case.
A JSON round trip is not always lossless. A password may be accepted but never returned, an ID may be generated by the server, and dates or numbers may use a public wire format different from the Java representation. Contract tests should therefore check request and response mapping separately, including missing values, unknown fields, boundaries, and sensitive-field absence.
JSON Serialization vs Deserialization
Direct Answer
Serialization is the process of turning a Java value into JSON text or bytes. Deserialization is the opposite process: it reads JSON and builds a value of a declared Java type. In a REST API, serialization controls the response that leaves the service, while deserialization handles request data entering it; successful mapping still does not replace validation.
Deep Dive & Architecture
Serialization begins with a Java object graph, but the API should publish a deliberate representation rather than every reachable object. Bidirectional entity relationships can recurse, lazy associations can trigger unexpected queries, and broad visibility can expose data. A response DTO makes the outgoing shape finite and reviewable.
Deserialization begins with untrusted bytes. A parser checks JSON syntax, the mapper applies target-type rules, Bean Validation checks structural constraints, and the service enforces domain rules. These are separate stages. A syntactically valid request can still have an unknown product, insufficient stock, or an invalid state transition.
Round-tripping is not always lossless. A write-only request field may not appear in a response. Server-generated IDs and timestamps appear only after processing. Numbers or dates may use representations chosen for cross-language safety. The contract should describe each direction instead of promising that any serialized object can be deserialized into an equivalent entity.
Mapping tests catch accidental contract drift. Test representative output fields, missing and null input, unknown members according to policy, boundary numbers, and time-zone behavior. Tests should assert the public JSON rather than Jackson's incidental property discovery on a persistence model.
Code Example
import com.fasterxml.jackson.databind.ObjectMapper;
final class JsonDirectionExample {
record CreateOrderRequest(String productId, int quantity) {}
record OrderResponse(long id, String productId, String status) {}
static String handle(String input) throws Exception {
ObjectMapper mapper = new ObjectMapper();
CreateOrderRequest request = mapper.readValue(
input, CreateOrderRequest.class); // deserialization
OrderResponse response =
new OrderResponse(42, request.productId(), "created");
return mapper.writeValueAsString(response); // serialization
}
}
The request carries client input such as productId and quantity. The response has a server-generated ID and status, so it uses a different shape. Validation still belongs between the two mapping steps.
Check your understanding
Answer these without looking back at the article.
- Why can serialization of JPA entities trigger unexpected database queries?
- Does valid JSON guarantee a valid domain command?
- When is a custom Jackson serializer appropriate?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.