我使用springfox 2.0配置了我的spring项目。我可以用它生成open api规范。
"paths": {
"/test/testinfo": {
"post": {
"tags": [
"test-controller"
],
"summary": "getTestInfo",
"operationId": "getTestInfoInfoUsingGET",
"consumes": [
"application/json"
],
"produces": [
"application/json"
]
正如您所看到的,operationId的值是格式
[java_method_name_here]Using[HTTP_verb_here]
离。 getPetsUsingGET
使用swagger-codegen生成客户端时使用此operationId。
有谁知道如何定制它?我知道这可以使用@ApiOperation
按api完成,但有没有更通用的方法来为所有api定义这种格式?
答案 0 :(得分:4)
你可以create your own plugin来做。以下是an example我们如何在springfox中使用相同的插件技术。
@Component
@Order(YOUR_PLUGIN_ORDER) // > Ordered.HIGHEST_PRECEDENCE + 1000
public class OperationNicknameIntoUniqueIdReader implements OperationBuilderPlugin {
@Override
public void apply(OperationContext context) {
//Create your own transformation to format the name in the way
//that you prefer
String operationNameStem = transformName(context.getName());
//Update the method name stem that is used to generate a unique id
context.operationBuilder().codegenMethodNameStem(operationNameStem);
}
...
}
注意:无论您提出什么干扰,springfox都会确保它在所有API中都是唯一的。因此,如果您有一个重复的命名方法,它将在您的唯一名称末尾开始编号方案。例如如果getCustomer
不唯一,则会生成唯一ID getCustomer_1
等。
答案 1 :(得分:0)
以下是删除“使用” + VERB的完整示例:
它与:
import com.google.common.base.Optional;
import io.swagger.annotations.ApiOperation;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import springfox.documentation.service.Operation;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spi.service.contexts.OperationContext;
import springfox.documentation.swagger.common.SwaggerPluginSupport;
@Component
@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
public class IncludeMissingNicknameIntoUniqueIdReader implements OperationBuilderPlugin
{
@Override
public void apply(OperationContext context)
{
Optional<ApiOperation> methodAnnotation = context.findControllerAnnotation(ApiOperation.class);
Operation operationBuilder = context.operationBuilder().build();
String uniqueId = operationBuilder.getUniqueId().replaceAll("Using(GET|POST|PUT|DELETE)", "");
if (methodAnnotation.isPresent())
{
ApiOperation operation = methodAnnotation.get();
if (MiscUtils.isNotEmpty(operation.nickname()))
{
// Populate the value of nickname annotation into uniqueId
context.operationBuilder().uniqueId(operation.nickname());
context.operationBuilder().codegenMethodNameStem(operation.nickname());
}
else
{
context.operationBuilder().uniqueId(uniqueId);
context.operationBuilder().codegenMethodNameStem(uniqueId);
}
}
else
{
context.operationBuilder().uniqueId(uniqueId);
context.operationBuilder().codegenMethodNameStem(uniqueId);
}
}
@Override
public boolean supports(DocumentationType delimiter)
{
return SwaggerPluginSupport.pluginDoesApply(delimiter);
}
}
答案 2 :(得分:0)
我们还可以使用昵称的这种方法来覆盖默认的operationId。
@ApiOperation(value = "", nickname = "getMeAllThePetsPlease")
@RequestMapping(value = "/pets", method = RequestMethod.GET)
public Model getAllThePets() {
...
}
所以我们将使用 getMeAllThePetsPlease 覆盖 operationId:getAllThePetsByGet 。
注意:昵称将覆盖operationId,因此可以相应地对其进行自定义。
答案 3 :(得分:0)
基于@bdzzaid的代码的较短和清晰的版本:
MAP_KEY_VALUE
答案 4 :(得分:0)
这不需要额外的依赖,也很容易自定义命名。 (改进here)
app/api/src/main/java/com/observatory/api/config/SwaggerIncludeMissingNicknameIntoUniqueIdReader.java
package com.observatory.api.config;
import com.google.common.base.Optional;
import io.swagger.annotations.ApiOperation;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import springfox.documentation.service.Operation;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spi.service.contexts.OperationContext;
import springfox.documentation.swagger.common.SwaggerPluginSupport;
import java.util.Locale;
@Component
@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
public class SwaggerIncludeMissingNicknameIntoUniqueIdReader implements OperationBuilderPlugin {
@Override
public void apply(OperationContext context) {
Optional<ApiOperation> methodAnnotation = context.findControllerAnnotation(ApiOperation.class);
Operation operationBuilder = context.operationBuilder().build();
String uniqueId = operationBuilder.getUniqueId();
if(operationBuilder.getTags().stream().findFirst().get().isEmpty())
throw new RuntimeException("operationBuilder.getTags().stream().findFirst()");
uniqueId = uniqueId.substring(0,1).toUpperCase(Locale.ROOT)+ uniqueId.substring(1);
uniqueId = uniqueId.replaceAll("[_].+","");
String tag = operationBuilder.getTags().stream().findFirst().get();
tag = tag.replace("-controller","s");
int index = tag.indexOf("-");
while (index >= 0) {
tag = tag.substring(0,index) + tag.substring(index+1,index+2).toUpperCase(Locale.ROOT)+ tag.substring(index+2);
index = tag.indexOf("-");
}
uniqueId = tag + uniqueId;
// If nickname exists, populate the value of nickname annotation into uniqueId
String fillId = methodAnnotation.transform(ApiOperation::nickname).or(uniqueId);
context.operationBuilder().uniqueId(fillId);
context.operationBuilder().codegenMethodNameStem(fillId);
}
@Override
public boolean supports(DocumentationType delimiter) {
return SwaggerPluginSupport.pluginDoesApply(delimiter);
}
}