swagger静态文档生成

swagger静态文档生成

有时候给接口文档的时候不能直接给个URL,这可能因为没部署上服务器,亦或是内网的限制.

这时对方需要一个HTML或者是个PDF静态文档,本来想着在swagger网址那里Ctrl+S保存下来发过去就行了,结果这样保存的文档根本不能看.

调研后发现,可以通过springfox-staticdocs组件生成swagger静态文件,然后通过maven组件根据静态文件生成HTML和PDF.

以之前的swagger示例项目来展示.
swagger接入请看 withing

话不多说上代码

首先添加dependency依赖

 <properties>
        <swagger.version>2.6.1</swagger.version>

        <!--生成静态文档所需属性-->
        <start-class>com.f6car.base.Application</start-class>
        <snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
    <asciidoctor.input.directory>${project.basedir}/docs/asciidoc</asciidoctor.input.directory>
        <generated.asciidoc.directory>${project.build.directory}/asciidoc</generated.asciidoc.directory>
        <asciidoctor.html.output.directory>${project.build.directory}/asciidoc/html</asciidoctor.html.output.directory>
        <asciidoctor.pdf.output.directory>${project.build.directory}/asciidoc/pdf</asciidoctor.pdf.output.directory>
    </properties>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-staticdocs</artifactId>
    <version>${swagger.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.restdocs</groupId>
    <artifactId>spring-restdocs-mockmvc</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-test</artifactId>
    <version>2.0.0.RELEASE</version>
    <scope>test</scope>
</dependency>

这里有个坑要注意: swagger.version换成2.6.1了,这是因为springfox-staticdocs这个组件只支持到2.6.1,但不能将其他两个swagger2和swagger-ui版本换成2.8.x或2.7.x,因为springfox-staticdocs生成文档时会调用以前版本的某个函数,更换成新版本会抛出MethodNotFoundException

添加测试用例生成swagger静态文件

@RunWith(SpringRunner.class)
@SpringBootTest
public class SwaggerStaticDocTest {
    @Autowired
    private WebApplicationContext context;
    private String snippetDir = "target/generated-snippets";
    private String outputDir = "target/asciidoc";

    private MockMvc mockMvc;

    @Before
    public void setUp() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
    }

    @Test
    public void Test() throws Exception {
        mockMvc.perform(get("/v2/api-docs").accept(MediaType.APPLICATION_JSON))
                .andDo(SwaggerResultHandler.outputDirectory(outputDir).build())
                .andExpect(status().isOk())
                .andReturn();


        Swagger2MarkupConverter.from(outputDir + "/swagger.json")
                .withMarkupLanguage(MarkupLanguage.ASCIIDOC)
                .withExamples(snippetDir)
                .build()
                .intoFolder(outputDir);
    }
}

添加maven 插件生成静态文档

 <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.asciidoctor</groupId>
                <artifactId>asciidoctor-maven-plugin</artifactId>
                <version>1.5.3</version>

                <dependencies>
                    <dependency>
                        <groupId>org.asciidoctor</groupId>
                        <artifactId>asciidoctorj-pdf</artifactId>
                        <version>1.5.0-alpha.14</version>
                    </dependency>

                    <dependency>
                        <groupId>org.jruby</groupId>
                        <artifactId>jruby-complete</artifactId>
                        <version>1.7.21</version>
                    </dependency>
                </dependencies>

                <configuration>
                    <sourceDirectory>${asciidoctor.input.directory}</sourceDirectory>
                    <sourceDocumentName>index.adoc</sourceDocumentName>
                    <attributes>
                        <doctype>book</doctype>
                        <toc>left</toc>
                        <toclevels>3</toclevels>
                        <numbered></numbered>
                        <hardbreaks></hardbreaks>
                        <sectlinks></sectlinks>
                        <sectanchors></sectanchors>
                        <generated>${generated.asciidoc.directory}</generated>
                    </attributes>
                </configuration>

                <executions>
                    <execution>
                        <id>output-html</id>
                        <phase>test</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>html5</backend>
                            <outputDirectory>${asciidoctor.html.output.directory}</outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>output-pdf</id>
                        <phase>test</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>pdf</backend>
                            <outputDirectory>${asciidoctor.pdf.output.directory}</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <finalName>${parent.artifactId}</finalName>
    </build>

配置生成文档的格式

在根目录中添加docs

include::{generated}/overview.adoc[]
include::{generated}/definitions.adoc[]
include::{generated}/paths.adoc[]

目录结构如下:

swagger静态文档生成

运行完后可在target里找到所需的静态文档

swagger静态文档生成

PS (很重要,但选做)

这样的生成方式,pdf的中文显示会不正确,主要原因时使用的默认字体对中文支持不好,可以手动替换字体,但需谨慎,因为字体会随系统不同有差异,导致根本运行不了,这根据个人需求来抉择.字体可以自行替换,能正常使用即可.

在docs里添加字体文件和主题文件

swagger静态文档生成

更改插件配置项

 <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.asciidoctor</groupId>
                <artifactId>asciidoctor-maven-plugin</artifactId>
                <version>1.5.3</version>

                <dependencies>
                    <dependency>
                        <groupId>org.asciidoctor</groupId>
                        <artifactId>asciidoctorj-pdf</artifactId>
                        <version>1.5.0-alpha.14</version>
                    </dependency>

                    <dependency>
                        <groupId>org.jruby</groupId>
                        <artifactId>jruby-complete</artifactId>
                        <version>1.7.21</version>
                    </dependency>
                </dependencies>

                <configuration>
                    <sourceDirectory>${asciidoctor.input.directory}</sourceDirectory>
                    <sourceDocumentName>index.adoc</sourceDocumentName>
                    <attributes>
                        <doctype>book</doctype>
                        <toc>left</toc>
                        <toclevels>3</toclevels>
                        <numbered></numbered>
                        <hardbreaks></hardbreaks>
                        <sectlinks></sectlinks>
                        <sectanchors></sectanchors>
                        <generated>${generated.asciidoc.directory}</generated>
                        <pdf-fontsdir>fonts</pdf-fontsdir>
                        <pdf-stylesdir>themes</pdf-stylesdir>
                        <pdf-style>cn</pdf-style>
                    </attributes>
                </configuration>

                <executions>
                    <execution>
                        <id>output-html</id>
                        <phase>test</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>html5</backend>
                            <outputDirectory>${asciidoctor.html.output.directory}</outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>output-pdf</id>
                        <phase>test</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>pdf</backend>
                            <outputDirectory>${asciidoctor.pdf.output.directory}</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <finalName>${parent.artifactId}</finalName>
    </build>

主要差别在这

                    <pdf-fontsdir>fonts</pdf-fontsdir>
                    <pdf-stylesdir>themes</pdf-stylesdir>
                    <pdf-style>cn</pdf-style>

这样生成的PDF文件就没问题了.

项目github: withing

pdf解决方法在dev分支.