swagger springboot整合

今天研究了下API框架,在网上查了下swagger相对不错,特别看了下,大体上可以解决问题,但是有些问题一直不知道原因,再次记录,后期希望能够处理掉。

首先是maven+eclipse,引入相应依赖包:

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.6.RELEASE</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<scope>test</scope>
		</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-swagger2</artifactId>
			<version>2.6.1</version>
		</dependency>
		<dependency>
			<groupId>io.github.swagger2markup</groupId>
			<artifactId>swagger2markup-maven-plugin</artifactId>
			<version>1.0.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.asciidoctor</groupId>
			<artifactId>asciidoctorj</artifactId>
			<version>1.5.4.1</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</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>
		</dependency>
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-staticdocs</artifactId>
			<version>2.6.1</version>
		</dependency>
	</dependencies>

可以通过springboot写个简单的接口,然后在类或方法上加上swagger相关注解,比如

@Api(value="/user",tags="UserController")
@RestController
@RequestMapping("/user")
public class UserController {

	public static Map<Integer,User> users = Collections.synchronizedMap(new HashMap<Integer, User>());
	
	static{
		buildUsers();
	}
	
	private static void buildUsers() {
		// TODO Auto-generated method stub
		for(int i=0;i<10;i++) {
			User user = new User();
			user.setId(i);
			user.setName("name"+i);
			user.setCtm(new Date());
			user.setAge((int) (20+(Math.random()*10)/2));
			users.put(i, user);
		}
	}
	
	@ApiOperation(value="获取用户信息",notes="根据id查询用户")
	@ApiImplicitParams({@ApiImplicitParam(name="id",value="用户id",required=true,dataType="Integer",paramType="path")})
	@GetMapping("/{id}")
	public ResponseEntity<JsonResult> getUserById(@PathVariable("id") int id){
		User user = users.get(id);
		JsonResult jr = new JsonResult();
		jr.setResult(user);
		jr.setStatus("ok");
		return ResponseEntity.ok(jr);
	}

同时加上swagger相关配置:

	@Bean
	public Docket createRestApi() {
		return new Docket(DocumentationType.SWAGGER_2)
				.apiInfo(apiInfo())
				.select()
				.apis(RequestHandlerSelectors.basePackage("com.api.demo"))
				.paths(PathSelectors.any())
				.build();
				//.pathMapping("/myapp"); // 在这里可以设置请求的统一前缀;
	}

	private ApiInfo apiInfo() {
		return new ApiInfoBuilder()
				.title("Spring boot API文档")
				.description("文档描述")
				.termsOfServiceUrl("http://123.com")
				.version("1.0.0")
				.build();
	}

启动项目,此时可以通过 http://localhost:8080/swagger-ui.html访问到项目api并进行测试。

然后将api以文档形式导出,按网上有两种方式实现,

需要用的技术与过程:

1)生成swagger.json/yaml文件,可以通过代码生成或者maven插件swagger-maven-plugin。

2)通过Swagger2markup将Swagger语义(json、yaml)转换成markdown、asciidoc文本格式。

3)通过Asciidoctor将adoc文档转换成html或pdf的最终格式。

实现方式:

a、存代码实现

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=Application.class)
public class Swagger2MarkupTest {

	@Autowired
	private WebApplicationContext webApplicationContext;
	
	private MockMvc mockMvc;
	
	@Before
	public void setUp() {
		this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
	}
	
//	@Test
	public void createSpringfoxSwaggerJson()throws Exception{
		String outputDir = "src/docs/json";//将api-docs的json数据写入文件
		MvcResult mvcResult = this.mockMvc.perform(get("/v2/api-docs")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andReturn();
		
		MockHttpServletResponse response = mvcResult.getResponse();
		String swaggerJson = response.getContentAsString();
		Files.createDirectories(Paths.get(outputDir));
		
		BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputDir, "swagger.json"), StandardCharsets.UTF_8);
        writer.write(swaggerJson);
	}
	
	/**
	 * 通过代码方式实现
	 * @throws Exception
	 */
	@Test
    public void convertSwaggerToAsciiDoc() throws Exception {
        MvcResult mvcResult = this.mockMvc.perform(get("/v2/api-docs")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andReturn();

        //文档输出目录 
        String outputDirectory = "docs/restful/generated";
        MockHttpServletResponse response = mvcResult.getResponse();
        String swaggerJson = response.getContentAsString();
//        swaggerJson = swaggerJson.replace("{\"status\":200,\"message\":\"\",\"data\":", "");
//        swaggerJson = swaggerJson.substring(0,swaggerJson.length()-1);
        Swagger2MarkupConverter.from(swaggerJson).build().toFolder(Paths.get(outputDirectory));
        
        Asciidoctor asciidoctor = Asciidoctor.Factory.create();
        Attributes attributes = new Attributes();
        attributes.setCopyCss(true);
        attributes.setLinkCss(false);
        attributes.setSectNumLevels(3);
        attributes.setAnchors(true);
        attributes.setSectionNumbers(true);
        attributes.setHardbreaks(true);
        attributes.setTableOfContents(Placement.LEFT);
        attributes.setAttribute("generated", "generated");
        OptionsBuilder optionsBuilder = OptionsBuilder.options()
                .backend("html5")
                .docType("book")
                .eruby("")
                .inPlace(true)
                .safe(SafeMode.UNSAFE)
                .attributes(attributes);
        String asciiInputFile = "docs/restful/index.adoc";//先定义该文件
        initIndex(asciiInputFile);
        asciidoctor.convertFile(
                new File(asciiInputFile),
                optionsBuilder.get());
        
    }
	
	public static void initIndex(String path) {
		File index = new File(path);//index.adoc
		if(index.exists() && index.isDirectory() && "index.adoc".equals(index.getName())) {
			
		}else {
			try {
				FileUtils.copyFile(new File("temp/index.adoc"), index);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

其中index.adoc需要自己编写。

b)通过maven插件实现:

首先编写生成swagger.json代码(为什么写在代码里,这是一个问题)

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
//@AutoConfigureRestDocs(outputDir = "build/asciidoc/snippets")
@SpringBootTest(classes=Application.class)
public class Swagger2MarkupDoc {

	@Autowired
	private WebApplicationContext webApplicationContext;
	
	private MockMvc mockMvc;
	
	@Before
	public void setUp() {
		this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
	}
	
	@Test
	public void createSpringfoxSwaggerJson(){
		String outputDir = "src/docs/json";//将api-docs的json数据写入文件
	//	String outputDir = System.getProperty("io.springfox.staticdocs.outputDir");
		BufferedWriter writer = null;
		try {
			MvcResult mvcResult = this.mockMvc.perform(get("/v2/api-docs")
			        .accept(MediaType.APPLICATION_JSON))
			        .andExpect(status().isOk())
			        .andReturn();
			
			MockHttpServletResponse response = mvcResult.getResponse();
			String swaggerJson = response.getContentAsString();
			Files.createDirectories(Paths.get(outputDir));
			
			writer = Files.newBufferedWriter(Paths.get(outputDir, "swagger.json"), StandardCharsets.UTF_8);
			writer.write(swaggerJson);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if(writer!=null) writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

然后在pom引入相关包和插件:

	<pluginRepositories>
		<pluginRepository>
			<id>jcenter-snapshots</id>
			<name>jcenter</name>
			<url>http://oss.jfrog.org/artifactory/oss-snapshot-local/</url>
		</pluginRepository>
		<pluginRepository>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
			<id>jcenter-releases</id>
			<name>jcenter</name>
			<url>http://jcenter.bintray.com</url>
		</pluginRepository>
	</pluginRepositories>
<build>
		<plugins>
			<plugin>
				<groupId>io.github.swagger2markup</groupId>
				<artifactId>swagger2markup-maven-plugin</artifactId>
				<version>${swagger2markup.version}</version>
				<dependencies>
					<dependency>
						<groupId>io.github.swagger2markup</groupId>
						<artifactId>swagger2markup-import-files-ext</artifactId>
						<version>${swagger2markup.version}</version>
					</dependency>
					<dependency>
						<groupId>io.github.swagger2markup</groupId>
						<artifactId>swagger2markup-spring-restdocs-ext</artifactId>
						<version>${swagger2markup.version}</version>
					</dependency>
				</dependencies>
				<configuration>
					<swaggerInput>${swagger.input}</swaggerInput>
					<outputDir>${generated.asciidoc.directory}</outputDir>
					<config>
						<swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage>
						<swagger2markup.pathsGroupedBy>TAGS</swagger2markup.pathsGroupedBy>

						<swagger2markup.extensions.dynamicOverview.contentPath>${project.basedir}/src/docs/asciidoc/extensions/overview</swagger2markup.extensions.dynamicOverview.contentPath>
						<swagger2markup.extensions.dynamicDefinitions.contentPath>${project.basedir}/src/docs/asciidoc/extensions/definitions</swagger2markup.extensions.dynamicDefinitions.contentPath>
						<swagger2markup.extensions.dynamicPaths.contentPath>${project.basedir}/src/docs/asciidoc/extensions/paths</swagger2markup.extensions.dynamicPaths.contentPath>
						<swagger2markup.extensions.dynamicSecurity.contentPath>${project.basedir}src/docs/asciidoc/extensions/security/</swagger2markup.extensions.dynamicSecurity.contentPath>

						<swagger2markup.extensions.springRestDocs.snippetBaseUri>${swagger.snippetOutput.dir}</swagger2markup.extensions.springRestDocs.snippetBaseUri>
						<swagger2markup.extensions.springRestDocs.defaultSnippets>false</swagger2markup.extensions.springRestDocs.defaultSnippets>
					</config>
				</configuration>
				<executions>
					<execution>
						<phase>test</phase>
						<goals>
							<goal>convertSwagger2markup</goal>
						</goals>
					</execution>
				</executions>
			</plugin>

			<!-- Then, run the generated asciidoc through Asciidoctor to generate 
				other documentation types, such as PDFs or HTML5 -->
			<plugin>
				<groupId>org.asciidoctor</groupId>
				<artifactId>asciidoctor-maven-plugin</artifactId>
				<version>1.5.3</version>
				<!-- Include Asciidoctor PDF for pdf generation -->
				<dependencies>
					<dependency>
						<groupId>org.asciidoctor</groupId>
						<artifactId>asciidoctorj-pdf</artifactId>
						<version>1.5.0-alpha.11</version>
					</dependency>
					<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>
					<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>

			<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>
					<systemPropertyVariables>
						<io.springfox.staticdocs.outputDir>${swagger.output.dir}</io.springfox.staticdocs.outputDir>
						<io.springfox.staticdocs.snippetsOutputDir>${swagger.snippetOutput.dir}</io.springfox.staticdocs.snippetsOutputDir>
					</systemPropertyVariables>
					<!-- 跳过mvn test -->
					<skip>false</skip>
					<!-- 只测试swagger包下的类 -->
					<!-- <test>swagger.*</test> -->
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<compilerVersion>${java.version}</compilerVersion>
					<source>${java.version}</source>
					<target>${java.version}</target>
					<encoding>UTF-8</encoding>
					<!-- prevents endPosTable exception for maven compile -->
					<useIncrementalCompilation>false</useIncrementalCompilation>
				</configuration>
			</plugin>
		</plugins>
		<pluginManagement>
			<plugins>
				<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
				<plugin>
					<groupId>org.eclipse.m2e</groupId>
					<artifactId>lifecycle-mapping</artifactId>
					<version>1.0.0</version>
					<configuration>
						<lifecycleMappingMetadata>
							<pluginExecutions>
								<pluginExecution>
									<pluginExecutionFilter>
										<groupId>
											com.github.kongchen
										</groupId>
										<artifactId>
											swagger-maven-plugin
										</artifactId>
										<versionRange>
											[3.1.5,)
										</versionRange>
										<goals>
											<goal>generate</goal>
										</goals>
									</pluginExecutionFilter>
									<action>
										<ignore></ignore>
									</action>
								</pluginExecution>
							</pluginExecutions>
						</lifecycleMappingMetadata>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>

通过mvn test命令即可生成文档,路径为target/asciidoc下。

问题:

1、通过代码生成只要引入相关的jar包即可,主要问题体现在通过maven插件,首先我们在生成swagger.json文件,目前是通过代码实现,而不是swagger-maven-plugin插件,因为在使用此插件时生成的json文件不完整,没有包含任何接口相关的信息,一直没找到原因,在网上示例中也是正常的,不知道与springboot有没关系;

示例代码代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值