programing

역직렬화 시 속성 무시

nicescript 2023. 2. 15. 23:02
반응형

역직렬화 시 속성 무시

나는 부동산의 getter와 setter에 대한 간단한 인터페이스를 가지고 있습니다.

public interface HasMoney { 

      Money getMoney();

      void setMoney(Money money);

 }

이 인터페이스를 구현하는 다른 클래스 User Account가 있습니다.

public class UserAccount implements HasMoney {

       private Money money;

       @Override
       Money getMoney() // fill in the blanks

       @Override
       void setMoney(Money money) // fill in the blanks

}

문제는 money 속성을 시리얼화하고 싶지만 시리얼화를 해제하는 동안 무시한다는 것입니다.즉, 이 속성에 대한 사용자의 값을 받아들이지 않는 것입니다.세터에서는 @JsonIgnore를, 게터에서는 @JsonIgnore(false)를 시도했지만 무시되지만 시리얼화 중에도 시도됩니다.

setter에서 @JsonIgnore를, getter에서 @JsonProperty를 시도했습니다.이것은, 머니 속성이 서버에 송신되어 잭슨이 머니 타입의 오브젝트를 구축할 수 없게 되었을 때에 애플리케이션이 크래시 하는 것 같습니다.

가장 이상한 것은 @JsonIgnore를 세터에, @JsonProperty를 세터에 배치하는 것은 대부분의 경우 속성이 원시적인 경우에 효과가 있다는 것입니다.

버전 2.6.0+에서는 클래스레벨의 @JsonIgnoreProperties를 사용하여 이를 실행할 수 있습니다.

@JsonIgnoreProperties(value={ "money" }, allowGetters=true)

이 마감된 호를 보세요.https://github.com/FasterXML/jackson-databind/issues/95

네, 그럼 @JsonIgnore의 동작은 1.9 이후(더 나쁜 imo를 위해) 근본적으로 바뀌었습니다.역직렬화 중에 속성이 무시되지 않는 이유에 대해 자세히 설명하지 말고 다음 코드를 사용하여 수정해 보십시오.

public class UserAccount implements HasMoney {
    @JsonIgnore
    private BigDecimal money;

    // Other variable declarations, constructors

    @Override
    @JsonProperty
    public BigDecimal getMoney() {
        return money;
    }

    @JsonIgnore
    @Override
    public void setMoney(final BigDecimal money) {
        this.money = money;
    }

    // Other getters/setters
}

의 사용에 주의해 주세요.@JsonIgnore실제 솔루션에 필요합니다.

주의: 환경 및 사용 사례에 따라서는 USE_GETTERS_AS_SETTERS, AUTO_DETETECT_GETTERS, AUTO_DETECT_SETTERS 등 ObjectMapper 인스턴스에 대한 추가 설정이 필요할 수 있습니다.

잭슨 2.10에서는 다음과 같은 읽기 전용 필드를 구현할 수 있습니다.

실전

public class UserAccount implements HasMoney {

   @JsonProperty(access = JsonProperty.Access.READ_ONLY)
   private Money money;
   
   // getter and setter

}

가상 필드

@JsonIgnoreProperties(ignoreUnknown = true) // to ignore ALL unknown properties
// OR
@JsonIgnoreProperties(value = {"money"}, allowGetters = true) // to ignore only 'money' input
public class UserAccount implements HasMoney {

   @JsonProperty
   public Money getMoney() {
       // some calculation
   }

}

값은 시리얼화되지만 역직렬화 중에는 무시됩니다.

소유하지 않거나 추가해서 클래스를 변경할 수 없는 경우@JsonIgnore주석: 구현에서 버전 2.5 이후 mixin을 사용하면 예상 결과를 얻을 수 있습니다.

public abstract class HasMoneyMixin {
    @JsonIgnore
    public abstract Money getMoney();
}

mixin을 사용하도록 매퍼를 구성합니다.

ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(HasMoney.class, HasMoneyMixin.class);
// avoid failing if all properties are empty
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

제 해결방법이 늦어진 것 같습니다만, 다른 사람들에게 도움이 될 것입니다.

선사시대: 제 프로젝트에는 JSON 문자열을 엔티티에 직접 읽어주는 클래스가 있습니다.JSON에는 클래스의 변수가 아닌 속성이 포함되어 있습니다.때문에.

objectMapper.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

디시리얼라이제이션 중에는 엔티티의 인스턴스가 생성되지 않습니다(프로젝트에서는 이러한 예외가 바람직합니다).

솔루션:

objectMapper.addHandler(new DeserializationProblemHandler() {
    @Override
    public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p, JsonDeserializer<?> deserializer, Object beanOrClass, String propertyName) throws IOException {
       if( (propertyName.equals("propertyToBeIgnored") && beanOrClass.getClass().equals(ClassOfTheProperty.class)) {
           p.skipChildren();
           return true;
       } else {
           return false;
       }
    }
});

언급URL : https://stackoverflow.com/questions/16019834/ignoring-property-when-deserializing

반응형