2015-05-15 3 views
0

Я хотел попробовать использовать вариант конвертера 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

ответ

0

Звучит как возможная ошибка здесь, возможно, аннотация из поля не «видна» конструктором. Вы можете попытаться определить, имеет ли значение перемещение @JsonDeserialize рядом с параметром конструктора.

В любом случае, стоит сообщить об ошибке по адресу: https://github.com/FasterXML/jackson-databind/issues/

+0

Спасибо. С небольшим количеством работы я создал минимальный тестовый пример, который, я думаю, демонстрирует, что это ошибка. Проблема заключается в том, что IceComTerm является абстрактным. Если я использую точно такой же подход с не-абстрактным классом, это нормально. Выделили проблему в github, как вы сказали: https://github.com/FasterXML/jackson-databind/issues/795 – myrosia

+0

Большое спасибо. Есть несколько причин, по которым проблема может быть вызвана, но ваше использование выглядит правильно, и проблема в обработке Джексона конвертера для аргумента конструктора. – StaxMan

Смежные вопросы