swagger在线文档和离线文档

Posted 吐槽村

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swagger在线文档和离线文档相关的知识,希望对你有一定的参考价值。

spring boot项目的swagger文档。

依赖从spring boot的基础上增加。参考pom.xml:

          <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		

		<!-- Swagger  -->
          <!-- 文档可视化--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> </dependency> <dependency> <groupId>org.springframework.restdocs</groupId> <artifactId>spring-restdocs-mockmvc</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-staticdocs</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.8</version> </dependency>

  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-surefire-plugin</artifactId>
                <configuration>
                    <includes>
                        <include>**/*Documentation.java</include>
                    </includes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.asciidoctor</groupId>
                <artifactId>asciidoctor-maven-plugin</artifactId>
                <version>1.5.3</version>

                <!-- Configure generic document generation settings -->
                <configuration>
                    <sourceDirectory>${project.basedir}/target/asciidoc</sourceDirectory>
                    <sourceDocumentName>paths.adoc</sourceDocumentName>
                    <attributes>
                        <doctype>book</doctype>
                        <toc>left</toc>
                        <toclevels>3</toclevels>
                        <numbered></numbered>
                        <hardbreaks></hardbreaks>
                        <sectlinks></sectlinks>
                        <sectanchors></sectanchors>
                        <generated>${project.build.directory}/asciidoc</generated>
                    </attributes>
                </configuration>
                <!-- Since each execution can only handle one backend, run
                     separate executions for each desired output type -->
                <executions>
                    <execution>
                        <id>output-html</id>
                        <phase>test</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>html5</backend>
                            <outputDirectory>${project.basedir}/docs/asciidoc/html</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
		</plugins>
	</build>

  

Swagger2.java参考代码:

import java.util.ArrayList;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod;

import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseMessageBuilder;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ResponseMessage;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;


@Configuration
@ComponentScan
@EnableSwagger2
public class Swagger2 {

	@Bean
	public Docket petApi() {
		
		//自定义异常信息
		 ArrayList<ResponseMessage> responseMessages = new ArrayList<ResponseMessage>() {{
	            add(new ResponseMessageBuilder().code(200).message("成功").build());
	            add(new ResponseMessageBuilder().code(400).message("请求参数错误").responseModel(new ModelRef("Error")).build());
	            add(new ResponseMessageBuilder().code(401).message("权限认证失败").responseModel(new ModelRef("Error")).build());
	            add(new ResponseMessageBuilder().code(403).message("请求资源不可用").responseModel(new ModelRef("Error")).build());
	            add(new ResponseMessageBuilder().code(404).message("请求资源不存在").responseModel(new ModelRef("Error")).build());
	            add(new ResponseMessageBuilder().code(409).message("请求资源冲突").responseModel(new ModelRef("Error")).build());
	            add(new ResponseMessageBuilder().code(415).message("请求格式错误").responseModel(new ModelRef("Error")).build());
	            add(new ResponseMessageBuilder().code(423).message("请求资源被锁定").responseModel(new ModelRef("Error")).build());
	            add(new ResponseMessageBuilder().code(500).message("服务器内部错误").responseModel(new ModelRef("Error")).build());
	            add(new ResponseMessageBuilder().code(501).message("请求方法不存在").responseModel(new ModelRef("Error")).build());
	            add(new ResponseMessageBuilder().code(503).message("服务暂时不可用").responseModel(new ModelRef("Error")).build());
	            add(new ResponseMessageBuilder().code(-1).message("未知异常").responseModel(new ModelRef("Error")).build());
	        }};
		return new Docket(DocumentationType.SWAGGER_2)
				.apiInfo(apiInfo())
				.select()
				.apis(RequestHandlerSelectors.basePackage("my.product.controller"))//扫描的API包
				.paths(PathSelectors.any())
				.build()
				.useDefaultResponseMessages(false)
                .globalResponseMessage(RequestMethod.GET, responseMessages)
                .globalResponseMessage(RequestMethod.POST, responseMessages)
                .globalResponseMessage(RequestMethod.PUT, responseMessages)
                .globalResponseMessage(RequestMethod.DELETE, responseMessages);
	}
	private ApiInfo apiInfo() {
		return new ApiInfoBuilder()
				.title("Spring cloud 中使用Swagger2构建Restful APIs")
				.description("swagger项目文档测试说明")
				.version("1.0").build();
	}

}

  TestController.java参考代码

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;


@Api(value = "学生信息查询", description = "学生基本信息操作API", tags = "StudentApi", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@RestController
public class Swagger2TestController {
	
	
    @ApiOperation(value = "getStudent", notes = "依据学生姓名查询学生信息")
    @RequestMapping(value = "student", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public Student getStudent(@RequestParam("name") String name){
    	System.out.println("name : "+name);
        Student reponse = new Student();
        reponse.setId(1);
        reponse.setName(name);
        reponse.setAge(12);
        reponse.setCls("二年级");
        reponse.setAddress("重庆市大竹林");
        reponse.setSex("男");
        return reponse;
    }

    @ApiOperation(value = "addStudent", notes = "添加一个学生", code = 201)
    @RequestMapping(value = "addStudent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    public void addStudent(@RequestBody Student student){
    	System.out.println("addStudent : "+student);
        return ;
    }

}

  student.java参考代码

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel(value = "Student", description = "学生信息描述")
public class Student {
	
	/**
     * 学号
     */
    @ApiModelProperty("学号")
    private int id;
    /**
     * 姓名
     */
    @ApiModelProperty("姓名")
    private String name;
    /**
     * 年龄
     */
    @ApiModelProperty("年龄")
    private int age;
    /**
     * 性别
     */
    @ApiModelProperty("性别")
    private String sex;
    /**
     * 班级
     */
    @ApiModelProperty("班级")
    private String cls;
    /**
     * 住址
     */
    @ApiModelProperty("家庭住址")
    private String address;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getCls() {
		return cls;
	}
	public void setCls(String cls) {
		this.cls = cls;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}

    

}

  测试类:

import org.junit.After;
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.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import com.alibaba.fastjson.JSON;
import com.swagger.model.Student;

import io.github.robwin.markup.builder.MarkupLanguage;
import io.github.robwin.swagger2markup.GroupBy;
import io.github.robwin.swagger2markup.Swagger2MarkupConverter;
import springfox.documentation.staticdocs.SwaggerResultHandler;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;

@AutoConfigureMockMvc
@AutoConfigureRestDocs(outputDir = "target/generated-snippets")
@RunWith(SpringRunner.class)
@SpringBootTest
public class SwaggerApplicationTests {

	 private String snippetDir = "target/generated-snippets";
	 private String outputDir = "target/asciidoc";
	 
	 @Autowired
	 private MockMvc mockMvc;
	 
	 @After
	    public void Test() throws Exception{
	        // 得到swagger.json,写入outputDir目录中
	        mockMvc.perform(get("/v2/api-docs").accept(MediaType.APPLICATION_JSON))
	                .andDo(SwaggerResultHandler.outputDirectory(outputDir).build())
	                .andExpect(status().isOk())
	                .andReturn();

	        // 读取上一步生成的swagger.json转成asciiDoc,写入到outputDir
	        // 这个outputDir必须和插件里面<generated></generated>标签配置一致
	        Swagger2MarkupConverter.from(outputDir + "/swagger.json")
	                .withPathsGroupedBy(GroupBy.TAGS)// 按tag排序
	                .withMarkupLanguage(MarkupLanguage.ASCIIDOC)// 格式
	                .withExamples(snippetDir)
	                .build()
	                .intoFolder(outputDir);// 输出
	    }
	@Test
	public void contextLoads() throws Exception {
		 mockMvc.perform(get("/student").param("name", "xxx")
	                .accept(MediaType.APPLICATION_JSON))
	                .andExpect(status().isOk())
	                .andDo(MockMvcRestDocumentation.document("getStudent", preprocessResponse(prettyPrint())));

	        Student student = new Student();
	        student.setName("xxx");
	        student.setAge(23);
	        student.setAddress("湖北麻城");
	        student.setCls("二年级");
	        student.setSex("男");

	        mockMvc.perform(post("/addStudent").contentType(MediaType.APPLICATION_JSON)
	                .content(JSON.toJSONString(student))
	                .accept(MediaType.APPLICATION_JSON))
	                .andExpect(status().is2xxSuccessful())
	                .andDo(MockMvcRestDocumentation.document("addStudent", preprocessResponse(prettyPrint())));
	}

}

  每个API都需要测试一下才有效。测试完后直接install,这离线文档就会在${product.path}\docs\asciidoc\html下生成。

在线文档启动项目访问http://localhost:8080/swagger-ui.html就行了。springboot启动类加@EnableSwagger2 注解就行

以上是关于swagger在线文档和离线文档的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot2基于Swagger2生成离线Api文档

XMPPFramework - 如何获取在线和离线好友列表?

如何访问特定于平台的包文档?

SpringBoot集成Swagger2在线文档

实现在线和离线表现不同的 css

如何生成离线 Swagger API 文档?