Spring Boot 3 Java record RequestBody camel case not filled properly

3 min read 20-09-2024
Spring Boot 3 Java record RequestBody camel case not filled properly


When working with Spring Boot 3, one common issue that developers face is the improper binding of JSON request bodies to Java record classes when using camel case. This article will explore this problem in detail, providing a solution and additional insights for better understanding.

Problem Scenario

Let’s say you have a simple Java record defined to hold user information, and you want to map JSON request bodies to this record using Spring Boot. The original code may look something like this:

import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;

@RestController
@RequestMapping("/api/users")
public class UserController {

    @PostMapping
    public ResponseEntity<String> createUser(@RequestBody UserRecord user) {
        // Logic to handle user creation
        return ResponseEntity.ok("User created: " + user);
    }
}

public record UserRecord(String firstName, String lastName) {}

When you send a JSON request body like this:

{
    "first_name": "John",
    "last_name": "Doe"
}

You might find that the firstName and lastName fields in your UserRecord are not being populated correctly due to the difference in naming conventions. This is because Spring Boot expects camel case by default while the incoming JSON uses snake case.

Analyzing the Issue

The main problem lies in how Spring’s ObjectMapper (part of the Jackson library) deserializes the JSON request. The default behavior does not automatically convert snake case to camel case, leading to null values in the UserRecord fields.

Solution: Customizing Serialization

To overcome this issue, you can customize the ObjectMapper to allow for snake case. Here's how you can do this in your Spring Boot application:

  1. Create a configuration class:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        return objectMapper;
    }
}

By setting the PropertyNamingStrategy to SNAKE_CASE, Jackson will automatically convert the snake case properties in your JSON to camel case when mapping to the Java record.

Testing the Solution

Now, if you send the same JSON request body:

{
    "first_name": "John",
    "last_name": "Doe"
}

You should see the values filled correctly in your UserRecord:

UserRecord(userRecord[firstName=John, lastName=Doe])

Practical Example

Here is a complete example of the updated code with the Jackson configuration:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {

    @PostMapping
    public ResponseEntity<String> createUser(@RequestBody UserRecord user) {
        return ResponseEntity.ok("User created: " + user);
    }
}

public record UserRecord(String firstName, String lastName) {}

@Configuration
public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        return objectMapper;
    }
}

With these changes, your Spring Boot application will now effectively handle JSON inputs with snake case keys.

Conclusion

Handling different naming conventions can sometimes pose challenges in Spring Boot applications. However, with a simple configuration of the ObjectMapper, developers can easily manage such cases.

Additional Resources

By taking these steps, developers can ensure seamless data binding and enhance their application’s robustness.


This article should provide clarity on the problem and equip you with the necessary tools to tackle camel case issues with Java records in Spring Boot 3 effectively. Happy coding!