programing

잭슨과의 불변의 롬복 주석 클래스

topblog 2023. 3. 9. 21:44
반응형

잭슨과의 불변의 롬복 주석 클래스

다음과 같은 클래스를 만드는 데 권장되는 방법은 무엇입니까?

  • 불변의
  • 잭슨과 시리얼화/디시리얼화 가능
  • 사람이 읽을 수 있고 보일러 플레이트 레벨이 낮습니다.

저는 다음과 같은 작업을 수행했으면 합니다.

@Data(onConstructor = @__(@JsonCreator))

그리고 모든 필드가private final하지만 컴파일도 되지 않습니다(그 이유는 잘 모르겠습니다).사용.

@AllArgsConstructor(onConstructor = @__(@JsonCreator))

컴파일되지만 산출량만 표시됩니다.

InvalidDefinitionException: No serializer found for class

add Constructor Properties:

  • 작성하다lombok.config다음 행이 있는 적절한 위치에 파일을 작성합니다.lombok.anyConstructor.addConstructorProperties = true
  • 롬복 추가@Value그것을 불변으로 만들기 위해 당신의 클래스에 대한 주석

그러면 잭슨의 직렬화와 직렬화가 예상대로 작동합니다.

이 방법은 다음과 같습니다.

편집: 2020-08-16

  • 주의: 사용방법@Builder와 함께@Value이 솔루션이 실패하는 원인이 됩니다.(아래의 @guilherme-blanco 코멘트 덕분입니다.)단, 예를 들어 를 추가하는 경우. @AllArgsConstructor아직 예상대로 작동합니다.

편집: 2021-08-19

  • 주의: 를 추가 또는 변경할 때lombok.config파일 변경은 재구축(클린 후 빌드)을 수행하지 않으면 선택되지 않습니다.나는 이것에 몇 번 들킨 적이 있다.
  • @Jacksonized 주석 솔루션은 주석이 달린 특정 클래스에 대해 원하는 결과를 얻기 위한 또 다른 방법입니다.그러나 개인적으로는 역직렬화에 사용되는 모든 클래스에 주석을 다는 것을 기억할 필요가 없습니다.사용.lombok.config이 오버헤드를 삭제합니다.

2020년 10월 15일(Lombok v1.18.16)부터는 단순히 주석을 사용할 수 있어야 합니다.

@Jacksonized @Builder
@JsonIgnoreProperties(ignoreUnknown = true)
public class JacksonExample {
  private List<Foo> foos;
}

링크된 설명서에서 설명한 바와 같이 이 주석은 다음과 같습니다.

  • 디시리얼라이제이션에 빌더를 사용하도록 잭슨을 설정합니다.
  • 는 필드 고유의 설정을 주석이 달린 클래스에서 생성된 빌더로 복사합니다(예:@JsonIgnoreProperties, 및
  • 는 빌더 메서드에서 사용되는 잭슨 접두사를 정렬합니다(예:builder().withField(field)builder.field(field)Lombok에서 설정된 것으로 이동합니다.

Lombok의 주석을 사용하여 불변의 POJO 클래스에 대한 빌더를 생성할 수 있습니다.그러나 잭슨의 탈직렬화에 의해 롬복에서 생성된 건축가를 사용할 수 있게 만드는 것은 다소 까다롭다.

  • 잭슨에게 사용할 빌더 클래스를 알려주려면 에서 POJO 클래스에 주석을 달아야 합니다.
  • Jackson에게 setter-method가 다음과 같이 시작되지 않음을 알려주려면 빌드 클래스에 주석을 달아야 합니다.with.

예:

불변의 POJO 클래스:

@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
    }
}

POJO의 개요

시리얼화/디시리얼화를 검증하기 위한 JUnit 테스트를 다음에 나타냅니다.

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);
    }
}

Joseph K의 답변을 참조합니다. 스트라우스 1세는 다음과 같은 해결책을 생각해냈다.

저에게 효과가 있었던 평범한 롬복 주석들은 이렇게 생겼습니다.다음 주석은 Jackson에 의해 직렬화 및 직렬화 해제될 수 있는 빌더와 함께 불변의 클래스를 제공합니다.

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

잭슨 고유의 주석이나 롬복 고유의 파일이 추가로 필요하지 않기 때문에 이 솔루션을 선호합니다.

훨씬 덜 장황한 또 다른 대안:

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

물론 필드를 직접 수정하는 개인 메서드가 있을 수 있지만 @Data POJO에 실제 코드가 있을 가능성은 매우 낮기 때문에 이러한 일이 발생하지 않기를 바랍니다.

면책사항:이는 변환자가 없는 기본 생성자만 존재하기 때문에 일반 Java 코드가 개체를 생성하지 못하게 하는 부작용이 있을 수 있습니다.일반 구성을 허용하려면 두 개의 주석이 더 필요합니다.

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

pojo에 대해 다음 주석 세트를 사용해 보십시오.

@Value
@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE)
@AllArgsConstructor

방금 다음과 같은 방법으로 문제를 해결했습니다.

@Value
@Builder(setterPrefix = "with")
@JsonDeserialize(builder = Clazz.ClazzBuilder.class)
public class Clazz {
    private String field;
}

때는 요.withField(...)이것은 잭슨이 사용하는 기본 동작입니다.

잭슨용으로 불변 클래스를 설정하는 가장 간단한 방법은 lombok 주석을 사용하는 것입니다.및 :

    @Jacksonized
    @Builder
    @Value
    class Foo {

        
    }

Thomas Fritch의 답변은 Jackson Dataformat 의존성을 pom에 추가한 후 Spring Boot과 완벽하게 연동되었습니다.

@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
    }
}

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml -->
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

언급URL : https://stackoverflow.com/questions/49999492/immutable-lombok-annotated-class-with-jackson

반응형