2017-05-30 49 views
1

在我的Spring(4.3.2)項目中,我使用Swagger(2.7.0)爲我的項目自動生成文檔和swagger-ui。迄今爲止這很有效。如何確認swagger來處理自定義Controller級別的PathVariable註釋?

但是現在我確定我需要能夠在控制器級別(而不是方法級別)聲明路徑變量。我需要教大家發現這些路徑變量並將它們添加到文檔和swagger-ui中。

我創建定製標註

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface HasCommonPathVariable { 
    /** 
    * The URI template variable to bind to. 
    */ 
    String name(); 
    Class<?> type(); 
    String defaultValue() default ""; 
} 

而我使用它是這樣的:

@RestController 
@Secured(SecurityConstants.ROLE_USER) 
@RequestMapping(path = "/rest/api/v1/env/{envId}/asset-type") 
@HasCommonPathVariable(name = "envId", type = Long.class) 
public class AssetTypeRestController extends CustomRestControllerBase<Long, AssetTypeRow, AssetTypeService> { 
// ... contorller code 
} 

我沒有與Spring的PathVariable註釋中提到的參數控制方法,和點我不允許這麼做(這是因爲我正在構建微觀框架)。

所以問題是:如何教大搖大擺發現路徑變量描述使用自定義註釋HasCommonPathVariable在控制器級應用?

回答

0

好的,我已經知道了。這是解決方案。這個bean需要在上下文中註冊。 Swagger會發現這個豆,並將其用作豐富操作的插件之一。

import java.util.ArrayList; 
import java.util.List; 
import org.apache.log4j.Logger; 
import org.springframework.core.annotation.Order; 
import com.fasterxml.classmate.TypeResolver; 
import com.google.common.base.Optional; 
import springfox.documentation.builders.ParameterBuilder; 
import springfox.documentation.schema.ModelRef; 
import springfox.documentation.service.Parameter; 
import springfox.documentation.spi.DocumentationType; 
import springfox.documentation.spi.service.OperationBuilderPlugin; 
import springfox.documentation.spi.service.contexts.OperationContext; 
import springfox.documentation.swagger.common.SwaggerPluginSupport; 

@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000) 
public class CommonPathVariableOperationBuilderPlugin implements OperationBuilderPlugin { 
    protected Logger log = Logger.getLogger(getClass()); 

    private TypeResolver typeResolver; 

    public CommonPathVariableOperationBuilderPlugin(TypeResolver typeResolver) { 
     this.typeResolver = typeResolver; 
    } 

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

    @Override 
    public void apply(OperationContext opCtx) { 
     List<Parameter> ret = new ArrayList<Parameter>(); 
     Optional<HasCommonPathVariable> annSingle = opCtx.findControllerAnnotation(HasCommonPathVariable.class); 
     if (annSingle.isPresent()) { 
      ret.add(addParameter(annSingle.get())); 
     } 

     Optional<HasCommonPathVariables> annPlural = opCtx.findControllerAnnotation(HasCommonPathVariables.class); 
     if (annPlural.isPresent()) { 
      for (HasCommonPathVariable ann : annPlural.get().value()) { 
       ret.add(addParameter(ann)); 
      } 
     } 
     opCtx.operationBuilder().parameters(ret); 
    } 

    private Parameter addParameter(HasCommonPathVariable ann) { 
     ParameterBuilder pb = new ParameterBuilder(); 
     pb.parameterType("path").name(ann.name()).type(typeResolver.resolve(ann.type())); 
     pb.modelRef(new ModelRef("string")); 
     pb.required(true); 
     if (!"".equals(ann.defaultValue())) { 
      pb.defaultValue(ann.defaultValue()); 
     } 
     return pb.build(); 
    } 
} 
相關問題