将Swagger导出HTML、PDF和MARKDOWN的一些心得
2018-03-12 11:26
741 查看
首先,我的项目是SpringBoot1.3.2+Spring4.2.3+JaveSE1.7+JUNIT4
之前也不会,就在网上找了一些教程,但是到我的实际项目中,都会有问题,今天只是记录下都需要怎么样去实现与出现的一些问题
Swagger的配置import static com.google.common.base.Predicates.or;
import static springfox.documentation.builders.PathSelectors.regex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StopWatch;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
private final Logger log = LoggerFactory.getLogger(SwaggerConfiguration.class);
@Bean
public Docket engineDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("ENGINE_API").apiInfo(cmApiInfo()).select()
.paths(or(regex("/ops/v1/execEngine.*"), regex("/ops/v1/exec/executor.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@Bean
public Docket cmDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2).groupName("CM_API")
.apiInfo(cmApiInfo()).select().paths(or(regex("/conf/v1/.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@Bean
public Docket opDefinitionkDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("OpDefinition_API").apiInfo(opDefApiInfo()).select()
.paths(or(regex("/ops/v1/opdefinition.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@Bean
public Docket opJobDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("OpJob_API").apiInfo(opJobApiInfo()).select()
.paths(or(regex("/ops/v1/opjob.*"), regex("/ops/v1/plan.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@SuppressWarnings("unchecked")
@Bean
public Docket dashboardDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("Dashboard_API").apiInfo(dashboradApiInfo()).select()
.paths(or(regex("/cm/v1/dashboard.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@SuppressWarnings("unchecked")
@Bean
public Docket inspectDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("Inspect_API").apiInfo(inspectApiInfo()).select()
.paths(or(regex("/inspect/v1/.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@SuppressWarnings("unchecked")
@Bean
public Docket sysMgtDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("SysMgt_API").apiInfo(opLogApiInfo()).select()
.paths(or(regex("/ops/v1/oplog.*"), regex("/cms/v1/sys/dept.*"),
regex("/cms/v1/sys/account.*"), regex("/cms/v1/sys/role.*"), regex("/cms/v1/login"),
regex("/cms/v1/logout"), regex("/cms/v1/sys/permission.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
private ApiInfo cmApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
private ApiInfo opDefApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
private ApiInfo opJobApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
private ApiInfo dashboradApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
private ApiInfo opLogApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
private ApiInfo inspectApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
}
注意:强调一下,这里面我们用了Swagger分组的方式,也就是上面的groupName内容,这个
pom.xml配置
生成HTML和PDF的测试类import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import com.idcos.cms.server.CloudConfServer;
import io.github.robwin.markup.builder.MarkupLanguage;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import springfox.documentation.staticdocs.SwaggerResultHandler;
@AutoConfigureMockMvc
@AutoConfigureRestDocs(outputDir = "target/generated-snippets")
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)//工程的启动类
public class SwaggerToHTMLandPDFTest {
private String snippetDir = "target/generated-snippets";
private String swaggerOutput = "src/asciidoc";
private String adocDir = "docs/asciidoc/src/asciidoc";
@Autowired
private MockMvc mockMvc;
@Test
public void Test() throws Exception {
// 得到swagger.json,写入outputDir目录中
mockMvc.perform(get("/v2/api-docs?group=SysMgt_API").accept(MediaType.APPLICATION_JSON))
.andDo(SwaggerResultHandler.outputDirectory(swaggerOutput).build())
.andExpect(status().isOk())
.andReturn();
// 读取上一步生成的swagger.json转成asciiDoc,写入到outputDir
Swagger2MarkupConverter.from(swaggerOutput + "/swagger.json")
.withMarkupLanguage(MarkupLanguage.ASCIIDOC)// 格式
.withExamples(snippetDir)
.build()
.intoFolder(adocDir);// 输出
}
}生成MARKDOWN的测试类import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.nio.file.Paths;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import com.idcos.cms.server.CloudConfServer;
import io.github.swagger2markup.GroupBy;
import io.github.swagger2markup.Language;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import springfox.documentation.staticdocs.SwaggerResultHandler;
@AutoConfigureMockMvc
@AutoConfigureRestDocs(outputDir = "src/asciidoc")
@RunWith(SpringRunner.class)
@SpringBootTest(classes = CloudConfServer.class)
public class SwaggerToMarkdownTest {
private String outputDir = "src/asciidoc";
@Autowired
private MockMvc mockMvc;
//生成markdowd文档
@Test
public void Test1() throws Exception{
// 得到swagger.json,写入outputDir目录中
mockMvc.perform(get("/v2/api-docs?group=SysMgt_API").accept(MediaType.APPLICATION_JSON))
.andDo(SwaggerResultHandler.outputDirectory(outputDir).build())
.andExpect(status().isOk())
.andReturn();
//生成markdown的配置
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.build();
//获取swagger.json文件,输出到outputDir中
Swagger2MarkupConverter converter = Swagger2MarkupConverter.from(Paths.get("src/asciidoc/swagger.json")).withConfig(config).build();
converter.toFile(Paths.get(outputDir));
}
}注意:在上面的mockMvc获取swagger.json文件的地址中,加入了group的查询参数,我之前在网上搜索的教程中,只有一个说了这个问题,但是也不是很清楚,导致我获取json文件很长时间。如果在swagger的配置中(看上面的SwaggerConfigration),进行了分组,在获取swagger.json的时候,就需要加上group这个参数,如果没有分组,就不用加
顺便提一下,如果你学过swagger,swagger的访问地址http://localhost:8080/swagger-ui.html,就可以看到接口的所有信息,并且进行测试,还有一个地址http://localhost:8080/v2/api-docs,打开这个地址,页面就显示一堆数据,就是swagger.json文件的具体信息,如果分组,还是需要加上group这个参数。
还需要有一个文件index.adocinclude::{generated}/overview.adoc[]
include::{generated}/definitions.adoc[]
include::{generated}/paths.adoc[]当在运行一个测试类之后,会生成swagger.json,测试类的第二个方法,会生成三个文件
这三个文件就是把swagger.json文件进行了处理,为构建html和pdf生成adoc文件
步骤(生成html和pdf):
1.运行第一个测试类,生成swagger.json和三个adoc文件
2.命令行,运行mvn clean test
3.在target/asciidoc下面就会生成html和pdf
生成markdown文件,直接运行第二个测试类
注意:生成pdf的时候,对中文的支持很不好,会缺少文字,由于使用的分组,只能一个个的文档生成
我在构建文档过程中出现的问题
1.升级Springboot(1.3.2升级到1.5.2)
由于我的项目是使用mongo数据库的,配置文件<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd" default-autowire="byName">
<mongo:mongo id="mongo" replica-set="${mongo.replicaSet}" >
<mongo:options connections-per-host="${mongo.connectionsPerHost}"
threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
connect-timeout="${mongo.connectTimeout}" max-wait-time="${mongo.maxWaitTime}"
auto-connect-retry="${mongo.autoConnectRetry}" socket-keep-alive="${mongo.socketKeepAlive}"
socket-timeout="${mongo.socketTimeout}"
write-number="1" write-timeout="0" write-fsync="true" />
</mongo:mongo>
<!-- mongo:db-factory dbname="${mongo.dbname}" mongo-ref="mongo" username="${mongo.username}"
password="${mongo.password}"/>-->
<mongo:db-factory dbname="${mongo.dbname}" mongo-ref="mongo"/>
<!-- <mongo:db-factory dbname="${mongo.dbname}" mongo-ref="mongo"/> -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
<constructor-arg ref="mappingMongoConverter" />
</bean>
<!-- <mongo:mapping-converter id="converter" db-factory-ref="mongoDbFactory"
/> -->
<!-- 默认Mongodb类型映射 -->
<bean id="defaultMongoTypeMapper"
class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
<constructor-arg name="typeKey">
<null /><!-- 这里设置为空,可以把 spring data mongodb 多余保存的_class字段去掉 -->
</constructor-arg>
</bean>
<bean id="mappingContext"
class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
<!-- 转换器:1、去掉write的_class字段 2、TimestampConverter -->
<bean id="mappingMongoConverter"
class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
<constructor-arg name="mappingContext" ref="mappingContext" />
<property name="typeMapper" ref="defaultMongoTypeMapper" />
</bean>
<!-- mongo操作文件的模板 -->
<bean id="gridFsTemplate" class="org.springframework.data.mongodb.gridfs.GridFsTemplate">
<constructor-arg ref="mongoDbFactory" />
<constructor-arg ref="mappingMongoConverter" />
</bean>
</beans>升级了之后,<mongo:mongo>这个element不能使用了,启动的时候导致mongo的bean都不可使用,程序无法启动,目前只能使用<mongo:mongo-client>,具体配置改为<mongo:mongo-client host="localhost" port="27017" id="mongo">
<mongo:client-options socket-keep-alive="${mongo.socketKeepAlive}"
socket-timeout="${mongo.socketTimeout}"
connect-timeout="${mongo.connectTimeout}"
max-wait-time="${mongo.maxWaitTime}"
threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
connections-per-host="${mongo.connectionsPerHost}"
/>
</mongo:mongo-client>其他的不用动
2.swagger-models的jar包出问题
之前这个jar包是不需要在pom.xml文件中引用的,是springfox.swagger2的包引用的,但是在运行第二个测试类的时候,有一个枚举类总是缺少元素,只能把这个包升级,在pom.xml中添加<dependency> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> <version>1.5.18</version> </dependency>
解决此问题
最后在强调一下,在测试的过程中,会有一些文件路径的问题,这个只能具体测试的时候,去解决了
特此感谢 http://blog.csdn.net/fly910905/article/details/79131755#comments
之前也不会,就在网上找了一些教程,但是到我的实际项目中,都会有问题,今天只是记录下都需要怎么样去实现与出现的一些问题
Swagger的配置import static com.google.common.base.Predicates.or;
import static springfox.documentation.builders.PathSelectors.regex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StopWatch;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
private final Logger log = LoggerFactory.getLogger(SwaggerConfiguration.class);
@Bean
public Docket engineDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("ENGINE_API").apiInfo(cmApiInfo()).select()
.paths(or(regex("/ops/v1/execEngine.*"), regex("/ops/v1/exec/executor.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@Bean
public Docket cmDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2).groupName("CM_API")
.apiInfo(cmApiInfo()).select().paths(or(regex("/conf/v1/.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@Bean
public Docket opDefinitionkDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("OpDefinition_API").apiInfo(opDefApiInfo()).select()
.paths(or(regex("/ops/v1/opdefinition.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@Bean
public Docket opJobDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("OpJob_API").apiInfo(opJobApiInfo()).select()
.paths(or(regex("/ops/v1/opjob.*"), regex("/ops/v1/plan.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@SuppressWarnings("unchecked")
@Bean
public Docket dashboardDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("Dashboard_API").apiInfo(dashboradApiInfo()).select()
.paths(or(regex("/cm/v1/dashboard.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@SuppressWarnings("unchecked")
@Bean
public Docket inspectDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("Inspect_API").apiInfo(inspectApiInfo()).select()
.paths(or(regex("/inspect/v1/.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
@SuppressWarnings("unchecked")
@Bean
public Docket sysMgtDocket() {
Docket swaggerSpringMvcPlugin = new Docket(DocumentationType.SWAGGER_2)
.groupName("SysMgt_API").apiInfo(opLogApiInfo()).select()
.paths(or(regex("/ops/v1/oplog.*"), regex("/cms/v1/sys/dept.*"),
regex("/cms/v1/sys/account.*"), regex("/cms/v1/sys/role.*"), regex("/cms/v1/login"),
regex("/cms/v1/logout"), regex("/cms/v1/sys/permission.*"))) // and by paths
.build();
return swaggerSpringMvcPlugin;
}
private ApiInfo cmApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
private ApiInfo opDefApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
private ApiInfo opJobApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
private ApiInfo dashboradApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
private ApiInfo opLogApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
private ApiInfo inspectApiInfo() {
return new ApiInfoBuilder()
.title("此分组的具体信息")
.description("描述信息")
.version("1.0")
.contact(new Contact("公司名称", "公司主页地址", "联系人邮件"))
.build();
}
}
注意:强调一下,这里面我们用了Swagger分组的方式,也就是上面的groupName内容,这个
pom.xml配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.chinamobile.iot</groupId> <artifactId>restdocs</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <properties> <snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory> <asciidoctor.input.directory>${project.basedir}/docs/asciidoc</asciidoctor.input.directory> <generated.asciidoc.directory>src/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> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.8</version> </dependency> <!--WEB层--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--测试--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <!--Swagger2--> <!--在线文档--> <!--swagger本身不支持spring mvc的,springfox把swagger包装了一下,让他可以支持springmvc--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.6.1</version> </dependency> <!--离线文档--> <dependency> <groupId>org.springframework.restdocs</groupId> <artifactId>spring-restdocs-mockmvc</artifactId> <version>1.1.2.RELEASE</version> <scope>test</scope> </dependency> <!--springfox-staticdocs 生成静态文档--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-staticdocs</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>io.github.swagger2markup</groupId> <artifactId>swagger2markup</artifactId> <version>1.3.2</version> </dependency> </dependencies> <build> <plugins> <!--<plugin> <groupId>org.springframework.boot</groupId> ca88 <artifactId>spring-boot-maven-plugin</artifactId> </plugin>--> <!--Maven通过Maven Surefire Plugin插件执行单元测试--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> </plugin> <!-- Run the generated asciidoc through Asciidoctor to generate other documentation types, such as PDFs or HTML5 --> <!--通过Asciidoctor使得asciidoc生成其他的文档格式,例如:PDF 或者HTML5--> <plugin> <groupId>org.asciidoctor</groupId> <artifactId>asciidoctor-maven-plugin</artifactId> <version>1.5.3</version> <!-- Include Asciidoctor PDF for pdf generation --> <!--生成PDF--> <dependencies> <dependency> <groupId>org.asciidoctor</groupId> <artifactId>asciidoctorj-pdf</artifactId> <version>1.5.0-alpha.14</version> </dependency> <!-- Comment this section to use the default jruby artifact provided by the plugin --> <dependency> <groupId>org.jruby</groupId> <artifactId>jruby-complete</artifactId> <version>1.7.21</version> </dependency> </dependencies> <!-- Configure generic document generation settings --> <!--文档生成配置--> <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> <!-- Since each execution can only handle one backend, run separate executions for each desired output type --> <!--因为每次执行只能处理一个后端,所以对于每个想要的输出类型,都是独立分开执行--> <executions> <!--html5--> <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> <!--pdf--> <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> </build> </project>
生成HTML和PDF的测试类import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import com.idcos.cms.server.CloudConfServer;
import io.github.robwin.markup.builder.MarkupLanguage;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import springfox.documentation.staticdocs.SwaggerResultHandler;
@AutoConfigureMockMvc
@AutoConfigureRestDocs(outputDir = "target/generated-snippets")
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)//工程的启动类
public class SwaggerToHTMLandPDFTest {
private String snippetDir = "target/generated-snippets";
private String swaggerOutput = "src/asciidoc";
private String adocDir = "docs/asciidoc/src/asciidoc";
@Autowired
private MockMvc mockMvc;
@Test
public void Test() throws Exception {
// 得到swagger.json,写入outputDir目录中
mockMvc.perform(get("/v2/api-docs?group=SysMgt_API").accept(MediaType.APPLICATION_JSON))
.andDo(SwaggerResultHandler.outputDirectory(swaggerOutput).build())
.andExpect(status().isOk())
.andReturn();
// 读取上一步生成的swagger.json转成asciiDoc,写入到outputDir
Swagger2MarkupConverter.from(swaggerOutput + "/swagger.json")
.withMarkupLanguage(MarkupLanguage.ASCIIDOC)// 格式
.withExamples(snippetDir)
.build()
.intoFolder(adocDir);// 输出
}
}生成MARKDOWN的测试类import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.nio.file.Paths;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import com.idcos.cms.server.CloudConfServer;
import io.github.swagger2markup.GroupBy;
import io.github.swagger2markup.Language;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import springfox.documentation.staticdocs.SwaggerResultHandler;
@AutoConfigureMockMvc
@AutoConfigureRestDocs(outputDir = "src/asciidoc")
@RunWith(SpringRunner.class)
@SpringBootTest(classes = CloudConfServer.class)
public class SwaggerToMarkdownTest {
private String outputDir = "src/asciidoc";
@Autowired
private MockMvc mockMvc;
//生成markdowd文档
@Test
public void Test1() throws Exception{
// 得到swagger.json,写入outputDir目录中
mockMvc.perform(get("/v2/api-docs?group=SysMgt_API").accept(MediaType.APPLICATION_JSON))
.andDo(SwaggerResultHandler.outputDirectory(outputDir).build())
.andExpect(status().isOk())
.andReturn();
//生成markdown的配置
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.build();
//获取swagger.json文件,输出到outputDir中
Swagger2MarkupConverter converter = Swagger2MarkupConverter.from(Paths.get("src/asciidoc/swagger.json")).withConfig(config).build();
converter.toFile(Paths.get(outputDir));
}
}注意:在上面的mockMvc获取swagger.json文件的地址中,加入了group的查询参数,我之前在网上搜索的教程中,只有一个说了这个问题,但是也不是很清楚,导致我获取json文件很长时间。如果在swagger的配置中(看上面的SwaggerConfigration),进行了分组,在获取swagger.json的时候,就需要加上group这个参数,如果没有分组,就不用加
顺便提一下,如果你学过swagger,swagger的访问地址http://localhost:8080/swagger-ui.html,就可以看到接口的所有信息,并且进行测试,还有一个地址http://localhost:8080/v2/api-docs,打开这个地址,页面就显示一堆数据,就是swagger.json文件的具体信息,如果分组,还是需要加上group这个参数。
还需要有一个文件index.adocinclude::{generated}/overview.adoc[]
include::{generated}/definitions.adoc[]
include::{generated}/paths.adoc[]当在运行一个测试类之后,会生成swagger.json,测试类的第二个方法,会生成三个文件
这三个文件就是把swagger.json文件进行了处理,为构建html和pdf生成adoc文件
步骤(生成html和pdf):
1.运行第一个测试类,生成swagger.json和三个adoc文件
2.命令行,运行mvn clean test
3.在target/asciidoc下面就会生成html和pdf
生成markdown文件,直接运行第二个测试类
注意:生成pdf的时候,对中文的支持很不好,会缺少文字,由于使用的分组,只能一个个的文档生成
我在构建文档过程中出现的问题
1.升级Springboot(1.3.2升级到1.5.2)
由于我的项目是使用mongo数据库的,配置文件<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd" default-autowire="byName">
<mongo:mongo id="mongo" replica-set="${mongo.replicaSet}" >
<mongo:options connections-per-host="${mongo.connectionsPerHost}"
threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
connect-timeout="${mongo.connectTimeout}" max-wait-time="${mongo.maxWaitTime}"
auto-connect-retry="${mongo.autoConnectRetry}" socket-keep-alive="${mongo.socketKeepAlive}"
socket-timeout="${mongo.socketTimeout}"
write-number="1" write-timeout="0" write-fsync="true" />
</mongo:mongo>
<!-- mongo:db-factory dbname="${mongo.dbname}" mongo-ref="mongo" username="${mongo.username}"
password="${mongo.password}"/>-->
<mongo:db-factory dbname="${mongo.dbname}" mongo-ref="mongo"/>
<!-- <mongo:db-factory dbname="${mongo.dbname}" mongo-ref="mongo"/> -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
<constructor-arg ref="mappingMongoConverter" />
</bean>
<!-- <mongo:mapping-converter id="converter" db-factory-ref="mongoDbFactory"
/> -->
<!-- 默认Mongodb类型映射 -->
<bean id="defaultMongoTypeMapper"
class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
<constructor-arg name="typeKey">
<null /><!-- 这里设置为空,可以把 spring data mongodb 多余保存的_class字段去掉 -->
</constructor-arg>
</bean>
<bean id="mappingContext"
class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
<!-- 转换器:1、去掉write的_class字段 2、TimestampConverter -->
<bean id="mappingMongoConverter"
class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
<constructor-arg name="mappingContext" ref="mappingContext" />
<property name="typeMapper" ref="defaultMongoTypeMapper" />
</bean>
<!-- mongo操作文件的模板 -->
<bean id="gridFsTemplate" class="org.springframework.data.mongodb.gridfs.GridFsTemplate">
<constructor-arg ref="mongoDbFactory" />
<constructor-arg ref="mappingMongoConverter" />
</bean>
</beans>升级了之后,<mongo:mongo>这个element不能使用了,启动的时候导致mongo的bean都不可使用,程序无法启动,目前只能使用<mongo:mongo-client>,具体配置改为<mongo:mongo-client host="localhost" port="27017" id="mongo">
<mongo:client-options socket-keep-alive="${mongo.socketKeepAlive}"
socket-timeout="${mongo.socketTimeout}"
connect-timeout="${mongo.connectTimeout}"
max-wait-time="${mongo.maxWaitTime}"
threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
connections-per-host="${mongo.connectionsPerHost}"
/>
</mongo:mongo-client>其他的不用动
2.swagger-models的jar包出问题
之前这个jar包是不需要在pom.xml文件中引用的,是springfox.swagger2的包引用的,但是在运行第二个测试类的时候,有一个枚举类总是缺少元素,只能把这个包升级,在pom.xml中添加<dependency> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> <version>1.5.18</version> </dependency>
解决此问题
最后在强调一下,在测试的过程中,会有一些文件路径的问题,这个只能具体测试的时候,去解决了
特此感谢 http://blog.csdn.net/fly910905/article/details/79131755#comments
相关文章推荐
- Markdown导出成HTML,PDF格式
- Markdown导出成HTML,PDF格式
- man手册导出成txt,pdf,html的一些小技巧
- 关于通过iText通过HTML转成PDF导出的操作遇到一些问题的记录
- 导出PDF文件中的公式LaTeX源码:翻译英文文献时的一些有用工具和心得
- 对itext导出PDF的一些小总结,以及ireport中生成中文PDF
- DataTable导出为word,excel,html,csv,pdf,.txt
- ASP.NET C#根据HTML页面导出PDF
- mac下利用Pandoc、LaTeX 转换markdown成html,pdf
- php 实现 html 导出 PDF
- java 实现html模板导出pdf的方式
- IOS学习笔记-9Objective-C规范注释心得——同时兼容appledoc(docset、html)与doxygen(html、pdf)的文档生成
- 将man帮助手册导出成txt,pdf,html
- DataTable导出为word,excel,html,csv,pdf,.txt
- ireport设计导出模板,Jasperreport导出PDF、HTML、Excel
- 导出pdf之--html2canvas
- MarkdownPad2导出PDF文字大小及格式问题处理
- ireport导出excel,html.pdf等格式完整实例
- Markdown文件导出为pdf
- phantomjs导出html到pdf的方法总结