Jackson을 사용하여 일부 JSON 개체를 Java 개체에 매핑하려고합니다. JSON 객체의 일부 필드는 필수이며 (로 표시 할 수 있음 @NotNull
) 일부는 선택 사항입니다.
Jackson과의 매핑 후 JSON 개체에 설정되지 않은 모든 필드는 Java에서 null 값을 갖습니다. @NotNull
null 인 경우 Jackson에게 Java 클래스 멤버에 기본값을 설정하도록 지시 할 수 있는 유사한 주석 이 있습니까?
편집 : 질문을 더 명확하게하기 위해 몇 가지 코드 예제가 있습니다.
Java 객체 :
class JavaObject {
@NotNull
public String notNullMember;
@DefaultValue("Value")
public String optionalMember;
}
JSON 객체는 다음 중 하나 일 수 있습니다.
{
"notNullMember" : "notNull"
}
또는:
{
"notNullMember" : "notNull",
"optionalMember" : "optional"
}
@DefaultValue
주석 그냥 내가 요구하고 무엇을 보여주는 것입니다. 실제 주석이 아닙니다. json으로 개체가 첫 번째 예에서와 같이 있으면 난의 값이 원하는 optionalMember
일을 "Value"
하지 null
. 그런 일을하는 주석이 있습니까?
답변
기본값을 설정하는 주석이 없습니다.
Java 클래스 수준에서만 기본값을 설정할 수 있습니다.
public class JavaObject
{
public String notNullMember;
public String optionalMember = "Value";
}
답변
제안 된 솔루션 중 하나만 명시 적으로 설정된 default-value
시기를 유지합니다 some-value:null
(POJO 가독성이 손실되고 어색함).
유지 default-value
하고 절대 설정하지 않는 방법은 다음과 같습니다.null
@JsonProperty("some-value")
public String someValue = "default-value";
@JsonSetter("some-value")
public void setSomeValue(String s) {
if (s != null) {
someValue = s;
}
}
답변
고유 한 JsonDeserializer를 만들고 해당 속성에 주석을 달 수 있습니다. @JsonDeserialize(as = DefaultZero.class)
예 : BigDecimal을 기본값으로 0으로 구성하려면 다음을 수행하십시오.
public static class DefaultZero extends JsonDeserializer<BigDecimal> {
private final JsonDeserializer<BigDecimal> delegate;
public DefaultZero(JsonDeserializer<BigDecimal> delegate) {
this.delegate = delegate;
}
@Override
public BigDecimal deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return jsonParser.getDecimalValue();
}
@Override
public BigDecimal getNullValue(DeserializationContext ctxt) throws JsonMappingException {
return BigDecimal.ZERO;
}
}
그리고 사용법 :
class Sth {
@JsonDeserialize(as = DefaultZero.class)
BigDecimal property;
}
답변
해결책은 기본 생성자 내부의 속성 값을 설정하는 것 같습니다. 따라서이 경우 Java 클래스는 다음과 같습니다.
class JavaObject {
public JavaObject() {
optionalMember = "Value";
}
@NotNull
public String notNullMember;
public String optionalMember;
}
Jackson과의 매핑 후 optionalMember
JSON에서이 누락 된 경우 Java 클래스의 값은 "Value"
.
그러나 주석이 있고 기본 생성자가없는 솔루션이 있는지 여전히 알고 싶습니다.
답변
구성원을 비공개로 만들고 setter / getter 쌍을 추가합니다. setter에서 null이면 대신 기본값을 설정하십시오. 또한 내부 값이 null 일 때 기본값을 반환하는 getter를 사용하여 스 니펫을 표시했습니다.
class JavaObject {
private static final String DEFAULT="Default Value";
public JavaObject() {
}
@NotNull
private String notNullMember;
public void setNotNullMember(String value){
if (value==null) { notNullMember=DEFAULT; return; }
notNullMember=value;
return;
}
public String getNotNullMember(){
if (notNullMember==null) { return DEFAULT;}
return notNullMember;
}
public String optionalMember;
}
답변
비슷한 문제가 있었지만 제 경우에는 기본값이 데이터베이스에있었습니다. 다음은 그에 대한 해결책입니다.
@Configuration
public class AppConfiguration {
@Autowired
private AppConfigDao appConfigDao;
@Bean
public Jackson2ObjectMapperBuilder builder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.deserializerByType(SomeDto.class,
new SomeDtoJsonDeserializer(appConfigDao.findDefaultValue()));
return builder;
}
그런 다음 필드 / 객체가 null 인 경우 json을 역 직렬화하고 기본값을 설정 SomeDtoJsonDeserializer
하는 ObjectMapper
데 사용 됩니다.
답변
이미 많은 좋은 제안이 있지만 여기에 하나 더 있습니다. @JsonDeserialize를 사용하여 Jackson이 post-deserialization을 호출하는 임의의 “sanitizer”를 수행 할 수 있습니다.
@JsonDeserialize(converter=Message1._Sanitizer.class)
public class Message1 extends MessageBase
{
public String string1 = "";
public int integer1;
public static class _Sanitizer extends StdConverter<Message1,Message1> {
@Override
public Message1 convert(Message1 message) {
if (message.string1 == null) message.string1 = "";
return message;
}
}
}