Preface
springfox-swagger2@2.9.2
version used by the project
To integrate the swagger document function in Spring, you need to @ApiModel
parameter classes with the 061109a42c6374 annotation, but if there are two classes with the same name under two different packages that use the @ApiModel
annotation, the document will be overwritten, for example:
- com.example.demo.login.dto.UserDTO
package com.example.demo.login.dto;
@Data
@ApiModel
public class UserDTO{
@ApiModelProperty("姓名")
private String name;
@ApiModelProperty("年龄")
private Integer age;
}
- com.example.demo.vip.dto.UserDTO
package com.example.demo.vip.dto;
@Data
@ApiModel
public class UserDTO{
@ApiModelProperty("姓名")
private String name;
@ApiModelProperty("会员级别")
private Integer vipLevel;
}
The documents generated by the above two classes will become a swagger model
:
As a result, the interface document displays an error:
Conflict resolution
Modify @ApiModel annotation (recommended)
By modifying the value attribute of @ApiModel to avoid conflicts with the same name, after the modification is:
package com.example.demo.login.dto;
@Data
@ApiModel("login$UserDTO")
public class UserDTO{}
package com.example.demo.vip.dto;
@Data
@ApiModel("vip$UserDTO")
public class UserDTO{}
You can see that two swagger model
generated:
Modify the class name
Modify the two class names so that the class names do not conflict.
Custom swagger plugin
However, the above method of resolving conflicts is still too cumbersome. It is only necessary to define the entry and exit parameters of a document, and the problem of the same class name should also be considered. This kind of problem of increasing mental burden and workload should be avoided as much as possible. I am thinking about it. It is impossible to add @ApiModel
annotations to each class, and all the remaining conflict issues do not need to be considered.
So by tracking the source code, I found the swagger model
was generated, see: github
Logical name can be seen that, taking a priority @ApiModel
the value
value will be used if no defaultTypeName
, into a look now, defaultTypeName
is direct access class abbreviated, as follows:
It is taken as default class
short, resulting in the same name as the class name generated out of different packages
swagger model
covered.
The reason has been out of the analysis, the next is to see if you can actually customize this super.nameFor(type)
method, however unfortunately this is to write dead, no place to start, but ApiModelTypeNameProvider
this class two notes @Component
and @Order
have expressed this It is a Spring bean
, and it is Spring plug-in mechanism, so you can customize a plug-in to complete it. By default, the unique
swagger model
is generated by the complete class path and class name. The code is as follows:
@Component
@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER - 100)
public class FullPathTypeNameProvider extends DefaultTypeNameProvider {
public static final String SPLIT_CHAR = "$";
@Override
public String nameFor(Class<?> type) {
ApiModel annotation = AnnotationUtils.findAnnotation(type, ApiModel.class);
if (annotation == null) {
return super.nameFor(type);
}
if (StringUtils.hasText(annotation.value())) {
return annotation.value();
}
// 如果@ApiModel的value为空,则默认取完整类路径
int packagePathLength = type.getPackage().getName().length();
return Stream.of(type.getPackage().getName().split("\\."))
.map(path -> path.substring(0, 1))
.collect(Collectors.joining(SPLIT_CHAR))
+ SPLIT_CHAR
+ type.getName().substring(packagePathLength + 1);
}
}
The effect is as follows:
postscript
postscript
Through this small optimization, unnecessary communication costs in many teams can be reduced, allowing us to focus more on business development.
I’m MonkeyWie , welcome to scan the code 👇👇 follow! From time to time, share the knowledge of dry goods such as JAVA
, Golang
, front end, docker
, k8s
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。