swagger 从属性文件中读取文档 [英] swagger read documentation from properties file

查看:101
本文介绍了swagger 从属性文件中读取文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


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

package com.demo.student.demo.controller;导入 com.demo.student.demo.entity.Student;导入 com.demo.student.demo.service.StudentService;导入 io.swagger.annotations.Api;导入 io.swagger.annotations.ApiOperation;导入 org.springframework.beans.factory.annotation.Autowired;导入 org.springframework.beans.factory.annotation.Value;导入 org.springframework.web.bind.annotation.*;导入 java.util.List;@RestController@RequestMapping(value = "/v1/students")@Api(description = "用于创建、检索、更新和删除学生的端点集.")公共类学生控制器{私人最终字符串消息;public StudentController(@Value("${test.swagger.message}") String message){this.message=message;}@自动连线私人学生服务 studentService;@GetMapping@ApiOperation(消息)公开名单<学生>找到所有(){返回 studentService.findAl();}}

此外,如何在@API(description) 的类级别注入值?

解决方案

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

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

这是您需要的代码:

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

    @Target({ ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)公共@interface ApiDescription {字符串值()默认";}

  2. 插件本身.它是一个可扩展点.在这种情况下,我们希望稍后交换或设置 @ApiOperation 注释的描述值.查看 Springfox 插件.

    <预><代码>...导入 springfox.documentation.spi.DocumentationType;导入 springfox.documentation.spi.service.OperationBuilderPlugin;导入 springfox.documentation.spi.service.contexts.OperationContext;导入 springfox.documentation.spring.web.DescriptionResolver;...@成分公共类 ApiDescriptionPlugin 实现 OperationBuilderPlugin {私有最终 DescriptionResolver 解析器;@自动连线公共 ApiDescriptionPlugin(DescriptionResolver 解析器){this.resolver = 解析器;}@覆盖公共无效应用(操作上下文上下文){可选的descOptional = context.findAnnotation(ApiDescription.class);boolean hasText = descOptional.isPresent() &&StringUtils.hasText(descOptional.get().value());如果(!hasText){返回;}最终字符串文件 = descOptional.get().value();最终 URL url = Resources.getResource(file);字符串描述;尝试 {description = Resources.toString(url, StandardCharsets.UTF_8);} catch(IOException e) {log.error("读取降价描述文件{}时出错", file, e);description = String.format("Markdown 文件 %s 未加载", file);}context.operationBuilder().notes(resolver.resolve(description));}@覆盖公共布尔支持(文档类型类型){返回真;}}

  3. 简单地用 @ApiDescription("/notes/auth/login.md") 注释端点(文件必须在 resources 文件夹)

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

它适用于 Swagger 2.0.

试试看.


I am trying to get Swagger to read the API documentation from a properties file swagger.properties but can't. In @ApiOperation annotation there is an error saying: Attribute value must be constant. Any suggestions about how to solve this and be able to read the documentation from a properties file?
Here is the Controller code:

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();
    }

}

And also, how can I inject a value at the class level in the @API(description)?

解决方案

There is a workaround. But you need an additional dependency for that - springfox.

You can write a plugin which will inject a text from an external file into you the @ApiOperation description field. I am using it in my project for injecting markdown files. It comes very handy since Swagger supports markdown and having a separate file for each endpoint provides you an opportunity to write extensive API descriptions (also within a markdown editor if you are using IntelliJ IDEA or similar).

Here is the code you need for it:

  1. Custom annotation (@ApiDescription) for each endpoint you want to provide a description. The value of the annotation will be the file path to your markdown or properties file. Later the plugin will look for the file at the provided filepath and set the description to the content of the file.

    @Target({ ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ApiDescription {
        String value() default "";
    }
    

  2. Plugin itself. It is an extensibility point. In this case we want to swap or set the value of description of @ApiOperation annotation later on. Check out the Springfox Plugins.

    ...
    
    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;
        }
    }
    

  3. Simply annotate the endpoints with @ApiDescription("/notes/auth/login.md") (the file must be in resources folder)

You can adapt this example to work with properties file(s) (I don't know how your structure looks like and how you separate different API descriptions). This workaround with markdown files is useful for writing extensive descriptions and keeping them away from the actual code.

It works with Swagger 2.0.

Give it a try.

这篇关于swagger 从属性文件中读取文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆