For Spring Boot applications, configure Jackson settings in application.yml:
spring:
# jackson configuration
jackson:
# date format
date-format: yyyy-MM-dd HH:mm:ss
# timezone
time-zone: GMT+8
# serialization settings
serialization:
# pretty print output
indent-output: false
# ignore unconvertible objects
fail-on-empty-beans: false
# deserialization settings
deserialization:
# allow objects to ignore properties not present in JSON
fail-on-ignored-properties: false
# set how nulls are serialized
default-property-inclusion: non_null
# parser settings
parser:
# allow special characters and escape sequences
allow-unquoted-control-chars: true
# allow single quotes
allow-single-quotes: true
Alternatively, configure using properties:
# date formatting
spring.jackson.date-format = yyyy-MM-dd HH:mm:ss
# timezone
spring.jackson.time-zone = GMT+8
# serialization settings
# pretty print output
spring.jackson.serialization.indent-output = false
# ignore unconvertible objects
spring.jackson.serialization.fail-on-empty-beans = false
# deserialization settings
# allow objects to ignore properties not present in JSON
spring.jackson.deserialization.fail-on-ignored-properties = false
# set how nulls are serialized
spring.jackson.default-property-inclusion = non_null
# allow special characters and escape sequences
spring.jackson.parser.allow-unquoted-control-chars = true
# allow single quotes
spring.jackson.parser.allow-single-quotes = true
Java utility class for ObjectMapper configuration:
static JsonMapper objectMapper = JsonMapper.builder().build();
static {
// don't fail if JSON contains properties not in the POJO
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
objectMapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL);
}
Serialization and Deserialization with Matching Field Names
When JSON field names match Java object field names:
package com.example.json.model;
import com.fasterxml.jackson.databind.ObjectMapper;
public class AuthToken {
private String tokenValue;
private long expirationTime;
public String getTokenValue() {
return tokenValue;
}
public void setTokenValue(String tokenValue) {
this.tokenValue = tokenValue;
}
public long getExpirationTime() {
return expirationTime;
}
public void setExpirationTime(long expirationTime) {
this.expirationTime = expirationTime;
}
@Override
public String toString() {
return "AuthToken [tokenValue=" + tokenValue + ", expirationTime=" + expirationTime + "]";
}
public static void main(String[] args) {
AuthToken token = new AuthToken();
token.setTokenValue("2r5fx9eiyapFxEGgHq");
token.setExpirationTime(7200);
try {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(token); // serialization
System.out.println(json);
AuthToken object = mapper.readValue(json, AuthToken.class); // deserialization
System.out.println(object);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output:
{"tokenValue":"2r5fx9eiyapFxEGgHq","expirationTime":7200}
AuthToken [tokenValue=2r5fx9eiyapFxEGgHq, expirationTime=7200]
Serialization and Deserialization with Different Field Names
When JSON field names differ from Java object field names, use @JsonProperty annotation:
package com.example.json.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
public class AuthToken {
private String tokenValue;
private long expirationTime;
@JsonProperty(value="access_token")
public String getTokenValue() {
return tokenValue;
}
@JsonProperty(value="access_token")
public void setTokenValue(String tokenValue) {
this.tokenValue = tokenValue;
}
@JsonProperty(value="expires_in")
public long getExpirationTime() {
return expirationTime;
}
@JsonProperty(value="expires_in")
public void setExpirationTime(long expirationTime) {
this.expirationTime = expirationTime;
}
@Override
public String toString() {
return "AuthToken [tokenValue=" + tokenValue + ", expirationTime=" + expirationTime + "]";
}
public static void main(String[] args) {
AuthToken token = new AuthToken();
token.setTokenValue("2r5fx9eiyapFxEGgHq");
token.setExpirationTime(7200);
try {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(token); // serialization
System.out.println(json);
AuthToken object = mapper.readValue(json, AuthToken.class); // deserialization
System.out.println(object);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output:
{"access_token":"2r5fx9eiyapFxEGgHq","expires_in":7200}
AuthToken [tokenValue=2r5fx9eiyapFxEGgHq, expirationTime=7200]
The @JsonProperty annotation applied to getter methods serializes properties with specified names, and when applied to setter methods, deserializes specified names to properties.
Deserializing List Objects
To deserialize JSON arrays into List objects:
public static void main(String[] args) {
try {
List<imagecontent> imageList = new ArrayList<>();
ImageContent content = new ImageContent();
content.setId(1);
content.setOrgId(100);
content.setTitle("google");
content.setImagePath("/upload/images/1.jpg");
content.setLinkUrl("http://www.google.com");
content.setStatus("modify");
imageList.add(content);
content = new ImageContent();
content.setId(2);
content.setOrgId(200);
content.setTitle("intel");
content.setImagePath("/upload/images/2.jpg");
content.setLinkUrl("http://www.intel.com");
content.setStatus("delete");
imageList.add(content);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(imageList);
System.out.println(json);
// Method 1: Using JavaType
JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, ImageContent.class);
List<imagecontent> newList = mapper.readValue(json, javaType);
// Method 2: Using TypeReference
List<imagecontent> newList2 = mapper.readValue(json, new TypeReference<list>>(){});
System.out.println(newList);
} catch (Exception e) {
e.printStackTrace();
}
}
</list></imagecontent></imagecontent></imagecontent>
Use the public T readValue(String content, JavaType valueType) method with JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, ImageContent.class) to specify collection type and generic type.
Handling Unrecognized Fields
When JSON contains fields not present in the Java object:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// or
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
Alternatively, add the @JsonIgnoreProperties annotation to the class:
@JsonIgnoreProperties(ignoreUnknown=true)
public class MyDataModel {
// class fields
}
The @JsonIgnore annotation can be used on fields or getter methods to ignore specific fields during serialization/deserialization. When applied to setter methods, it has the same effect as when applied to fields. This annotation is useful when you want to ignore fields that exist in the POJO.
The @JsonIgnoreProperties annotation can specify which fields to ignore:
@JsonIgnoreProperties({ "internalId", "secretKey" })
public class MyDataModel {
// class fields
}
Custom Serialization Filter - Regular Objects
Define a test POJO:
package com.example.json.model;
/**
* Test POJO
*/
public class UserProfile {
private String fullName;
private String mailingAddress;
private int age;
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getMailingAddress() {
return mailingAddress;
}
public void setMailingAddress(String mailingAddress) {
this.mailingAddress = mailingAddress;
}
}
Define a filter interface:
package com.example.json.filter;
import com.fasterxml.jackson.annotation.JsonFilter;
@JsonFilter("UserProfileFilter")
public interface UserProfileFilter {
}
Implement the filter:
package com.example.json.filter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.example.json.model.UserProfile;
public class SerializationFilterDemo {
public static void main(String[] args) throws JsonProcessingException {
UserProfile profile = new UserProfile();
profile.setFullName("John Doe");
profile.setMailingAddress("123 Main St, Anytown");
profile.setAge(30);
// Method 1: Define filter
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.serializeAllExcept("age");
// Method 2: Override SimpleBeanPropertyFilter's serializeAsField method
SimpleBeanPropertyFilter customFilter = new SimpleBeanPropertyFilter() {
@Override
public void serializeAsField(Object pojo, JsonGenerator jgen,
SerializerProvider provider, PropertyWriter writer) throws Exception {
if (!writer.getName().equals("age")) {
writer.serializeAsField(pojo, jgen, provider);
}
}
};
// Define provider
FilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("UserProfileFilter", filter); // or use customFilter
// Data binding
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(UserProfile.class, UserProfileFilter.class);
mapper.setFilterProvider(filterProvider);
String json = mapper.writeValueAsString(profile);
System.out.println(json);
}
}
Output:
{"fullName":"John Doe","mailingAddress":"123 Main St, Anytown"}
The mapper.addMixIn(UserProfile.class, UserProfileFilter.class) is crucial. The addMixIn method signature is:
public ObjectMapper addMixIn(Class> target, Class> mixinSource);
This method uses annotations from the mixinSource interface or class to override annotations in the target or its subtypes.
Custom Serialization Filter - List Object Fields
Test POJOs:
package com.example.json.model;
import java.util.List;
public class NewsArticleCollection {
/**
* Articles
*/
private List<newsarticle> articles;
public List<newsarticle> getArticles() {
return articles;
}
public void setArticles(List<newsarticle> articles) {
this.articles = articles;
}
}
package com.example.json.model;
public class NewsArticle {
/**
* Title
*/
private String title;
/**
* Cover image media ID (must be permanent media ID)
*/
private String coverMediaId;
/**
* Author
* [Optional]
*/
private String author;
/**
* Article summary, only available for single articles, empty for multiple articles.
* If not provided, defaults to first 64 characters of content.
* [Optional]
*/
private String summary;
/**
* Whether to show cover image, 0 for false, 1 for true
*/
private boolean showCoverImage;
/**
* Article content, supports HTML tags, must be less than 20,000 characters and 1MB.
* JavaScript will be removed. Image URLs must come from "Upload image in article" interface.
* External image URLs will be filtered.
*/
private String content;
/**
* Original URL of the article, the URL after clicking "Read more"
*/
private String sourceUrl;
// Getters and setters
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCoverMediaId() {
return coverMediaId;
}
public void setCoverMediaId(String coverMediaId) {
this.coverMediaId = coverMediaId;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public boolean getShowCoverImage() {
return showCoverImage;
}
public void setShowCoverImage(boolean showCoverImage) {
this.showCoverImage = showCoverImage;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getSourceUrl() {
return sourceUrl;
}
public void setSourceUrl(String sourceUrl) {
this.sourceUrl = sourceUrl;
}
}
</newsarticle></newsarticle></newsarticle>
Filter non-required fields (author, summary) in NewsArticle:
package com.example.json.filter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.example.json.model.NewsArticle;
import com.example.json.model.NewsArticleCollection;
public class NewsSerializationDemo {
public static void main(String[] args) throws JsonProcessingException {
NewsArticle article = new NewsArticle();
article.setTitle("Sample Title");
article.setCoverMediaId("sample_media_id");
article.setShowCoverImage(true);
article.setContent("Article content here");
article.setSourceUrl("https://example.com");
article.setAuthor("John Doe");
article.setSummary("This is a summary of the article");
List<newsarticle> articles = new ArrayList<>();
articles.add(article);
NewsArticleCollection newsCollection = new NewsArticleCollection();
newsCollection.setArticles(articles);
String json = JsonFilterUtil.toJson(NewsArticle.class, newsCollection, new String[]{"author", "summary"});
System.out.println(json);
}
}
</newsarticle>
Utility class for JSON filtering:
/**
* Serialization with custom filter
* @param clazz Class of objects in the list
* @param value Object to serialize
* @param filterFields Fields to exclude
* @return JSON string
*/
public static String toJson(Class> clazz, Object value, String[] filterFields) {
try {
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.serializeAllExcept(filterFields);
FilterProvider filterProvider = new SimpleFilterProvider().addFilter("UserProfileFilter", filter);
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(clazz, UserProfileFilter.class);
mapper.setFilterProvider(filterProvider);
return mapper.writeValueAsString(value);
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
Important: The class in addMixIn should be the class of objects in the list.
Excluding NULL, DEFAULT, EMPTY Values from Serialization
Method 1: Using @JsonInclude annotation
- Applied to properties: affects only that property
- Applied to classes: affects all properties of the class including inherited ones
@JsonInclude(Include.NON_NULL) // don't serialize null properties
Method 2: Using code
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
Available values:
- Include.ALWAYS (default) - serialize all properties
- Include.NON_DEFAULT - don't serialize properties with default values
- Include.NON_EMPTY - don't serialize empty or null properties
- Include.NON_NULL - don't serialize null properties
Property Naming Strategies
Different naming strategies for JSON properties:
Organization org = new Organization();
org.setName("apple");
org.setPostalCode("100000");
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
try {
String json = mapper.writeValueAsString(org); // serialization
System.out.println(json);
Organization organization = mapper.readValue(json, Organization.class); // deserialization
System.out.println(organization.toString());
} catch (Exception e) {
e.printStackTrace();
}
PropertyNamingStrategy constants:
Serialization Inclusion Settings
Control which property are included in serialization:
Organization org = new Organization();
org.setName("");
org.setPostalCode(null);
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
try {
String json = mapper.writeValueAsString(org); // serialization
System.out.println(json);
Organization organization = mapper.readValue(json, Organization.class); // deserialization
System.out.println(organization.toString());
} catch (Exception e) {
e.printStackTrace();
}
JsonInclude.Include options:
Date Formatting
Format dates during serialization/deserialization:
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
@TableField("timestamp_")
private String timestamp;