Вы можете сделать это, связав свои свойства и используя @JacksonInject
. Эта аннотация хорошо работает с объектным картографом. Я пропускаю часть о том, как связать пружину с Джексоном в коде, но приведу простой пример ObjectMapper
. Смотрите этот код:
package de.pandaadb.jackson;
import java.io.IOException;
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class DataModel {
private String test;
private String optionalValue;
@JsonCreator
public DataModel(@JsonProperty("test") String test, @JacksonInject("opt") @JsonProperty(value= "opt", required=false)String opt) {
this.optionalValue = opt;
this.test = test;
}
@Override
public String toString() {
return "test=" + test + " optional=" + optionalValue;
}
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
InjectableValues.Std std = new InjectableValues.Std();
std.addValue("opt", "alternative");
String withOptional = "{\"test\" : \"hello\" , \"opt\" : \"optss\"}";
String withoutOptional = "{\"test\" : \"hello\"}";
mapper.setInjectableValues(std);
System.out.println(mapper.readValue(withOptional, DataModel.class));
System.out.println(mapper.readValue(withoutOptional, DataModel.class));
}
}
Этот код печатает:
test=hello optional=optss
test=hello optional=alternative
Несколько нот:
Конструктор использует аннотацию JacksonInject
в конструкторе в дополнение к свойству. Это сначала введет сконфигурированное значение, опционально перезаписав его значением json, поступающим с входа.
ObjectMapper
передаются свойства, которые соответствуют аннотации
Вторая часть самая важная.
Что касается работы с пружиной, подход будет иметь такой код в вашей конфигурации:
@Configuration
public class ObjectMapperConfiguration {
ObjectMapper mapper(@Value("${my.test.string}") String test) {
ObjectMapper mapper = new ObjectMapper();
InjectableValues.Std std = new InjectableValues.Std();
std.addValue("my.test.string", "test");
mapper.setInjectableValues(std);
return mapper;
}
}
В качестве альтернативы вы также можете внедрить ВСЕ свойства и передать их обратно в преобразователь объектов, чтобы не приходилось расширять это с каждым новым свойством.
Надеюсь, это поможет,
Еще несколько материалов для чтения здесь: https://www.concretepage.com/jackson-api/jackson-jacksoninject-example#ObjectMapper
Последнее редактирование: как сделать это только с одним аргументом конструктора, если Джексон сам обработает перезапись
- Артур