3

I have a Model 'NewModel' with the following property

import com.fasterxml.jackson.databind.JsonNode;

@ApiModel(
   description = "Data Class to hold new details"
)
public class NewModel {
   @ApiModelProperty(
      notes = "Value in JSON key:value format. Can be any key:value pair",
      example = "{ds:2017:08:05,hh:11}"
   )
   private final JsonNode value;
   (... getters and setters ...)
}

Apart from this, I have some rest controllers which get a JSON in request body. I use this model to get the JSOn from request body.

I have configured springfox swagger using maven, and generated the api definition. But in the generated API definitions, this model has been generated as

"NewModel": {
            "type": "object",
            "properties": {
                "value": {
                    "example": "{nds:2017:08:05,hh:11}",
                    "description": "Value of the stamp in JSON key:value format",
                    "$ref": "#/definitions/JsonNode"
                }
            },
            "description": "Data Class to hold details"
        }

And the reference JsonNode definition generated is

"definitions": {
    "JsonNode": {
        "type": "object",
        "properties": {
            "array": {
                "type": "boolean"
            },
            "bigDecimal": {
                "type": "boolean"
            },
            "bigInteger": {
                "type": "boolean"
            },
            "binary": {
                "type": "boolean"
            },
            "boolean": {
                "type": "boolean"
            },
            "containerNode": {
                "type": "boolean"
            },
            "double": {
                "type": "boolean"
            },
            "float": {
                "type": "boolean"
            },
            "floatingPointNumber": {
                "type": "boolean"
            },
            "int": {
                "type": "boolean"
            },
            "integralNumber": {
                "type": "boolean"
            },
            "long": {
                "type": "boolean"
            },
            "missingNode": {
                "type": "boolean"
            },
            "nodeType": {
                "type": "string",
                "enum": [
                    "ARRAY",
                    "BINARY",
                    "BOOLEAN",
                    "MISSING",
                    "NULL",
                    "NUMBER",
                    "OBJECT",
                    "POJO",
                    "STRING"
                ]
            },
            "null": {
                "type": "boolean"
            },
            "number": {
                "type": "boolean"
            },
            "object": {
                "type": "boolean"
            },
            "pojo": {
                "type": "boolean"
            },
            "short": {
                "type": "boolean"
            },
            "textual": {
                "type": "boolean"
            },
            "valueNode": {
                "type": "boolean"
            }
        }
    }

Now, when I generate a client library with this API definition, the JsonNode Object allowed on the client side has only Boolean variables, and I cannot assign actual JSON strings to it, and hence cannot pass a JSON value to the connecting server (from which I generated the API definitions)

I was wondering is there was a way I could get to pass Json Strings from client to server using the swagger generated libraries. Or any other directions in which I can achieve the required end result.

Thanks (and apologies for the long post)

abisheksampath
  • 376
  • 8
  • 23

2 Answers2

1

An attribute in ApiModelProperty, dataType="java.util.Map" should help

public class NewModel {
   @ApiModelProperty(
      example = "{ds:2017:08:05,hh:11}",
      dataType = "java.util.Map"
   )
   private final JsonNode value;
0

Perhaps AlternateTypeRuleConvention, which is introduced in Springfox, will help you.

For example, you can do this:

@Bean
public AlternateTypeRuleConvention typeConvention(final TypeResolver resolver) {
    return new AlternateTypeRuleConvention() {

        @Override
        public int getOrder() {
            return Ordered.HIGHEST_PRECEDENCE;
        }

        @Override
        public List<AlternateTypeRule> rules() {
            return Collections.singletonList(
                    AlternateTypeRules.newRule(resolver.resolve(JsonNode.class), resolver.resolve(jsonNodeApi()))
            );
        }
    };
}

private Type jsonNodeApi() {
    return new AlternateTypeBuilder()
            .fullyQualifiedClassName(
                    String.format("%s.generated.%s",
                            JsonNode.class.getPackage().getName(),
                            JsonNode.class.getSimpleName()))
            .build();
}

AlternateTypeBuilder also allows you to specify custom fields if necessary.

DDtKey
  • 51
  • 1
  • 4