[JAVA] Let's find out how to receive in Request Body with REST API of Spring Boot

environment

Java8 SpringBoot 2.1.9.RELEASE

Assumptions and sharing

--Policies to deserialize in Jackson but not use basic Setter --When deserializing in Jackson, Getter / Setter is unnecessary when the field visibility defined in the object is public, and it is necessary when it is protected or less, but this time it is a policy not to define it in public ――Aim to be immutable as much as possible

Sample code

String field definition only

Send JSON: {"id ":" 1 "," name ":" Name "}

/**
 *Write with Getter
 */
public class Sample {

    String id;
    String name;

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}
/**
 *Write in constructor
 */
public class Sample {

    String id;
    String name;

    public Sample(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

int field definition only

Send JSON: {"id ": 1," age ": 20}

/**
 *Write with Getter
 */
public class Sample {

    int id;
    int age;

    public int getId() {
        return id;
    }

    public int getAge() {
        return age;
    }
}
/**
 *Write in constructor
 */
public class Sample {

    int id;
    int age;

    public Sample(int id, int age) {
        this.id = id;
        this.age = age;
    }
}

By the way, if you use Integer type, you can tolerate null (anger) {"id": null, "age": 20}

public class Sample {

    Integer id;
    int age;

    public Sample(Integer id, int age) {
        this.id = id;
        this.age = age;
    }
}

Result: ʻIntSample {id = null, age = 20} `

boolean field definition only

__ Could not be implemented with Getter __ So only how to write in the constructor Send JSON: {"isHoge ": true," isFuga ": true}

/**
 *Write in constructor
 */
public class BooleanSample {

    boolean isHoge;
    boolean isFuga;

    public BooleanSample(boolean isHoge, boolean isFuga) {
        this.isHoge = isHoge;
        this.isFuga = isFuga;
    }
}

For Boolean type, it will be null if deserialization is not possible

String, int, boolean definition

I verified it as String, int, and boolean, but it seems that the constructor is required when boolean is mixed, so I can not consider how to write with Getter. Therefore, it seems that only the constructor can be defined.

I tried it with Getter Send JSON: {" name ":" Kiguri "," age ": 24," isPerson ": true}

/**
 *Write with Getter
 */
public class Sample {

    String name;
    int age;
    boolean isPerson;

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public boolean isPerson() {
        return isPerson;
    }
}

Result: Sample {name ='Kiguri', age = 24, isPerson = false} The value of boolean is not bound, which is a very disappointing result ...

/**
 *Write in constructor
 */
public class Sample {

    String name;
    int age;
    boolean isPerson;

    public Sample(String name, int age, boolean isPerson) {
        this.name = name;
        this.age = age;
        this.isPerson = isPerson;
    }
}

Result: SIBSample {name ='Kiguri', age = 24, isPerson = true} I'm smiling.

Where I think it's a trap (unsolved)

Did you notice that the sample code so far has prepared two field definitions in common? If there is only one field definition and it is deserialized by the constructor, it is different from the original usage, but if you do not use @JsonCreator and @JsonProperty, you will get an exception.

Exception pattern

Send JSON: {" name ":" Kiguri "}

public class Sample {

    String name;

    public Sample(String name) {
        this.name = name;
    }
}

Exception content

{
    "timestamp": "2019-10-11T03:25:50.724+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "JSON parse error: Cannot construct instance of `sandbox.Sample` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `sandbox.Sample` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)\n at [Source: (PushbackInputStream); line: 1, column: 2]",
    "path": "/s"
}

Success pattern

Send JSON: {" name ":" Kiguri "}

public class Sample {

    String name;

    @JsonCreator
    public Sample(@JsonProperty("name") String name) {
        this.name = name;
    }
}

Summary

I wonder if it will be a title scam that completely explained Jackson. Also, please tell me who is familiar with the trap part. You might be asked, "Isn't it okay to add @JsonProperty to the field without using a constructor? ", But I'll limit the instance creation method to one and add it to the constructor argument for ease of viewing. I will. Looking for a better way !! !!

Recommended Posts

Let's find out how to receive in Request Body with REST API of Spring Boot
How to read Body of Request multiple times with Spring Boot + Spring Security
[Beginner] Let's write REST API of Todo application with Spring Boot
How to use CommandLineRunner in Spring Batch of Spring Boot
Introduce swagger-ui to REST API implemented in Spring Boot
How to boot by environment with Spring Boot of Maven
Implement REST API in Spring Boot
How to realize huge file upload with Rest Template of Spring
[Spring Boot] I investigated how to implement post-processing of the received request.
How to bind request parameters in list format with bean property in Spring
How to use MyBatis2 (iBatis) with Spring Boot 1.4 (Spring 4)
How to use built-in h2db with spring boot
How to add a classpath in Spring Boot
How to bind to property file in Spring Boot
How to implement optimistic locking in REST API
How to set environment variables in the properties file of Spring boot application
Automatically map DTOs to entities with Spring Boot API
Hello World (REST API) with Apache Camel + Spring Boot 2
How to create a Spring Boot project in IntelliJ
Implement a simple Rest API with Spring Security with Spring Boot 2.0
Customize REST API error response with Spring Boot (Part 2)
Customize REST API error response with Spring Boot (Part 1)
Let's write how to make API with SpringBoot + Docker from 0
How to change application.properties settings at boot time in Spring boot
Implement REST API with Spring Boot and JPA (Application Layer)
Implement REST API with Spring Boot and JPA (Infrastructure layer)
How to use the same Mapper class in multiple data sources with Spring Boot + MyBatis
Let's make a simple API with EC2 + RDS + Spring boot ①
Create API to send and receive Json data in Spring
To receive an empty request with Spring Web MVC @RequestBody
Implement a simple Rest API with Spring Security & JWT with Spring Boot 2.0
How to control transactions in Spring Boot without using @Transactional
Implement a simple Web REST API server with Spring Boot + MySQL
[Sprint Boot] How to use 3 types of SqlParameterSource defined in org.springframework.jdbc.core.namedparam
How to create your own Controller corresponding to / error with Spring Boot
How to use Lombok in Spring
How to find May'n in XPath
Spring with Kotorin --4 REST API design
How to set Spring Boot + PostgreSQL
How to apply thymeleaf changes to the browser immediately with #Spring Boot + maven
I want to display images with REST Controller of Java and Spring!
Procedure to make the value of the property file visible in Spring Boot
How to execute with commands of normal development language in Docker development environment
Workaround for Command Line Runner to work with JUnit in Spring Boot
How to access Socket directly with the TCP function of Spring Integration
How to convert an array of Strings to an array of objects with the Stream API
How to find out the Java version of a compiled class file
How to find the total number of pages when paging in Java
How to insert processing with any number of elements in iterative processing in Ruby
Convert request parameter to Enum in Spring
How to include Spring Tool in Eclipse 4.6.3?
HTTPS with Spring Boot and Let's Encrypt
How to split Spring Boot message file
How to get the ID of a user authenticated with Firebase in Swift
[Laravel] How to deal with out of memory error when composer require [Docker]
03. I sent a request from Spring Boot to the zip code search API
How to check the latest version of io.spring.platform to describe in pom.xml of Spring (STS)
Organize the differences in behavior of @NotBlank, @NotEmpty, @NotNull with Spring Boot + Thymeleaf
[Spring Boot] How to get properties dynamically from a string contained in a URL
How to perform UT with Excel as test data with Spring Boot + JUnit5 + DBUnit
I tried to clone a web application full of bugs with Spring Boot