I'm planning to use Lombok for creating hundreds of classes that are based on "value object" pattern as follows:
@Data
public final class SomeId implements Serializable {
private final long value;
}
And I want to use these classes for JSON serialization powered by Jackson. for example, consider a DTO class as follows:
public class SomeDTO {
SomeId id;
public SomeId getId() {
return id;
}
}
I want that DTO class to be serialized as something like {"id":123}
, but Jackson produces something like {"id":{"value":123}}
, which comes with unnecessary nested object with a field named value
. i.e. a testcase expresses my requirement:
public class SomeDTOTest {
@Test
public void serializationTest() throws Exception {
SomeDTO dto = new SomeDTO();
dto.id = new SomeId(123);
String serialized = new ObjectMapper().writeValueAsString(dto);
System.out.println(serialized); // {"id":{"value":123}}
assertThat(serialized, is("{\"id\":123}")); // I want {"id":123} instead!
}
}
I know putting @JsonValue
annotation to every getValue()
method in SomeId
classes would be a solution, but I can't do it because there is no actual definition of @Data
classes because Lombok automatically creates it.
Creating actual getValue()
method annotated as @JsonValue
for every classes by hand might be another solution but it means creating tons of boilarplate code.
How do I achieve this requirement without boilerplate code?
I created an interface which has getValue()
which annotated as @JsonValue
:
public interface LongValue {
@JsonValue
long getValue();
}
Then implemented it in every @Data
classes. note that actual implementation of getValue()
will be automatically generated by Lombok:
@Data
public final class SomeId implements LongValue, Serializable {
private final long value;
}
With that I've got the test SomeDTOTest
passed - SomeDTO
is serialized to {"id":123}
as I expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With