Immutable Lombok annotated class with Jackson

▼魔方 西西 提交于 2019-12-04 00:59:17

Another alternative which:

is to add ConstructorProperties:

  • Create a lombok.config file in an appropriate location with the line: lombok.anyConstructor.addConstructorProperties = true
  • Add lombok @Value annotation to your class to make it immutable

Then serialization and deserialization by Jackson works as expected.

You can use Lombok's @Builder annotation to generate a builder for your immutable POJO class. But making the Lombok-generated builder usable by Jackson's deserialization is somewhat tricky.

Example:

An immutable POJO class:

@Data
@Builder(builderClassName = "PointBuilder")
@JsonDeserialize(builder = Point.PointBuilder.class)
public class Point {

    private final int x;

    private final int y;

    @JsonPOJOBuilder(withPrefix = "")
    public static class PointBuilder {
        // Lombok will add constructor, setters, build method
    }
}

Here is a JUnit test to verify the serialization/deserialization:

public class PointTest extends Assert {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Test
    public void testSerialize() throws IOException {
        Point point = new Point(10, 20);
        String json = objectMapper.writeValueAsString(point);
        assertEquals("{\"x\":10,\"y\":20}", json);
    }

    @Test
    public void testDeserialize() throws IOException {
        String json = "{\"x\":10,\"y\":20}";
        Point point = objectMapper.readValue(json, Point.class);
        assertEquals(new Point(10, 20), point);
    }
}

Another alternative that is much less verbose:

@Data
@Setter(AccessLevel.NONE)
public class Clazz {
    private String field;
} 

Of course, you could still have some private method that modifies the field directly, but it would be very unlikely to even have any actual code in a @Data POJO, so this would hopefully not happen.

Disclaimer: This will have the side-effect (perhaps beneficial) of not letting regular Java code create the object since there is only a default constructor with no mutators. To allow for normal construction you will need 2 more annotations:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Setter(AccessLevel.NONE)
public class Clazz {
    private String field;
} 

By referencing answer by Joseph K. Strauss I came up with following solution.

Plain lombok annotations that worked out for me looks like this. Following annotations give you immutable classes with builder that can be serialized and deserialized by Jackson.

    @Data
    @Setter(AccessLevel.NONE)
    @Builder(toBuilder = true)
    @AllArgsConstructor
    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public class Clazz {
        private String field;
    } 

I prefer this solution because it requires no additional Jackson specific annotations and no additional lombok specific files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!