明白你的意思了,按照你的意思做了一下,篇幅有限,只展示主要代码
自定义注解
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface FormData {
}
覆盖springfox.documentation.spring.web.readers.operation.OperationParameterReader
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class OperationParameterReaderSub extends OperationParameterReader {
private final ModelAttributeParameterExpander expander;
private final EnumTypeDeterminer enumTypeDeterminer;
@Autowired
private DocumentationPluginsManager pluginsManager;
@Autowired
public OperationParameterReaderSub(
ModelAttributeParameterExpander expander,
EnumTypeDeterminer enumTypeDeterminer,
ApplicationContext applicationContext) {
super(expander, enumTypeDeterminer);
this.expander = expander;
this.enumTypeDeterminer = enumTypeDeterminer;
/*
* 删除父类bean定义
* DocumentationPluginsManager中使用ParameterBuilderPlugin类型获取bean,而不是OperationParameterReader类型
* 所以@Primary注解并不能覆盖父类
*/
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
defaultListableBeanFactory.removeBeanDefinition("operationParameterReader");
}
private boolean shouldExpand(final ResolvedMethodParameter parameter, ResolvedType resolvedParamType) {
return !parameter.hasParameterAnnotation(RequestBody.class)
&& !parameter.hasParameterAnnotation(FormData.class) // 加上自定义的注解
&& !parameter.hasParameterAnnotation(RequestPart.class)
&& !parameter.hasParameterAnnotation(RequestParam.class)
&& !parameter.hasParameterAnnotation(PathVariable.class)
&& !isBaseType(typeNameFor(resolvedParamType.getErasedType()))
&& !enumTypeDeterminer.isEnum(resolvedParamType.getErasedType())
&& !isContainerType(resolvedParamType)
&& !isMapType(resolvedParamType);
}
// 其他省略,直接从父类复制
}
覆盖springfox.documentation.spring.web.readers.operation.OperationModelsProvider
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class OperationModelsProviderSub extends OperationModelsProvider {
private static final Logger LOG = LoggerFactory.getLogger(OperationModelsProvider.class);
private final TypeResolver typeResolver;
@Autowired
public OperationModelsProviderSub(TypeResolver typeResolver, ApplicationContext applicationContext) {
super(typeResolver);
this.typeResolver = typeResolver;
/*
* 删除父类bean定义
* DocumentationPluginsManager中使用OperationModelsProviderPlugin类型获取bean,而不是OperationModelsProvider类型
* 所以@Primary注解并不能覆盖父类
*/
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
defaultListableBeanFactory.removeBeanDefinition("operationModelsProvider");
}
private void collectParameters(RequestMappingContext context) {
LOG.debug("Reading parameters models for handlerMethod |{}|", context.getName());
List<ResolvedMethodParameter> parameterTypes = context.getParameters();
for (ResolvedMethodParameter parameterType : parameterTypes) {
if (parameterType.hasParameterAnnotation(RequestBody.class)
|| parameterType.hasParameterAnnotation(FormData.class) // 加上自定义的注解
|| parameterType.hasParameterAnnotation(RequestPart.class)) {
ResolvedType modelType = context.alternateFor(parameterType.getParameterType());
LOG.debug("Adding input parameter of type {}", resolvedTypeSignature(modelType).or("<null>"));
context.operationModelsBuilder().addInputParam(modelType);
}
}
LOG.debug("Finished reading parameters models for handlerMethod |{}|", context.getName());
}
// 其他省略,直接从父类复制
}
示例controller
像使用RequestBody一样使用FromData,只变文档,没有其他副作用
@GetMapping
@ApiOperation(value = "测试")
public String test(@FormData User user) {
System.out.println(user);
return "随便返回点什么";
}