swagger 从属性文件中读取文档

m.y*_*y.m 2 spring swagger swagger-ui spring-boot openapi


我试图让 Swagger 从属性文件中读取 API 文档,swagger.properties但不能。在@ApiOperation注释中有一个错误说:Attribute value must be constant。有关如何解决此问题并能够从属性文件中读取文档的任何建议?
这是控制器代码:

package com.demo.student.demo.controller;

import com.demo.student.demo.entity.Student;
import com.demo.student.demo.service.StudentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping(value = "/v1/students")
@Api(description = "Set of endpoints for Creating, Retrieving, Updating and Deleting of Students.")
public class StudentController {
    private final String message;

    public StudentController(@Value("${test.swagger.message}") String message){
        this.message=message;
    }

    @Autowired
    private StudentService studentService;

    @GetMapping
    @ApiOperation(message)
    public List<Student> findAll(){
        return studentService.findAl();
    }

}
Run Code Online (Sandbox Code Playgroud)

而且,如何在@API(description) 的类级别注入一个值?

Vla*_*ier 5

有一个解决方法。但是你需要一个额外的依赖 - springfox

您可以编写一个插件,将外部文件中的文本注入到您的@ApiOperation description字段中。我在我的项目中使用它来注入降价文件。它非常方便,因为 Swagger 支持降价,并且为每个端点拥有一个单独的文件为您提供了编写大量 API 描述的机会(如果您使用的是 IntelliJ IDEA 或类似产品,也可以在降价编辑器中)。

这是您需要的代码:

  1. @ApiDescription您要提供描述的每个端点的自定义注释 ( )。注释的值将是 Markdown 或属性文件的文件路径。稍后插件将在提供的文件路径中查找文件并将描述设置为文件的内容。

    @Target({ ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ApiDescription {
        String value() default "";
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 插件本身。它是一个可扩展点。在这种情况下,我们希望@ApiOperation稍后交换或设置注释的描述值。查看Springfox 插件

    ...
    
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spi.service.OperationBuilderPlugin;
    import springfox.documentation.spi.service.contexts.OperationContext;
    import springfox.documentation.spring.web.DescriptionResolver;
    
    ...
    
    @Component
    public class ApiDescriptionPlugin implements OperationBuilderPlugin {
    
        private final DescriptionResolver resolver;
    
        @Autowired
        public ApiDescriptionPlugin(DescriptionResolver resolver) {
            this.resolver = resolver;
        }
    
        @Override
        public void apply(OperationContext context) {
    
            Optional<ApiDescription> descOptional = context.findAnnotation(ApiDescription.class);
            boolean hasText = descOptional.isPresent() && StringUtils.hasText(descOptional.get().value());
            if(!hasText) {
                return;
            }
    
            final String file = descOptional.get().value();
            final URL url = Resources.getResource(file);
    
            String description;
            try {
                description = Resources.toString(url, StandardCharsets.UTF_8);
            } catch(IOException e) {
                log.error("Error while reading markdown description file {}", file, e);
                description = String.format("Markdown file %s not loaded", file);
            }
            context.operationBuilder().notes(resolver.resolve(description));
        }
    
        @Override
        public boolean supports(DocumentationType type) {
            return true;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 只需用@ApiDescription("/notes/auth/login.md")(文件必须在resources文件夹中)注释端点

您可以修改此示例以使用属性文件(我不知道您的结构是什么样子以及如何分离不同的 API 描述)。这种使用降价文件的解决方法对于编写大量描述并使它们远离实际代码很有用。

它适用于Swagger 2.0

试一试。