We use a lot of static inner classes as a way of grouping together similar, but not identical dtos.
For example:
public class CustomerDto {
public static class In {
// fields for saving a new customer
}
public static class Out {
// fields returned when querying a customer.
}
}
public class Address {
public static class In {
//...
}
public static class Out {
//...
}
}
In this case, it looks like the swagger.json is including only one of the In classes (with the reference "#/definitions/In") and one of the Out classes.
This makes it fairly unusable since the apis using the other In/Out classes have the wrong model.
At the least, could the generation fail if it gets naming conflicts? Right now it's just silently referencing the wrong model.
I'm using Jersey to generate the swagger.json if that helps/makes a difference.
Thanks.
Looks like the name is coming out of TypeNameResolver, which uses .getSimpleName().
Not sure how to make it use a different TypeNameResolver.
I can probably also use @ApiModel to override the generated names.
My biggest worry is that it's failing silently when there are name conflicts, so it's really easy for a dev to not realize they have to provide a unique name.
I'm assuming you'd have the same issue if you had classes with the same name in two different packages.
I have just encountered this behaviour and was really suprised because I would assume that this would be a serious issue. For example I have one User model and have multiple request and response classes for multiple operations with User - each containing only a subset of User's attributes.
For example I have class CreateUserRequest (in one package) annotated with @JsonRootName(value = "user") and another class UpdateUsersStateRequest (may be even in the same package) again with annotation @JsonRootName(value = "user"). Swagger definition has only one of those definitions and ignoring others so basically most of the generated examples which I see in swagger UI are wrong.
I would assume that swagger would have different definition for each REST method, am I missing something? It is extremely important to be able to define same object with different attributes in different API methods.
I have a problem where two DTOs have the same name, but different package names. As @mhaefele noted above, the TypeNameResolver uses Class.getSimpleName(), which makes resolution ambiguous and sometimes nondeterministic between swagger-core versions. Using the @ApiModel has been our solution thus far, however it seems that simply changing the TypeNameResolver to use Class.getName() will solve both problems.
With this change, assuming the CustomerDTO above is in the test package, the definition names would resolve to:
test.CustomerDTO$In
test.CustomerDTO$Out
I've tested this change locally:
smills@smills-mac:~/Development/src/swagger-core (master *)$ git diff
diff --git a/modules/swagger-core/src/main/java/io/swagger/jackson/TypeNameResolver.java b/modules/swagger-core/src/main/java/io/swagger/jackson/TypeNameResolver.java
index c1dfdd2f..adafffef 100644
--- a/modules/swagger-core/src/main/java/io/swagger/jackson/TypeNameResolver.java
+++ b/modules/swagger-core/src/main/java/io/swagger/jackson/TypeNameResolver.java
@@ -41,11 +41,11 @@ public class TypeNameResolver {
protected String nameForClass(Class<?> cls, Set<Options> options) {
if (options.contains(Options.SKIP_API_MODEL)) {
- return cls.getSimpleName();
+ return cls.getName();
}
final ApiModel model = cls.getAnnotation(ApiModel.class);
final String modelName = model == null ? null : StringUtils.trimToNull(model.value());
- return modelName == null ? cls.getSimpleName() : modelName;
+ return modelName == null ? cls.getName() : modelName;
}
protected String nameForGenericType(JavaType type, Set<Options> options) {
smills@smills-mac:~/Development/src/swagger-core (master *)$
This change seems to work in my functional application testing, however I had to build with skipTests=true because this change breaks several unit tests. An official PR would need to resolve the tests as well. I can submit a PR if this is an approved change.
Note: This does not solve the @JsonRootName issue noted by @PavelJ.
confirming this issue. using simpleName in this context looks defective to me. @ApiModel can be applied as a workaround.
Can you provide example on @ApiModel workaround?
My current issue is the model comes from imported jar library, hence I cannot apply @ApiModel on the class name that needs to be changed.
@arzath, @io.swagger.annotations.ApiModel only supports TYPE targets so you won't be able to use it.
Thanks @seanmmills, do you know if any fix is on its way/projected in the future?
One thing need to mention is: based on the snakeyaml - the max length of a key of a map better not be longer than 128, otherwise snakeyaml will generate a VALID yaml with complex mapping key which cannot be recognized by swagger editor.
A solution for this issue has been implemented in #2797, check out this comment and related test case, to be able to customize name resolving
https://github.com/swagger-api/swagger-core/issues/2121#issuecomment-285109628
I am aslo facing same issue like @PavelJ as mention in above link ,please do helpful to solve to this issue.
Thank you in advance.
I am attaching files of block of code for reference,please refer it.




Most helpful comment
I have just encountered this behaviour and was really suprised because I would assume that this would be a serious issue. For example I have one User model and have multiple request and response classes for multiple operations with User - each containing only a subset of User's attributes.
For example I have class CreateUserRequest (in one package) annotated with @JsonRootName(value = "user") and another class UpdateUsersStateRequest (may be even in the same package) again with annotation @JsonRootName(value = "user"). Swagger definition has only one of those definitions and ignoring others so basically most of the generated examples which I see in swagger UI are wrong.
I would assume that swagger would have different definition for each REST method, am I missing something? It is extremely important to be able to define same object with different attributes in different API methods.