Issue
I am writing a controller with the annotation @RequestBody in order to map to a Java object. The method that uses the annotation is:
@PostMapping("/users")
public ResponseEntity<Object> createUserForProject(@Valid @RequestBody User user) {
log.info("Creating a user " + user.getEmail());
}
This is the User class:
@Getter
@AllArgsConstructor
@Slf4j
@EqualsAndHashCode
@ToString
public class User {
@NotEmpty
@Email
private String email;
@NotEmpty
private String firstName;
@NotEmpty
private String lastName;
@JsonIgnore
private Optional<LocalDate> lastLogonDate = Optional.empty();
@JsonIgnore
private Optional<LocalDate> lastModificationDate = Optional.empty();
@JsonIgnore
private Optional<LocalDate> creationDate = Optional.empty();
@JsonIgnore
private Optional<LocalDate> mfaWarningDate = Optional.empty();
@JsonIgnore
private Optional<LocalDate> auditStartNotificationDate = Optional.empty();
@JsonIgnore
private boolean enabled = true;
public User() {
log.info("HI");
}
(More code without explicit setters)
So when I make a POST call with the body
{
"email":"[email protected]",
"firstName":"testName",
"lastName":"testLastName"
}
Outputs HI and the log with the Creating a user [email protected] message, so the object is created. My point here is... why does this really work? The HttpMessageConverter is calling the no-args constructor and there are no setters to call after create the object with the constructor. How do the object attributes get their values without any setter? What am I missing here?
Solution
Spring boot uses Jackson for Object <-> JSON conversion, and Jackson does not need setters, it sets fields via reflection.
Here is a relevant question about Jackson and why it doesn't need setters How does jackson set private properties without setters?
Answered By - Igor Flakiewicz
Answer Checked By - David Marino (JavaFixing Volunteer)