一、刪除默認plugin
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
TypeResolver resolver = new TypeResolver();
AlternateTypeRule timestampRule = new AlternateTypeRule(resolver.resolve(Timestamp.class), resolver.resolve(Object.class));
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class)) //只顯示添加@Api註解的類
.build()
.alternateTypeRules(timestampRule)
.apiInfo(apiInfo());
removeDefaultPlugin();
return docket;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("xxxxAPI") // 粗標題
.build();
}
/** 去掉默認的PluginRegistry插件 */
@SuppressWarnings("unchecked")
private void removeDefaultPlugin() {
// 從spring容器中獲取swagger插件註冊表
PluginRegistry<OperationBuilderPlugin, DocumentationType> pluginRegistry =
ApplicationContextHelper.getBean("operationBuilderPluginRegistry", PluginRegistry.class);
// 插件集合
List<OperationBuilderPlugin> plugins = pluginRegistry.getPlugins();
// 從spring容器中獲取需要刪除的插件
OperationParameterReader operationParameterReader = ApplicationContextHelper.getBean(OperationParameterReader.class);
// 原plugins集合不能修改,創建新集合,通過反射替換
if (pluginRegistry.contains(operationParameterReader)) {
List<OperationBuilderPlugin> plugins_new = new ArrayList<OperationBuilderPlugin>(plugins);
plugins_new.remove(operationParameterReader);
try {
Field field = PluginRegistrySupport.class.getDeclaredField("plugins");
field.setAccessible(true);
field.set(pluginRegistry, plugins_new);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
以上爲swagger配置類,ApplicationContextHelper是spring容器gong工具類,需要自行實現,以operationBuilderPluginRegistry爲例,刪除默認OperationParameterReader。
二、自定義plugin擴展
網上比較多的就是參數展開的問題,以下是我的解決方案,請根據自己的情況修改
上一步已經將默認的OperationParameterReader插件移除了,自定義OperationParameterReader2和ModelAttributeParameterExpander2類,分別將springfox.documentation.spring.web.readers.operation.OperationParameterReader和springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander的源碼拷進來
OperationParameterReader2修改,將private final ModelAttributeParameterExpander expander;改成private final ModelAttributeParameterExpander2 expander;調用自定義的ModelAttributeParameterExpander2。
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class OperationParameterReader2 implements OperationBuilderPlugin {
private final ModelAttributeParameterExpander2 expander;
@Autowired
private DocumentationPluginsManager pluginsManager;
@Autowired
public OperationParameterReader2(ModelAttributeParameterExpander2 expander) {
this.expander = expander;
}
// 省略
}
ModelAttributeParameterExpander2修改expand方法
public List<Parameter> expand(ExpansionContext context) {
List<Parameter> parameters = newArrayList();
Set<String> beanPropNames = getBeanPropertyNames(context.getParamType().getErasedType());
Iterable<ResolvedField> fields = FluentIterable.from(fieldProvider.in(context.getParamType()))
.filter(onlyBeanProperties(beanPropNames));
// 添加判斷,只展開ApiModelProperty註解且hidden爲false的字段
List<ResolvedField> fields_new = new ArrayList<ResolvedField>();
Iterator<ResolvedField> it = fields.iterator();
while (it.hasNext()) {
ResolvedField resolvedField = it.next();
Field field = resolvedField.getRawMember();
field.setAccessible(true);
ApiModelProperty apiModelProperty = field.getDeclaredAnnotation(ApiModelProperty.class);
if (apiModelProperty!=null && apiModelProperty.hidden()==false) {
fields_new.add(resolvedField);
}
}
// 添加判斷結束
LOG.debug("Expanding parameter type: {}", context.getParamType());
AlternateTypeProvider alternateTypeProvider = context.getDocumentationContext().getAlternateTypeProvider();
FluentIterable<ModelAttributeField> modelAttributes = from(fields_new)
.transform(toModelAttributeField(alternateTypeProvider));
FluentIterable<ModelAttributeField> expendables = modelAttributes.filter(not(simpleType()))
.filter(not(recursiveType(context)));
// 省略
return FluentIterable.from(parameters).filter(not(hiddenParameters())).toList();
}
需要注意的是OperationParameterReader和ModelAttributeParameterExpander都有@Component所以我們自定義的類也需要加入spring掃描。
注:這篇博客的擴展方式太粗暴了,如果有興趣,可以看我另一篇博客