如何将文件内容传递给@ExampleProperty批注值?

时间:2019-04-26 14:38:45

标签: java swagger swagger-ui swagger-2.0

我正在使用swagger 3.0.0-Snapshot为我的Spring Boot应用程序创建文档。 我的Maven依赖项是

<dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>3.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>3.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-spring-webmvc</artifactId>
            <version>3.0.0-SNAPSHOT</version>
        </dependency>

我的swagger配置类尽可能简单:

@Configuration
@EnableSwagger2WebMvc
public class SwaggerConfig {
    @Bean
    public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
                .useDefaultResponseMessages(false)
                .select()
         .apis(RequestHandlerSelectors.basePackage("com.mycompany.cs"))
                .paths(PathSelectors.any())
                .build()
                .pathMapping("/")
                .useDefaultResponseMessages(false);
    }

我的控制器方法具有以下注释:

@ApiOperation(value = "Hello world", httpMethod = "POST")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "OK",
                    examples = @Example(value = @ExampleProperty(mediaType = "application/json",
                            value = exampleValue)))
    })

它正在运行,并且在Swagger UI中显示了具有常量字符串exampleValue的字段“ Example Value”字段值,该字符串是私有静态String。

问题是如何将资源文件夹中json文件的内容传递给@ExampleProperty值?

我试图读取静态块中的文件内容,并将其传递给它来初始化最终的String,但是编译器说“属性值必须恒定”。

必须在Swagger UI的示例字段中显示json文件的内容。

1 个答案:

答案 0 :(得分:0)

好消息是Swagger正在使用Spring,并且可以使用DI的功能。

例如,您想向ServiceModelToSwagger2MapperImpl添加新功能。创建自己的扩展组件并将其标记为主要。 Spring将自动连接ServiceModelToSwagger2Mapper抽象类的实现。

class Context:
    # Stack of current contexts entered; stored as a class attribute
    stack = []

    def __init__(self, name):
        self.name = name
        self.vars = {}

    def __enter__(self):
        # Put self on the stack.
        Context.stack.append(self)
        return self

    def __exit__(self, et, ev, tb):
        # Ensure we're popping ourselves off the stack.
        assert Context.stack[-1] is self
        # Remove self.
        Context.stack.pop(-1)

    def register(self, var):
        # Register a `Var` in self...
        self.vars[var.name] = var
        # ... and set its Context.
        var.context = self

    @staticmethod
    def get_current():
        # Get the topmost Context if any.
        return Context.stack[-1] if Context.stack else None

    def __repr__(self):
        return "<Context %r with %d vars>" % (self.name, len(self.vars))


class Var:
    def __init__(self, name):
        self.context = None
        self.name = name

        # Register ourselves in the current context, if any.
        ctx = Context.get_current()
        if ctx:
            ctx.register(self)

    def __repr__(self):
        return "<%s (in %s)>" % (self.name, self.context)


with Context("spam") as c:
    v = Var("foo")
    x = Var("bar")

print(c.vars)

例如,您希望它读取文件的内容并将其放在示例字段中:

@Component
@Primary
@Slf4j
public class ServiceModelToSwagger2MapperExtensionImpl extends ServiceModelToSwagger2MapperImpl {

这是控制器中用法的示例:

@Override
protected Map<String, Response> mapResponseMessages(Set<ResponseMessage> from) {
    Map<String, Response> responses = super.mapResponseMessages(from);
    responses.forEach((key, response)-> {
        Map<String, Object> examples = response.getExamples();
        examples.entrySet().forEach(example -> {
            Object exampleObject = example.getValue();
            if (exampleObject instanceof String) {
                String exampleValue = (String) exampleObject;
                if (exampleValue.startsWith("file:")) {
                    String fileContent = readFileContent(exampleValue);
                    example.setValue(fileContent);
                }
            }});
    });

    return responses;
}

private String readFileContent(String example) {
    String fileContent = "";
    try {
        String fileName = example.replace("file:", "");
        File resource = new ClassPathResource(fileName).getFile();
        if(resource.exists()) {
            fileContent
                    = new String(Files.readAllBytes(resource.toPath()));
        }
    } catch (
            IOException e) {
        log.error("Cannot read swagger documentation from file {}", example);
    }
    return fileContent;
}