Search code examples
javaspring-bootserializationjacksonjson-deserialization

Jackson fails to serialize property


In my SpringBoot application, I have defined a Controller in the following way:

@RestController
@RequestMapping("/api/book")
@Slf4j
public class BookController {

    @PostMapping("/create")
    public ResponseEntity<String> createBook(@RequestBody BookCreationPayload payload) {

        log.info(payload.getName());
        log.info(payload.getAuthor());
        log.info(payload.getEBookReference());

        return ResponseEntity.ok().body("Created successfully!");
    }
}

The corresponding payload is defined like this:

@Data
public class BookCreationPayload {

    private String name;
    private String author;
    private String eBookReference;
}

When I hit the endpoint with the following requestbody, I get null for property eBookReference.

{
    "name":"Kafka on the Shore",
    "author": "Haruki Murakami",
    "eBookReference": "https://www.pdfdrive.com/kafka-on-the-shore-e191718472.html"
}

Now if I change the property name to electronicBookReference, it works just fine. I think Jackson fails to serialize it due to some naming convention issue but I don't exactly know what's happening.

This is my pom.xml.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>sandbox</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sandbox</name>
    <description>sandbox</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


Solution

  • As mentioned by @xerx593 in comments the problem is regarding naming convention & Getter Setter method generated by Lombok the solution if you don't want to use @JsonProperty @JsonCreator is to create Getter & Setter method manually as below.

    public String geteBookReference() {
        return eBookReference;
    }
    
    public void seteBookReference(String eBookReference) {
        this.eBookReference = eBookReference;
    }
    
    

    This works with above mentioned request payload you mentioned bcoz Jackson uses class getters and setters methods for serialization and deserialization. What follows "get", "is" and "set" in those methods will be used as the key for the JSON field.