С помощью библиотеки Джексона json можно десериализовать объект с помощью @JsonCreator
и получить карту «верхнего уровня», представляющую входной json, следующим образом:
class MyClass {
final int field;
@JsonCreator
public MyClass(Map<String, Object> map) {
this.field = (int) map.get("theInt");
}
}
илидаже при статическом заводском методе:
class MyClass {
final int field;
public MyClass(int theInt) {
this.field = theInt;
}
@JsonCreator
static MyClass create(Map<String, Object> map) {
return new MyClass((int) map.get("theInt"));
}
}
В предыдущих примерах может обрабатываться следующий тип ввода json:
{
"key1":"value1",
"key2":"value2",
"key3":"value3"
}
Это особенно полезно в моем случае, потому что я хотел бы десериализоватьJSON, структура которого я не знаю.Получение доступа к тому, что я называю «картой верхнего уровня», упрощает процесс.
Я бы хотел десериализовать свои объекты таким образом, поскольку он также позволяет создавать неизменяемые объекты вместо использования @JsonAnySetter
, который неЯ не могу этого допустить, и @JsonProperty
, который я не могу использовать, так как заранее не знаю названия свойств, как я уже упоминал ранее.
Затем, чтобы пойти дальше, я хотел бы добавить некоторую конфигурацию в мойфабричный метод, и Джексон позволяет это с помощью @JacksonInject
и вызова withInjectableValues(InjectableValues)
на ObjectMapper
.
. В конечном итоге я хотел бы использовать такой код:
class MyClass {
final MyField[] myFields;
public MyClass(MyField... myFields) {
this.myFields = myFields;
}
@JsonCreator
static MyClass create(@JacksonInject("conf") Conf conf, Map<String, Object> map) {
MyFields[] myFields;
// initialize myFields (or any other object) based on the content of map
// and also make use of the inject conf
return new MyClass(myFields);
}
}
К сожалению, Джексон выбрасывает следующие исключения:
- при попытке обмануть конструктор
JsonMappingException: Argument #1 of constructor [constructor for MyClass, annotations: {JsonCreator=@JsonCreator()}] has no property name annotation; must have name when multiple-paramater constructor annotated as Creator
- при попытке использовать трюк на заводском методе
JsonMappingException: Argument #1 of factory method [method create, annotations: {JsonCreator=@JsonCreator()}] has no property name annotation; must have when multiple-paramater static method annotated as Creator
Кто-нибудь знает, как я могу решить эту проблему?
Чтобы подвести итог требований,Мне нужно:
- доступ к карте верхнего уровня (сделатьзаранее не знаю имен свойств json)
- для создания неизменяемого объекта (поэтому нельзя использовать
@JsonAnySetter
) - для добавления некоторого conf в украшенный конструктор
@JsonCreator
илифабричный метод
Я не могу изменить формат ввода json, который выглядит следующим образом:
{
"key1":"value1",
"key2":"value2",
"key3":"value3"
}
[EDIT]
Это известная проблема: http://jira.codehaus.org/browse/JACKSON-711 (еще не исправлено)