Configuring ObjectMapper in Spring for @JsonProperty-Only Serialization

Nov 21, 2025 · Programming · 13 views · 7.8

Keywords: Spring | ObjectMapper | Jackson | JSON Serialization | @JsonProperty

Abstract: This article provides an in-depth exploration of configuring Jackson ObjectMapper in Spring framework to serialize only fields annotated with @JsonProperty. Through analysis of common configuration issues and integration with Spring Boot annotation-based configuration, it offers complete solutions and code examples. The discussion extends to visibility configuration, Spring integration essentials, and best practices for avoiding serialization pitfalls in real-world projects.

Introduction

In modern web application development, JSON serialization is an indispensable technical component. Jackson, as the most popular JSON processing library in the Java ecosystem, has its core component ObjectMapper whose configuration directly impacts serialization behavior. Many developers aim to configure it to serialize only fields with specific annotations, which is particularly important in data-sensitive scenarios.

Problem Analysis

From the user-provided case, it is evident that despite extending ObjectMapper and configuring visibility checkers to limit serialization scope, all fields are still serialized during runtime. This primarily stems from the following reasons:

First, Jackson's visibility configuration needs to work in tandem with annotation strategies. In the provided CompanyObjectMapper configuration, although various visibilities are set to NONE, if annotation detection is not explicitly enabled, the system may still process according to default rules.

Second, Spring version compatibility is also a critical factor. The user employs Spring 3.0.5 and Jackson 1.8.0, where configuration methods differ from newer versions. In older versions, additional configurations might be necessary to ensure custom ObjectMapper is correctly recognized and utilized.

Solution Approach

Based on the best answer guidance, we recommend using Spring Boot's annotation-based configuration, which is more concise and modern. Below is the complete configuration example:

@Configuration
public class JacksonConfiguration {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
        
        // Key configuration: Set visibility strategy
        mapper.setVisibility(
            mapper.getSerializationConfig().getDefaultVisibilityChecker()
                .withFieldVisibility(JsonAutoDetect.Visibility.NONE)
                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE)
        );
        
        // Enable annotation detection
        mapper.configure(MapperFeature.USE_ANNOTATIONS, true);
        
        return mapper;
    }
}

In this configuration, we not only replicate the basic setup from the best answer but also add crucial visibility settings and annotation enabling. By setting all visibilities to NONE and enabling annotation detection, the system will serialize only fields explicitly marked with @JsonProperty.

Entity Class Configuration

To align with the above configuration, entity classes must correctly use annotations:

public class NumbersOfNewEvents implements StatusAttribute {

    @JsonProperty("newAccepts")
    public Integer newAccepts;
    
    @JsonProperty("openRequests") 
    public Integer openRequests;
    
    // Non-annotated fields will not be serialized
    public String internalField;
    
    public NumbersOfNewEvents() {
        super();
    }
}

By adding @JsonProperty annotations to fields requiring serialization, we can precisely control which fields appear in the final JSON output. Non-annotated fields, such as internalField, will not be serialized.

Spring Integration Essentials

When integrating custom ObjectMapper in Spring MVC, note the following points:

For modern Spring Boot applications, the above @Configuration approach automatically registers the ObjectMapper Bean, and Spring will use it for all JSON serialization operations.

For traditional Spring XML configuration, refer to the user's servlet.xml setup, but ensure:

<bean id="jacksonObjectMapper" class="com.yourpackage.JacksonConfiguration" factory-method="objectMapper" />

This method creates ObjectMapper instances via factory method, ensuring correct application of configurations.

Advanced Configuration Options

Beyond basic visibility settings, ObjectMapper offers rich configuration options to meet various business needs:

Date Format Configuration: Addressing date serialization issues mentioned in the reference article can be done as follows:

mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// Or using Java 8 Time API
mapper.registerModule(new JavaTimeModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

Custom Serializers: For complex serialization requirements, register custom serializers:

SimpleModule module = new SimpleModule();
module.addSerializer(CustomClass.class, new CustomSerializer());
mapper.registerModule(module);

Performance Considerations

As noted in the reference article, when using custom ObjectMapper in workflow engines like Camunda, performance impacts must be considered. ObjectMapper creation and configuration are relatively expensive operations; it is advisable to:

1. Use singleton ObjectMapper instances

2. Complete all configurations at application startup

3. Avoid recreating ObjectMapper for each serialization

4. For high-concurrency scenarios, consider thread-safe versions of ObjectMapper or object pooling techniques

Testing Verification

To ensure correct configuration, write comprehensive unit tests:

@SpringBootTest
class ObjectMapperTest {

    @Autowired
    private ObjectMapper objectMapper;

    @Test
    void testJsonPropertyOnlySerialization() throws Exception {
        NumbersOfNewEvents event = new NumbersOfNewEvents();
        event.newAccepts = 10;
        event.openRequests = 5;
        event.internalField = "secret";

        String json = objectMapper.writeValueAsString(event);
        
        // Verify only annotated fields are serialized
        assertThat(json).contains("newAccepts");
        assertThat(json).contains("openRequests");
        assertThat(json).doesNotContain("internalField");
        assertThat(json).doesNotContain("secret");
    }
}

Compatibility Considerations

When dealing with different versions of Jackson and Spring, note API changes:

In Jackson 2.x, visibility configuration methods have evolved:

// Jackson 2.x approach
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.NONE);

For users on older Jackson 1.x versions, upgrading to 2.x is recommended for better performance and more features.

Best Practices Summary

Based on this article's analysis and practical experience, we summarize the following best practices:

1. Explicitly Configure Visibility Strategy: Do not rely on defaults; explicitly set all visibility rules

2. Enable Annotation Detection: Ensure USE_ANNOTATIONS feature is enabled

3. Unified Configuration Management: Use consistent ObjectMapper configuration across the application

4. Version Compatibility Checks: Regularly check and use the latest stable Jackson versions

5. Comprehensive Testing: Write thorough test cases for serialization configurations

By adhering to these practices, developers can effectively control JSON serialization behavior, ensuring data security and consistency while maintaining good application performance.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.