1. 程式人生 > >swagger2使用自定義註解生成文件

swagger2使用自定義註解生成文件

在開發專案中,由於歷史或各種原因(日誌/攔截等)在controller層使用了自定義註解,此時想用swagger2生成api文件時會碰到一個很頭疼的重複說明問題


那怎麼能將@ApiOperation中的value替換為@Explain註解中的value呢~

/**********部分原始碼分析  不想看的直接拉到最後********/

檢視原始碼發現,文件生成控制在springfox.documentation.spring.web.plugins.DocumentationPluginsManager中

operation相關

  @Autowired
  @Qualifier("operationBuilderPluginRegistry")
  private PluginRegistry<OperationBuilderPlugin, DocumentationType> operationBuilderPlugins;

發現注入了OperationBuilderPlugin這個介面的實現類

執行的方法

public Operation operation(OperationContext operationContext) {
    for (OperationBuilderPlugin each : operationBuilderPlugins.getPluginsFor(operationContext.getDocumentationType())) {
      each.apply(operationContext);
    }
    return operationContext.operationBuilder().build();
  }

將執行讀取到的的Bean容器中所有OperationBuilderPlugin實現類的apply方法

官方實現的OperationBuilderPlugin類上都標有@Order(Ordered.HIGHEST_PRECEDENCE)

所以我們只需要實現OperationBuilderPlugin並將Order設定為官方之後即可

/*********原始碼分析結束,以下為解決實現*************/

此示例僅實現以Explain註解中的value值替換@ApiOperation中的value值。若沒有@ApiOperation註解時,將Explain的值存入builder,更多實現邏輯可自己實現。

配置類:

@Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                /**apiInfo**/
                .apiInfo(apiInfo())
                /**useDefaultResponseMessages**/
                .useDefaultResponseMessages(false)
                /**alternateTypeRules**/
                .alternateTypeRules(AlternateTypeRules.newRule(QueryPage.class, QueryPageTemplate.class))
                .alternateTypeRules(AlternateTypeRules.newRule(ResultEntity.class, ResultEntityTemplate.class))
                /**select**/
                .select()
                /**apis**/
                .apis(RequestHandlerSelectors.withMethodAnnotation(Explain.class))
                /**paths**/
                .paths(PathSelectors.any()).build();
    }

僅掃描有Explain註解的方法

替換實現:

import java.util.List;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import io.swagger.annotations.ApiOperation;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spi.service.contexts.OperationContext;
import top.wboost.common.annotation.Explain;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE - 10)
public class ExplainOperationBuilderPlugin2 implements OperationBuilderPlugin {

    @Override
    public void apply(OperationContext context) {
        List<ApiOperation> list = context.findAllAnnotations(ApiOperation.class);
        if (list.size() == 0) {
            List<Explain> explainList = context.findAllAnnotations(Explain.class);
            if (explainList.size() > 0) {
                Explain explain = explainList.get(0);
                context.operationBuilder().summary(explain.value());//替換預設值
            }
        }
    }

    @Override
    public boolean supports(DocumentationType delimiter) {
        return true;
    }

}

如想修改@ApiParam等官方註解的替換及邏輯更改的同理