logo-cover-swagger2 导出离线Word/PDF/HTML文档

1.前言

通过前面的两篇博客
Spring Boot Security Swagger2整合生成安全的在线REST API文档 SpringMVC也可参考
spring boot REST 通过Swagger2生成接口文档(含例子源码下载
我们已经介绍了如何使用spring boot整合swagger2 生成在线的API文档。

但是某些情况下,我们需要上交文档类型的接口文档以完成国内开发项目中的文档空缺。然而我们需要提交的文档一般都是Word文档或者PDF文档之类的。HTML这类都很少见。但是这些统统都要离线的。
 

2.通过swagger2markup来实现swagger2 Word/PDF/HTML的导出

2.1在项目中添加swagger2markup的依赖。

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-staticdocs</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.restdocs</groupId>
            <artifactId>spring-restdocs-mockmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-jsonSchema</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.github.robwin</groupId>
            <artifactId>assertj-swagger</artifactId>
            <version>0.2.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.github.swagger2markup</groupId>
            <artifactId>swagger2markup-spring-restdocs-ext</artifactId>
            <version>${swagger2markup.version}</version>
            <scope>test</scope>
        </dependency>
当然项目之前的swagger2依赖统统的需要。如果这里有啥不懂得可以参考上面的两个博客。这里将不会再详细的讲述swagger2生成在线文档。
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-bean-validators</artifactId>
            <version>2.7.0</version>
            <scope>test</scope>
        </dependency>

2.2配置文档输出路径

    <properties>
        <java.version>1.8</java.version>
        <swagger2markup.version>1.3.1</swagger2markup.version>
        <asciidoctor.input.directory>${project.basedir}/src/docs/asciidoc</asciidoctor.input.directory>

        <swagger.output.dir>${project.build.directory}/swagger</swagger.output.dir>
        <swagger.snippetOutput.dir>${project.build.directory}/asciidoc/snippets</swagger.snippetOutput.dir>
        <generated.asciidoc.directory>${project.build.directory}/asciidoc/generated</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>

        <swagger.input>${swagger.output.dir}/swagger.json</swagger.input>
    </properties>
2.3这里举个宠物controller的代码
/*
 *
 *  Copyright 2015 the original author or authors.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *
 */

package io.github.robwin.swagger2markup.petstore.controller;

import io.swagger.annotations.*;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import io.github.robwin.swagger2markup.petstore.Responses;
import io.github.robwin.swagger2markup.petstore.model.Pet;
import io.github.robwin.swagger2markup.petstore.model.Pets;
import io.github.robwin.swagger2markup.petstore.repository.MapBackedRepository;

import java.util.List;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.APPLICATION_XML_VALUE;
import static org.springframework.web.bind.annotation.RequestMethod.*;

@Controller
@RequestMapping(value = "/pets", produces = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE, "application/x-smile"})
@Api(value = "/pets", tags = "Pets", description = "关于pets的操作")
public class PetController {

  PetRepository petData = new PetRepository();

  @RequestMapping(value = "/{petId}", method = GET)
  @ApiOperation(
          value = "通过ID查找宠物", notes = "当ID <10时,返回宠物。ID> 10或非整数将模拟API" +
          "错误条件",
          response = Pet.class,
          authorizations = {
                  @Authorization(value = "api_key"),
                  @Authorization(value = "petstore_auth", scopes = {
                          @AuthorizationScope(scope = "write_pets", description = ""),
                          @AuthorizationScope(scope = "read_pets", description = "")
                  })})
  @ApiResponses(value = {
          @ApiResponse(code = 400, message = "提供的ID无效"),
          @ApiResponse(code = 404, message = "Pet没找到")}
  )
  public ResponseEntity<Pet> getPetById(
          @ApiParam(value = "需要提取的宠物ID", allowableValues = "range[1,5]", required = true)
          @PathVariable("petId") String petId)
          throws NotFoundException {
    Pet pet = petData.get(Long.valueOf(petId));
    if (null != pet) {
      return Responses.ok(pet);
    } else {
      throw new NotFoundException(404, "Pet not found");
    }
  }

  @RequestMapping(method = POST)
  @ApiOperation(value = "添加一个新宠物到商店")
  @ApiResponses(value = {@ApiResponse(code = 405, message = "Invalid input")})
  public ResponseEntity<String> addPet(
          @ApiParam(value = "需要添加到商店的宠物对象", required = true) @RequestBody Pet pet) {
    petData.add(pet);
    return Responses.ok("SUCCESS");
  }

  @RequestMapping(method = PUT)
  @ApiOperation(value = "更新一个已存在的宠物信息",
          authorizations = @Authorization(value = "petstore_auth", scopes = {
                  @AuthorizationScope(scope = "write_pets", description = ""),
                  @AuthorizationScope(scope = "read_pets", description = "")
          }))
  @ApiResponses(value = {@ApiResponse(code = 400, message = "无效ID"),
          @ApiResponse(code = 404, message = "宠物没找到"),
          @ApiResponse(code = 405, message = "验证错误")})
  public ResponseEntity<String> updatePet(
          @ApiParam(value = "需要添加到商店的宠物对象", required = true) @RequestBody Pet pet) {
    petData.add(pet);
    return Responses.ok("SUCCESS");
  }

  @RequestMapping(value = "/findByStatus", method = GET)
  @ApiOperation(
          value = "通过状态查询宠物",
          notes = "多个状态值可以用逗号分隔的字符串提供",
          response = Pet.class,
          responseContainer = "List",
          authorizations = @Authorization(value = "petstore_auth", scopes = {
                  @AuthorizationScope(scope = "write_pets", description = ""),
                  @AuthorizationScope(scope = "read_pets", description = "")
          }))
  @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid status value")})
  /** TODO: This renders parameter as
   *
   "name": "status",
   "in": "query",
   "description": "Status values that need to be considered for filter",
   "required": false,
   "type": "array",
   "items": {"type": "string"},
   "collectionFormat": "multi",
   "default": "available"
   */
  public ResponseEntity<List<Pet>> findPetsByStatus(
          @ApiParam(value = "Status values that need to be considered for filter",
                  required = true,
                  defaultValue = "available",
                  allowableValues = "available,pending,sold",
                  allowMultiple = true)
          @RequestParam("status") String status) {
    return Responses.ok(petData.findPetByStatus(status));
  }

  @RequestMapping(value = "/findByTags", method = GET)
  @ApiOperation(
          value = "通过标签查询宠物",
          notes = "多个标签可以用逗号分隔的字符串提供。 使用tag1,tag2,tag3进行测试。",
          response = Pet.class,
          responseContainer = "List",
          authorizations = @Authorization(value = "petstore_auth", scopes = {
                  @AuthorizationScope(scope = "write_pets", description = ""),
                  @AuthorizationScope(scope = "read_pets", description = "")
          }))
  @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid tag value")})
  @Deprecated
  /** TODO: This renders the parameter as 
  "name": "tags",
          "in": "query",
          "description": "Tags to filter by",
          "required": false,
          "type": "array",
          "items": {"type": "string"},
          "collectionFormat": "multi" */
  public ResponseEntity<List<Pet>> findPetsByTags(
          @ApiParam(
                  value = "Tags to filter by",
                  required = true,
                  allowMultiple = true)
          @RequestParam("tags") String tags) {
    return Responses.ok(petData.findPetByTags(tags));
  }

  static class PetRepository extends MapBackedRepository<Long, Pet> {
    public List<Pet> findPetByStatus(String status) {
      return where(Pets.statusIs(status));
    }

    public List<Pet> findPetByTags(String tags) {
      return where(Pets.tagsContain(tags));
    }
  }
}

3.执行maven命令来生成文档

生成文档命令:
maven test
或者
maven install
如果是eclipse的话通过maven插件可以选中项目右键选择maven test即可
swagger2 文档导出
或许你们会说为啥并没有Word,但是我们有PDF就够了啊。首选把PDF文件复制出来打开看看效果:
PDF文档查看

文档导出效果还是不错的。接下来将PDF转换为Word,如果你安装了微软的office (我这里是office 2016按理说10,13版本都可以未做测试)
Word打开PDF

Word打开效果:
Word打开效果

并且通过红色文字可以看到文档是支持编辑的。整体效果也还不错。只需要配置好在线文档那么离线文档也OK了。

提示:源码下载






 
暂无评论