0

So I have been playing around with Spring building a full stack application and I am at the point where I am validating data. First off, I want to validate that the incoming post request to my Spring Controller is able to create a User object and add it to the database. I created a custom validator using the combinator pattern and Java 8 features to do this.

Question 1 is there a way to intercept one of the JSON fields in post method? It is coming back as a String but I need a localdate to satisfy the user object creation/validation.

Question 2 when is it preferred to use validation annotations in the POJO object vs validating when the request comes through the controller? Should you be using both? Are there preferred patterns for validation? Obviosuly the client side will be validated as well before the info reaches the server.

//Using my custom validation here
@PostMapping
    public ResponseEntity addUser(@RequestBody User user) {

        UserValidation.ValidationResult result = userValidationService.validate(user);

        if (result.equals(UserValidation.ValidationResult.SUCCESS)){
            logger.info("Added a new user.");
            userService.addUser(user);

            return ResponseEntity.ok(HttpStatus.OK);
        }

        logger.info("Could not add new user.");
        return new ResponseEntity(HttpStatus.BAD_REQUEST);
    }

//Using annotation validation here on the POJO
@Data
@Table
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NotNull
    @Length(max = 6)
    private String firstName;
    @NotNull
    private String lastName;
    private String username;
    @Email
    private String email;
    private LocalDate birthDate;
    private String password;

    public User() {

    }

    public User(String firstName, String lastName, String username, String email, String password,
                LocalDate birthDate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.username = username;
        this.email = email;
        this.password = password;
        this.birthDate = birthDate;
    }
}

1 Answers1

0

You can create a DTO object for Entity and do all validation there.

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class UserDto {

    @NotNull
    @Length(max = 6)
    private String firstName;
    @NotNull
    private String lastName;
    private String username;
    @Email
    private String email;
    private LocalDate birthDate;
    private String password;
}

Then put this object in Controller:

    @PostMapping
    public ResponseEntity addUser(@Valid @RequestBody UserDto userDto) { // @Valid will check if validation is ok in object UserDto 
        UserValidation.ValidationResult result = userValidationService.validate(userDto);

        if (result.equals(UserValidation.ValidationResult.SUCCESS)){
            logger.info("Added a new user.");
            userService.addUser(toEntity(userDto)); //maps UserDto to User Entity

            return ResponseEntity.ok(HttpStatus.OK);
        }

        logger.info("Could not add new user.");
        return new ResponseEntity(HttpStatus.BAD_REQUEST);
    }

    // maps UserDto to User so you can save it to database in Service layer
    User toEntity(UserDto userDto) {
        User user = new User();
        user.setFirstName(userDto.getFirstName);
        user.setLastName(userDto.getUserlastName);
        user.setUsername(userDto.getUsername);
        user.setEmail(userDto.getEmail);
        user.setPassword(userDto.getPassword);
        user.setBirthDate(userDto.birthDate)
        return user;
    }



acakojic
  • 306
  • 2
  • 11
  • Thanks for this answer and introducing Dto to me. So with using this method is there even a need for the custom validator that I created if we are instead using the annotations? – thottivelli Jun 14 '22 at 20:41
  • 1
    You can use it separately and you can use both. If validation that framework offers don't suit you then create custom validation. You can mix it. Check creating custom annotation: https://stackoverflow.com/questions/56381693/spring-dto-validation-using-constraintvalidator – acakojic Jun 14 '22 at 21:22