day0ops
day0ops

Reputation: 7482

Validate nested object in Jackson

Ive got a spring project and using jackson for json serialization and deserialization.

And I have these DTOs defined,

CertManDTO,

public class CertManDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private UUID certificateId;

    @NotNull
    private Long orgId;

    @NotNull
    private CertificateType certificateType;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    @NotNull
    private PublicCertificateDTO publicCertificate;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private PrivateCertificateDTO privateCertificate;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private ZonedDateTime expiryDate;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private ZonedDateTime createdDate;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private ZonedDateTime updatedDate;

    // Getters and setters
}

PublicCertificateDTO,

public class PublicCertificateDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    @JsonIgnore
    private Long id;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    @NotNull
    private String certificate;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    @NotNull
    private String dnsZone;

    // Getters and setters
}

PrivateCertificateDTO,

public class PrivateCertificateDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    @JsonIgnore
    private Long id;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String pkcs12;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String privateCertificatePassword;

    // Getters and setters
}

You can see above that I have set I have @NotNull annotation set for the fields certificate & dnzZone.

However posting this JSON seems to parse successfully. This only happens on nested objects.

{  
   "orgId":"1001",
   "certificateType":"Single Use",
   "privateCertificate":{  
      "pkcs12":"test",
      "certificatePassword":"Test"
   },
   "publicCertificate":{  

   }
}

If I post the following it will fail the validation as @NotNull is set for publicCertificate

{  
   "orgId":"1001",
   "certificateType":"Single Use",
   "privateCertificate":{  
      "pkcs12":"test",
      "certificatePassword":"Test"
   }
}

I do have @Valid set for the @RequestBody in the RestController.

Any idea what could be causing this ??

Upvotes: 0

Views: 5522

Answers (2)

Mike Wojtyna
Mike Wojtyna

Reputation: 771

It seems you forgot to add @Valid annotation to your nested DTOs. Try the following code:

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@NotNull
@Valid
private PublicCertificateDTO publicCertificate;

Upvotes: 7

day0ops
day0ops

Reputation: 7482

As soon as I posted the question I came across this blog post about bean validation. You need to @Valid to validate the nested objects.

Hence refactored CertManDTO as,

public class CertManDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private UUID certificateId;

    @NotNull
    private Long orgId;

    @NotNull
    private CertificateType certificateType;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    @NotNull
    @Valid
    private PublicCertificateDTO publicCertificate;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private PrivateCertificateDTO privateCertificate;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private ZonedDateTime expiryDate;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private ZonedDateTime createdDate;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private ZonedDateTime updatedDate;

    // Getters and setters
}

Upvotes: 0

Related Questions