1. 程式人生 > >swagger在線文檔和離線文檔

swagger在線文檔和離線文檔

ger one 服務器 sys div als red rep dex

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:[email protected]ger2 註解就行

swagger在線文檔和離線文檔