Как сопоставить swagger.json с объектом Swagger? - PullRequest
0 голосов
/ 30 апреля 2019

В настоящее время я пытаюсь сопоставить файл swagger.json с io.swagger.models.Swagger.class.Я пытался использовать com.fasterxml.jackson.databind.ObjectMapper.class, чтобы решить эту проблему следующим образом:

new ObjectMapper().readValue(file.getInputStream(), Swagger.class)`

, но я получил это исключение:

"InvalidDefinitionException: Cannot construct instance of io.swagger.models.parameters.Parameter (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information at [Source: (FileInputStream); line: 28, column: 21] (through reference chain: io.swagger.models.Swagger["paths"]->java.util.LinkedHashMap["/myPath"]->io.swagger.models.Path["post"]->io.swagger.models.Operation["parameters"]->java.util.ArrayList[0])"

Проблема заключается вчто поле параметров в классе Swagger выглядит следующим образом:

protected Map<String, Parameter> parameters;

Параметр здесь - это Интерфейс, поэтому ObjectMapper не знает, какой класс создать (BodyParameter, PathParameter, FormParameter...)

Я ожидаю загрузки файла swagger.json в объект Swagger.

Спасибо за помощь.

1 Ответ

0 голосов
/ 30 апреля 2019

Я нашел это, мне нужно было реализовать десериализаторы, чтобы явно объявить, какой конструктор класса использовать. У меня были проблемы с параметром, моделью и свойством, которые были всеми интерфейсами.

Вот код:

ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addDeserializer(io.swagger.models.parameters.Parameter.class, new ParameterDeserializer());
        module.addDeserializer(io.swagger.models.Model.class, new ModelDeserializer());
        module.addDeserializer(io.swagger.models.properties.Property.class, new PropertyDeserializer());
        mapper.registerModule(module);

Просто пример, чтобы прояснить ситуацию, позже я могу сделать его более гибким:

import java.io.IOException;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.FormParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.parameters.PathParameter;
import io.swagger.models.parameters.QueryParameter;

public class ParameterDeserializer extends StdDeserializer<io.swagger.models.parameters.Parameter> {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public ParameterDeserializer() {
        this(null);
    }

    public ParameterDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public Parameter deserialize(JsonParser parser, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        final JsonNode node = parser.getCodec().readTree(parser);
        final ObjectMapper mapper = (ObjectMapper) parser.getCodec();
        if (node.get("in").toString().toLowerCase().replaceAll("\"", "").equals("path")) {
            return mapper.treeToValue(node, PathParameter.class);
        } else if (node.get("in").toString().toLowerCase().replaceAll("\"", "").equals("body")) {
            return mapper.treeToValue(node, BodyParameter.class);
        } else if (node.get("in").toString().toLowerCase().replaceAll("\"", "").equals("query")) {
            return mapper.treeToValue(node, QueryParameter.class);
        } else {
            return mapper.treeToValue(node, FormParameter.class);
        }
    }

}

То же самое для других десериализаторов. Надеюсь, это поможет.

...