Я хотел попробовать использовать вариант конвертера Jackson для анализа некоторых пользовательских строк. Мне приходится иметь дело с устаревшими представлениями строк, которые имеют свой собственный синтаксический анализатор, способный взять строку и преобразовать ее в мой желаемый класс, IceComTerm
. Таким образом, я создал класс, который использует поле IceComTerm
типа (с некоторыми дополнительными полями удалены для удобства чтения) и преобразовательКак правильно использовать конвертер Jackson Deserializer
public final class PropertySetRepresentation {
@JsonProperty("kbPrepare")
@JsonDeserialize(converter = IceComTermJsonAdapter.IceComTermDeserializationConverter.class)
private final IceComTerm kbPrepare;
@JsonCreator
public PropertySetRepresentation(@JsonProperty("kbPrepare")IceComTerm kbPrepare){
this.kbPrepare = kbPrepare;
}
@JsonIgnore
public IceComTerm getIceComRepresentation() {
return kbPrepare;
}
}
public class IceComTermJsonAdapter {
public static class IceComTermDeserializationConverter extends StdConverter<String, IceComTerm> {
@Override
public IceComTerm convert(String arg) {
try {
return IceComFactory.parseIceTerm(arg);
} catch (IceComException e) {
e.printStackTrace();
throw new IllegalArgumentException("Incorrect IceComString, fails to parse as IceCom: " + e.getMessage(), e);
}
}
}
}
я ожидал, что это будет в состоянии взять строку и превратить его в IceComTerm
типа, который я необходимо. Но когда я запускаю следующий тест, я получаю исключение:
@Test
public void deserializePropertySetRepresentation() throws IOException {
String propertySet = "{\"kbPrepare\":\"[forall,?circ,in,[:set,Circuit-36]]\"}";
PropertySetRepresentation model = JSON_MAPPER.readValue(propertySet, PropertySetRepresentation.class);
assertNotNull(model);
}
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of iceInterfaces.IceComTerm, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
at [Source: {"kbPrepare":"[forall,?circ,in,[:set,Circuit-36]]"}; line: 1, column: 2]
Я подумал, что если я использую конвертер, это не имеет значения, что IceComTerm
является абстрактным классом, потому что я создаю определенный экземпляр, разбор строка в конвертере. Что мне здесь не хватает? Я использую Jackson 2.5.0
Спасибо. С небольшим количеством работы я создал минимальный тестовый пример, который, я думаю, демонстрирует, что это ошибка. Проблема заключается в том, что IceComTerm является абстрактным. Если я использую точно такой же подход с не-абстрактным классом, это нормально. Выделили проблему в github, как вы сказали: https://github.com/FasterXML/jackson-databind/issues/795 – myrosia
Большое спасибо. Есть несколько причин, по которым проблема может быть вызвана, но ваше использование выглядит правильно, и проблема в обработке Джексона конвертера для аргумента конструктора. – StaxMan