1

我正在尝试反序列化以下内容:

{
 "type":"GIQuestionnaire",
 "id":6051,   
 "questions":[
      {
        "type":"IncludeExcludeQuestion",
        "id":24057,
        "answers":[
            {
              "type":"IncludeExcludeAnswer",
               "id":101497
            },
            {
              "type":"IncludeExcludeAnswer",
               "id":101496
            }
         ]
      }
   ]
}

导致此错误:

java.lang.AssertionError: Can not handle managed/back reference 'questionnaire-questions': value deserializer is of type ContainerDeserializerBase, but content type is not handled by a BeanDeserializer  (instead it's of type com.foo.questionnaire.json.QuestionDeserializer)

Junit测试:

@Test
public void testDeserializeQuestionnaire() {
    ObjectMapper mapper = new ObjectMapper();
    GIQuestionnaire q = manager.createGIQuestionnaire(…);
    try
    {
        String json = mapper.writeValueAsString(q);
        assertTrue(q.equals(mapper.readValue(json, GIQuestionnaire.class)));
    } catch (Exception e) {
        fail(e.getMessage());
    }
}

Questionnaire 包含 Question 对象的 Set(实现为 TreeSet)。一个问题包含一组答案对象(TreeSet)。

以下是显示我如何使用 Jackson 注释的相关代码片段:

// Questionnaire abstract base class
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({
    @JsonSubTypes.Type(value=GIQuestionnaire.class, name="GIQuestionnaire"),
    @JsonSubTypes.Type(value=PolicyQuestionnaire.class, name="PolicyQuestionnaire")    
})
public abstract class Questionnaire implements Serializable {
    @JsonManagedReference("questionnaire-questions")
    @JsonDeserialize(as = TreeSet.class, contentAs = Question.class)

    private Set<Question> questions = new TreeSet<>();

    // … remainder omitted for brevity 
}

// Question abstract base class
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = EntityQuestion.class, name = "EntityQuestion"),
    @JsonSubTypes.Type(value = IncludeExcludeQuestion.class, name = "IncludeExcludeQuestion")
})
@JsonDeserialize(using = QuestionDeserializer.class)
public abstract class Question implements Comparable<Question>, Serializable {
   @JsonBackReference("questionnaire-questions")
   private Questionnaire questionnaire;

   @JsonManagedReference("question-answers")
   @JsonDeserialize(as = TreeSet.class, contentAs = Answer.class)
   private Set<Answer> answers = new TreeSet<>();

    // … remainder omitted for brevity
}

// Answer abstract base class
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = EntityAnswer.class, name = "EntityAnswer"),         
    @JsonSubTypes.Type(value = IncludeExcludeAnswer.class, name = "IncludeExcludeAnswer")
})
@JsonDeserialize(using = AnswerDeserializer.class)
public abstract class Answer implements Comparable<Answer>, Serializable {

   @JsonBackReference("question-answers")
   private Question question;
   // … remainder omitted for brevity 
}

public class QuestionDeserializer extends JsonDeserializer<Question> {
    @Override
    public Question deserialize(JsonParser jsonParser, DeserializationContext     deserializationContext) throws IOException, JsonProcessingException {
        //deserialize a Question to a concrete instance
    }
}

public class AnswerDeserializer extends JsonDeserializer<Answer> {
    @Override
    public Answer deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        //deserialize an Answer to a concrete instance
    }
}

我的注释和/或反序列化器哪里出错了?

4

2 回答 2

3

根据Jackson WIKI,不支持多态反序列化和 @JsonManagedReference / @JsonBackReference 的组合。

目前(从 1.6.0 版开始)抽象类型的组合(使用 @JsonTypeInfo 进行多态处理)不适用于此功能

另请参阅 Jackson 问题跟踪器中的最新问题JIRA-890

于 2013-05-06T08:39:34.413 回答
0

如果您尝试@JsonIdentityInfo使用 jackson 2 库中提供的非常方便的接口实现会怎样?

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Answer { ....

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Question { ....

在 Maven 中

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.0.2</version>
</dependency>
于 2015-03-07T01:31:47.713 回答