0

I am currently trying to map a swagger.json file to a io.swagger.models.Swagger.class. I've tried to use com.fasterxml.jackson.databind.ObjectMapper.class to solve the issue by :

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

but i got this exception:

"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])" 

The problem is that the parameters field in Swagger class goes like this :

protected Map<String, Parameter> parameters;

Parameter here is an Interface, so the ObjectMapper doesn't know which class to instantiate (BodyParameter, PathParameter, FormParameter...)

I expect to load a swagger.json file into a Swagger Object.

Thank you for your help.

2 Answers 2

2

Similar to Rayen's answer, you have to register deserialisers. Swagger offers serializers for its objects (e.g. Parameter, Property, Model) in io.swagger.util within io.swagger:swagger-core.

Sign up to request clarification or add additional context in comments.

Comments

1

I found it, I needed to implement Deserializers in order to declare explicitly which class constructor to use. I had problem with Parameter, Model and Property which were all interfaces.

Here is the Code :

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); 

Just an example to clarify things, I can make it more flexible later :

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); } } } 

Same for the other deserializers. Hope it helps.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.