如何在spring-boot中将json反序列化为抽象类

时间:2017-04-14 03:34:33

标签: json spring-boot

在我的应用程序中,我有类似的东西。

public class Question{}
public class MCQ extends Question{}
public class TrueAndFalse Question{}
public class Match Question{}

在我的RestController中我有一个添加问题的服务。

@RequestMapping(value = "/game/question/add", method = RequestMethod.POST)
public Question addQuuestion(@RequestParam("gameId") long id, @RequestBody Question question)

但是当我尝试调用此服务时出现错误,因为我发送了具有不同结构的json文件,用于MCQ,TrueAndFalse和Match。 所以可以将收到的json反序列化为问题抽象类。

并提前感谢。

1 个答案:

答案 0 :(得分:2)

您可以创建一个自定义反序列化器,它将根据json有效内容属性创建Question个实例。

例如,如果Question类看起来像这样:

public class Question {

    private final String name;

    @JsonCreator
    Question(@JsonProperty("name") String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

子类TrueAndFalse

public class TrueAndFalse extends Question {

    private final String description;

    @JsonCreator
    TrueAndFalse(@JsonProperty("name") String name,
                 @JsonProperty("description") String description) {

        super(name);
        this.description = description;
    }

    public String getDescription() {
        return description;
    }
}

然后你可以创建一个反序列化器,通过检查它是否具有TrueAndFale属性来创建description子类的实例:

public class QuestionDeserializer extends JsonDeserializer<Question> {

    @Override
    public Question deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
        ObjectCodec codec = p.getCodec();
        JsonNode tree = codec.readTree(p);

        if (tree.has("description")) {
            return codec.treeToValue(tree, TrueAndFalse.class);
        }

        // Other types...

        throw new UnsupportedOperationException("Cannot deserialize to a known type");
    }
}

然后,确保在对象映射器上注册它:

@Configuration
public class ObjectMapperConfiguration {

    @Bean
    public ObjectMapper objectMapper() {
        SimpleModule module = new SimpleModule();
        module.addDeserializer(Question.class, new QuestionDeserializer());
        return new ObjectMapper().registerModules(module);
    }
}