Issue
I use Jackson for serialization/deserialization with my Spring Boot project.
I have a DTO object with the following structure,
public class TestDTO 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)
@Valid
@NotNull
private PublicCertificateDTO publicCertificate;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@Valid
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;
}
Serialization of this object in my unit tests with the following method,
public static byte[] convertObjectToJsonBytes(TestDTO object)
throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
JavaTimeModule module = new JavaTimeModule();
mapper.registerModule(module);
return mapper.writeValueAsBytes(object);
}
causes fields with WRITE_ONLY
access to get ignored (for obvious reasons). So in the serialized object I see null values for publicCertificate
and privateCertificate
.
I did try setting mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
Is there any other way to ignore these properties for Unit Tests ?
Solution
While the solution specified works, it is an overkill for the requirement. You don't need custom serializers if all you want is to override annotations. Jackson has a mixin feature for such trivial requirements
Consider the following simplified POJO:
public class TestDTO
{
public String regularAccessProperty;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
public String writeAccessProperty;
}
If you want to override the @JsonProperty
annotation, you create another POJO that has a variable with the exact same name (or same getter/setter names):
// mixin class that overrides json access annotation
public class UnitTestDTO
{
@JsonProperty(access = JsonProperty.Access.READ_WRITE)
public String writeAccessProperty;
}
You associate the original POJO and the mixin via a Simplemodule:
simpleModule.setMixInAnnotation(TestDTO.class, UnitTestDTO.class);
Answered By - Sharon Ben Asher
Answer Checked By - Marilyn (JavaFixing Volunteer)