programing

Jackson + Builder pattern?

procenter 2022. 10. 30. 16:16
반응형

Jackson + Builder pattern?

잭슨이 다음 생성자와의 클래스를 역직렬화했으면 합니다.

public Clinic(String name, Address address)

첫 번째 인수를 역직렬화하는 것은 쉽습니다.문제는 주소가 다음과 같이 정의된다는 것입니다.

public class Address {
  private Address(Map<LocationType, String> components)
  ...

  public static class Builder {
    public Builder setCity(String value);
    public Builder setCountry(String value);
    public Address create();
  }
}

다음과 같이 구성됩니다.new Address.Builder().setCity("foo").setCountry("bar").create();

직접 주소를 작성하기 위해 잭슨으로부터 키와 값의 쌍을 얻을 수 있는 방법이 있습니까?아니면 Jackson이 Builder 클래스 자체를 사용하도록 하는 방법이 있습니까?

Jackson 2+ 를 사용하고 있는 한, 이것에 대한 서포트가 짜넣어져 있습니다.

먼저 이 주석을 다음 항목에 추가해야 합니다.Address클래스:

@JsonDeserialize(builder = Address.Builder.class)

그런 다음 이 주석을 다음 항목에 추가해야 합니다.Builder클래스:

@JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set")

빌드할 Builder의 작성 방법 및 설정 대신 앞에 붙일 Builder의 설정 이름을 바꾸려면 이 두 번째 주석을 건너뛸 수 있습니다.

완전한 예:

@JsonDeserialize(builder = Address.Builder.class)
public class Address
{
  private Address(Map<LocationType, String> components)
  ...

  @JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set")
  public static class Builder
  {
    public Builder setCity(String value);
    public Builder setCountry(String value);
    public Address create();
  }
}

@Rupert Madden-Abbott의 답변은 효과가 있습니다.단, 기본이 아닌 생성자가 있는 경우,

Builder(String city, String country) {...}

그런 다음 다음과 같이 파라미터에 주석을 달아야 합니다.

@JsonCreator
Builder(@JsonProperty("city")    String city, 
        @JsonProperty("country") String country) {...}

이 경우 나에게 적합한 솔루션(나는 "Lombok" 빌더 주석을 사용했습니다).

@Getter
@Builder(builderMethodName = "builder")
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@JsonAutoDetect(
    fieldVisibility = JsonAutoDetect.Visibility.ANY,
    creatorVisibility = JsonAutoDetect.Visibility.ANY
)

당신에게도 도움이 되길 바랍니다.

@JsonDeserialize를 사용하여 다음과 같이 구현했습니다.

@JsonDeserialize(using = JacksonDeserializer.class)
public class Address
{...}

@JsonCachable
static class JacksonDeserializer extends JsonDeserializer<Address>
{
    @Override
    public Address deserialize(JsonParser parser, DeserializationContext context)
        throws IOException, JsonProcessingException
    {
        JsonToken token = parser.getCurrentToken();
        if (token != JsonToken.START_OBJECT)
        {
            throw new JsonMappingException("Expected START_OBJECT: " + token, parser.getCurrentLocation());
        }
        token = parser.nextToken();
        Builder result = new Builder();
        while (token != JsonToken.END_OBJECT)
        {
            if (token != JsonToken.FIELD_NAME)
            {
                throw new JsonMappingException("Expected FIELD_NAME: " + token, parser.getCurrentLocation());
            }
            LocationType key = LocationType.valueOf(parser.getText());

            token = parser.nextToken();
            if (token != JsonToken.VALUE_STRING)
            {
                throw new JsonMappingException("Expected VALUE_STRING: " + token, parser.getCurrentLocation());
            }
            String value = parser.getText();

            // Our Builder allows passing key-value pairs
            // alongside the normal setter methods.
            result.put(key, value);
            token = parser.nextToken();
        }
        return result.create();
    }
}

builder 패턴은 현재 지원이 없습니다만, 꽤 오래전에 요청되어 있었습니다(그리고 최종적으로 Jira 발행 http://jira.codehaus.org/browse/JACKSON-469이 접수되었습니다).수요가 충분하다면 1.8 릴리즈에 추가할 수 있습니다(Jira!에서 투표해 주십시오).이는 합리적인 추가 기능으로 개발자의 시간만큼 지연될 뿐입니다.하지만 더하면 좋을 것 같아요.

이것은 나에게 효과가 있었습니다: @NoArgsConstructor 이것의 유일한 단점은 = 새로운 ADTO()를 다시 할 수 있다는 것입니다.하지만, 어쨌든, 나는 코드 경찰을 좋아하지 않아, 나에게 코드 사용법을 가르쳐줘:-) 그러니 내 POJO DTOS를 네가 원하는 대로 사용해.빌더가 있든 없든.제안합니다. 빌더와 함께 하셔도 좋습니다.

@Data
@Builder
//Dont forget this! Otherwise no Jackson serialisation possible!
@NoArgsConstructor
@AllArgsConstructor
public class ADTO {
.....
}

언급URL : https://stackoverflow.com/questions/4982340/jackson-builder-pattern

반응형