Ответ 1
Нет аннотации для установки значения по умолчанию.
Вы можете установить значение по умолчанию только на уровне класса java:
public class JavaObject
{
public String notNullMember;
public String optionalMember = "Value";
}
Я пытаюсь сопоставить некоторые объекты JSON с объектами Java с Jackson. Некоторые из полей в объекте JSON являются обязательными (что я могу отметить с помощью @NotNull
), а некоторые являются необязательными.
После сопоставления с Jackson все поля, которые не заданы в объекте JSON, будут иметь нулевое значение в Java. Есть ли аналогичная аннотация для @NotNull
, которая может сказать Джексону установить значение по умолчанию для члена класса Java, если оно равно null?
Изменить: Чтобы сделать этот вопрос более ясным, приведен пример кода.
Объект 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
по default-value
когда some-value:null
был установлен явно (читаемость POJO там потеряна и неуклюжа)
Вот как можно сохранить default-value
по default-value
и никогда не устанавливать его на null
@JsonProperty("some-value")
public String someValue = "default-value";
@JsonSetter("some-value")
public void setSomeValue(String s) {
if (s != null) {
someValue = s;
}
}
Похоже, решение состоит в том, чтобы установить значение свойств внутри конструктора по умолчанию. Итак, в этом случае класс java:
class JavaObject {
public JavaObject() {
optionalMember = "Value";
}
@NotNull
public String notNullMember;
public String optionalMember;
}
После сопоставления с Jackson, если в JSON отсутствует optionalMember
, его значение в классе Java равно "Value"
.
Однако мне все еще интересно узнать, есть ли решение с аннотациями и без конструктора по умолчанию.
Сделайте элемент частным и добавьте пару setter/getter. В вашем сеттере, если значение null, вместо этого установите значение по умолчанию. Кроме того, я показал фрагмент с геттером, также возвращающим значение по умолчанию, когда внутреннее значение равно null.
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;
}
Вы можете создать свой собственный JsonDeserializer и аннотировать это свойство с помощью @JsonDeserialize(as = DefaultZero.class)
Например: чтобы настроить BigDecimal по умолчанию на Ноль:
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;
}
У меня была аналогичная проблема, но в моем случае значение по умолчанию было в базе данных. Ниже приведено решение для этого:
@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;
}
Затем в SomeDtoJsonDeserializer
используйте ObjectMapper
для десериализации json и установки значения по умолчанию, если ваше поле/объект имеет значение null.