Using swagger to document a string from enum values - java

I am getting the following error when trying to get the enum values for an allowableValues tag.
The value for annotation attribute ApiModelProperty.allowableValues
must be a constant expression
What I am trying to do:
#ApiModelProperty(allowableValues = new Enums().enumToString(SomeEnum.class))
private String someString;
Here is the logic for Enums().enumToString
public class Enums {
public final <E extends Enum<E>> String enumToString(Class<E> inputEnum) {
//inputEnum;
for (Enum enumValues : EnumSet.allOf(inputEnum)) {
//will create a string of the enum values
}
return "will be a formatted string of the enum values";
}
}
Is it possible to do what I am trying to accomplish? I know it is possible to just expose the enum in my API and swagger would then recognize the allowed values automatically, however the field in question needs to be exposed as a string, even though our internal logic has it as an enum.
Thanks in advance for your help!

#ApiModelProperty(value = "embed", dataType = "[Lmodel.request.Embed;")
private final List<String> embed;
the Embed path is a list of enums. This show you something like this in the swagger documentation:
type: "object"
properties:
embed:
type: "array"
description: "embed"
items:
type: "string"
enum:
-SOME
-SOME
-SOME
-SOME

Your problem is not related to Swagger at all but basic Java.
In Java annotations, you can have constant expressions, meaning you can't do method calls there, any other things but only use constant values.

Related

Change naming of attributes in json without #JsonProperty

I have to convert my json from camelCase to kebab-case.
Example:
My Json:
{
"disclaimerConfirmed" : true
}
And I need:
{
"disclaimer-confirmed" : true
}
I cannot use #JsonProperty because it rename this atributes permanently. I am looking for something which will consume Json (can be as String) and returns modified json(as String).
Jackson supports naming strategies so you could read the input String to map (with camelCase strategy) and then write the map back to a String (with kebab-case which is natively supported );
Specific method you need to switch these conventions in ObjectMapper without annotations is:
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.*);
You can have different serializers for different cases or you can create pojo with #JsonProperty and use those where-ever required.
For example,
class A {
private String disclaimerConfirmed;
}
class AkebabCase {
#JsonProperty("disclaimer-confirmed")
private String disclaimerConfirmed;
}
So, if you want to serialize to kebab-case you can use converters to convert A to AkebabCase and then serialize.

Issue using jackson to parse JSON containing variable that equals the "final" keyword in java

I am using jackson to parse json files to java objects.
This requires me to create java objects matching the json files. However currently I have a json file looking like this:
{
"name": "myName",
"final": "whatever"
}
Normally I would create a matching class in java:
class MyClass {
String name;
String final;
}
However the problem here is that 'final' is a java keyword and can't be used as a Java variable name. What would be the best way to solve this (trying to avoid manual parsing as the above is just a simplified version of the real situation).
You can use #JsonProperty annotation to tell jackson how to serialize/deserialize your custom fields. final is a special keyword in Java so you can use this annotation and name field whatever is valid :
class MyClass {
String name;
#JsonProperty("final")
String someName;
}

Dynamodb - Convert enumerator collection

Is there a way to convert a collection of enums? I've tried the following without success:
#DynamoDBTypeConvertedEnum
#DynamoDBAttribute(attributeName="myEnums")
private Collection<MyEnum> myEnums;
In order to save it as collection (i.e. set of strings), please use #DynamoDBTyped annotation with SS attribute type.
#DynamoDBTyped(DynamoDBAttributeType.SS)
#DynamoDBAttribute(attributeName = "myEnums")
public Set<MyEnum> getMyEnums() {
return myEnums;
}
myEnums is a Set of enums, not an enum itself.
DynamoDBTyped
The enum type is only supported by override or custom converter
Because you have a set of enums, you will need to use a customer converter. So remove the #DynamoDBTypeConvertedEnum annotation and use a custom converter. You can see an example I have posted before here. Its a generic Set example but it will work for your enum Set.
EDIT: i.e. use DynamoDBTypeConverted

Using Swagger-annotation to represent a complex property as a String

In a Java/Spring ReST application, I'm using swagger-annotations 1.3.7 I have a number of small classes (for example, GenderCode) that I use as properties in my ReST models. These classes have a single public property, called value. Using Jackson, my APIs can accept a simple String s and construct an instance of, say, GenderCode with its value set to s. Similarly, it can serialize a GenderCode as a simple String (which of course represents the value of value).
I would like my Swagger documentation to represent these objects as simple strings, since that represents what the JSON will look like. Instead it represents an complex type with a "value" key:
{
"genderCode": {
"value": ""
},
...
}
It should look simply like this:
{
"genderCode": "",
...
}
Here's what the Java model would look like:
public class Person {
#JsonProperty("genderCode")
#Valid
#KnownEnumValue
#ApiModelProperty(value = "GenderCode", dataType="string", required = false,
allowableValues=GenderCode.POSSIBLE_VALUES_DISPLAY)
private GenderCode genderCode;
...
}
Here's the definition of that property within the API definition file that Swagger generates:
"genderCode":{"enum":["ANY","M","F"],"description":"GenderCode","required":false,"type":"GenderCode"}
I've tried using an OverrideConverter, but that had no effect. Any thoughts on how this can be done?

How to represent fields with generic types like List<Something> in swagger-spring-mvc for swagger-codegen

I'm using swagger-spring-mvc 0.9.5 and have fields like this in my response data:
#ApiModelProperty("Some description")
private List<Account> accounts;
Short version of the question: how can I get from this annotated Java to e.g. Objective C via swagger-codegen?
The swagger JSON that gets generated by that is:
accounts: {
description: "Some description",
items: {
type: "Account"
},
required: false,
type: "List"
}
My colleague is feeding this into swagger-codegen to generate Objective C classes, and it's producing code that doesn't compile.
#property (nonatomic, strong) NSArray<Optional, NSArray> *accounts;
because NSArray (inside the < >) isn't a protocol.
The swagger template files (mustache) create a protocol for each model. When that protocol is specified on an array, it is picked up by JSONModel to generate the correct models from the data inside the list / array. So in this case the expected output is
#property (nonatomic, strong) NSArray<Optional, MAAccount> *accounts;
This will create an NSArray of MAAccount's (Account being the object type and MA being a prefix that swagger already has).
If we hand-edit the swagger JSON to change List to array (as suggested in various similar cases), the output is correct, but we want to avoid this manual step.
So I tried to get swagger-spring-mvc to use "array":
#ApiModelProperty(value = "Some description", dataType = "array")
private List<Account> accounts;
But then discovered that dataType is ignored in swagger-spring-mvc 0.9.5, and by the looks of it, in springfox 2.0 it is ignored unless it's a fully-qualified Java class name.
Is there a way to achieve this, either by getting swagger-spring-mvc/springfox to use "array" or by any other means?
For the most part the swagger annotations are only an aid to the springfox engine to infer additional information about the types like description/hidden/readonly etc that are not otherwise available from the type system. It can also used as a crutch to represent types that are not easily inferred. Data types can be overriden, but just for type safety as it was pointed out in the comment.
Specifically, I read that dataType will be ignored unless it's a fully-qualified class name.
Like #CupawnTae suggested, version 2.x of springfox supports an option to render generic types with code-generation friendly and language agnostic representations of generic types.
When creating/configuring your docket you will need to specify that the rendered swagger service description needs to be code-generation friendly using the forCodeGeneration option
#Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
...
.forCodeGeneration(true)
...;
}
This will cause springfox to render generic types like List<String>
as ListOfString when forCodeGeneration is set to true
as ListĀ«StringĀ» when forCodeGeneration is set to false
You can try notation below. Dont't forget to use package info of you class
#ApiModelProperty(dataType = "[Lyour.package.Account;")
private List<Account> accounts;

Categories

Resources