Spring Boot 2.X集成 Swagger2 开发 API 文档(在线+离线)

点击上方蓝色字体,选择“标星公众号”

优质文章,第一时间送达

上一篇:这300G的Java资料是我师傅当年给我的,免费分享给大家

下一篇:昨天分享资料不小心把百度网盘深处的秘密泄露了

作者:朝雾轻寒 来源:开源中国:

http://suo.im/6iDzqd

前言

相信很多后端开发在项目中都会碰到要写 api 文档,不管是给前端、移动端等提供更好的对接,还是以后为了以后交接方便,都会要求写 api 文档。

而手写 api 文档的话有诸多痛点:

  • 文档更新的时候,需要再次发送给对接人

  • 接口太对,手写文档很难管理

  • 接口返回的结果不明确

  • 不能直接在线测试接口,通常需要使用工具,如 postman 等

Swagger 就很好的解决了这个问题。

Swagger 简介

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。

官网:https://swagger.io

Swagger 使用

1.相关依赖

<!--swagger2 -->
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <version>2.9.2</version>
    </dependency>
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>
      <version>2.9.2</version>
    </dependency>

2.Swagger 配置类

@Configuration
@EnableSwagger2
public class SwaggerConfig {
  @Bean
    public Docket buildDocket() {
        return new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(buildApiInf()) //将api的元信息设置为包含在json resourcelisting响应中
        //.host("127.0.0.1:8080") //设置ip和端口,或者域名
        .select() //启动用于api选择的生成器
        //.apis(RequestHandlerSelectors.any())
        .apis(RequestHandlerSelectors.basePackage("cn.zwqh.springboot.controller"))//指定controller路径
        .paths(PathSelectors.any()).build();
    }

    private ApiInfo buildApiInf() {
      
        Contact contact=new Contact("朝雾轻寒","https://www.zwqh.top/","zwqh@clover1314.com");
        return new ApiInfoBuilder()
        .title("Swagger Demo Restful API Docs")//文档标题
        .description("Swagger 示例 Restful Api 文档")//文档描述
        .contact(contact)//联系人
        .version("1.0")//版本号
        //.license("")//更新此API的许可证信息
        //.licenseUrl("")//更新此API的许可证Url
        //.termsOfServiceUrl("")//更新服务条款URL
        .build();

    }
}

3.Spring MVC 相关配置

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
  /**
   * 静态资源配置(默认)
   */
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");// 静态资源路径
    registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
    registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    super.addResourceHandlers(registry);
  }


}

如果不添加此静态资源配置会报错,找不到相关路径

4.Model 中使用 Swagger 注解

@ApiModel(value = "UserEntity", description = "用户对象")
public class UserEntity implements Serializable{

  /**
   *
   */
  private static final long serialVersionUID = 5237730257103305078L;
  @ApiModelProperty(value ="用户id",name="id",dataType="Long",required = false,example = "1",hidden = false )
  private Long id;
  @ApiModelProperty(value ="用户名",name="userName",dataType="String",required = false,example = "关羽" )
  private String userName;
  @ApiModelProperty(value ="用户性别",name="userSex",dataType="String",required = false,example = "男" )
  private String userSex;

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getUserName() {
    return userName;
  }

  public void setUserName(String userName) {
    this.userName = userName;
  }

  public String getUserSex() {
    return userSex;
  }

  public void setUserSex(String userSex) {
    this.userSex = userSex;
  }

}

5. Controller 中使用 Swagger 注解

@RestController
@RequestMapping("/api")
@Api(tags = { "接口分组1", "接口分组2" })
public class ApiController {

  @Autowired
  private UserDao userDao;

  @GetMapping("/getAllUser")
  @ApiOperation(value = "获取所有用户", notes = "", httpMethod = "GET", tags = "接口分组3")
  public List<UserEntity> getAll() {
    return userDao.getAll();
  }

  @GetMapping("/getUserById")
  @ApiOperation(value = "根据id获取用户", notes = "id必传", httpMethod = "GET")
  @ApiImplicitParam(name = "id", value = "用户id",example = "1", required = true, dataType = "long", paramType = "query")
  public UserEntity getOne(Long id) {
    return userDao.getOne(id);
  }

  @PostMapping("/getUserByNameAndSex")
  @ApiOperation(value = "根据name和sex获取用户", notes = "", httpMethod = "POST")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "userName", value = "用户名", example = "关羽", required = true, dataType = "string", paramType = "query"),
      @ApiImplicitParam(name = "userSex", value = "用户性别", example = "男", required = true, dataType = "string", paramType = "query") })
  public UserEntity getUserByNameAndSex(String userName, String userSex) {
    return userDao.getUserByNameAndSex(userName, userSex);
  }

  @PostMapping("/insertUser")
  @ApiOperation(value = "新增用户", notes = "传json,数据放body", httpMethod = "POST")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "body", value = "用户对象json", example = "{userName:'朝雾轻寒',userSex:'男'}", required = true) })
  public String insertUser(@RequestBody String body) {
    System.out.println(body);
    UserEntity user = JSON.parseObject(body, UserEntity.class);
    userDao.insertUser(user);
    return "{code:0,msg:'success'}";
  }

  @PostMapping("/updateUser")
  @ApiOperation(value = "修改用户", notes = "传json,数据放body", httpMethod = "POST")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "body", value = "用户对象json", example = "{id:23,userName:'朝雾轻寒',userSex:'女'}", required = true) })
  public String updateUser(@RequestBody String body) {
    System.out.println(body);
    UserEntity user = JSON.parseObject(body, UserEntity.class);
    userDao.updateUser(user);
    return "{code:0,msg:'success'}";
  }

  @PostMapping("/deleteUser")
  @ApiOperation(value = "删除用户", notes = "id必传", httpMethod = "POST")
  public String deleteUser(@ApiParam(name = "id", value = "用户id", required = true) Long id) {
    userDao.deleteUser(id);
    return "{code:0,msg:'success'}";
  }
}

6.测试

访问 http://127.0.0.1:8080/swagger-ui.html 进行接口在线测试

Swagger 常用注解

1.@Api

用于类,表示标识这个类是swagger的资源。属性如下:

  • tags 表示说明,tags如果有多个值,会生成多个列表

  • value 表示说明,可以使用tags替代

2.@ApiOperation

用于方法,表示一个http请求的操作。属性如下:

  • value 用于方法描述

  • notes 用于提示内容

  • tags 用于API文档控制的标记列表,视情况而用,可以进行独立分组

3.@ApiParam

用于方法、参数、字段说明;表示对参数的添加元数据。

  • name 参数名

  • value 参数说明

  • required 是否必填

4.@ApiModel

用于类,表示对类进行说明,用于参数用实体类接受。

  • value 对象名

  • description 描述

5.@ApiModelProperty

用于方法、字段,表示对model属性的说明或者数据操作更改。

  • value 字段说明

  • name 重写属性名

  • dataType 重写属性数据类型

  • required 是否必填

  • example 举例说明

  • hidden 隐藏

6.@ApiIgnore

用于类、方法、方法参数,表示这个方法或者类被忽略,不在swagger-ui.html上显示。

7.@ApiImplicitParam

用于方法,表示单独的请求参数。

  • name 参数名

  • value 参数说明

  • dataType 数据类型

  • paramType 参数类型

  • example 举例说明

8.@ApiImplicitParams

用于方法,包含多个 @ApiImplicitParam。

9.@ApiResponses @ApiResponse

用于类或者方法,描述操作的可能响应。

  • code 响应的HTTP状态代码

  • message 响应附带的可读消息

10.@ResponseHeader

用于方法,响应头设置。

  • name 响应头名称

  • description 头描述

  • response 默认响应类 void

  • responseContainer 参考ApiOperation中配置

Swagger 导出离线 api 文档

1.导出 AsciiDocs、Markdown、Confluence 格式文档

添加依赖

<!-- swagger2markup 相关依赖 -->
    <dependency>
      <groupId>io.github.swagger2markup</groupId>
      <artifactId>swagger2markup</artifactId>
      <version>1.3.3</version>
    </dependency>

转换工具类

public class SwaggerUtils {

  private static final String url = "http://127.0.0.1:8080/v2/api-docs";
  /**
   * 生成AsciiDocs格式文档
   * @throws MalformedURLException
   */
  public static void generateAsciiDocs() throws MalformedURLException {
    Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
        .withMarkupLanguage(MarkupLanguage.ASCIIDOC)
        .withOutputLanguage(Language.ZH)
        .withPathsGroupedBy(GroupBy.TAGS)
        .withGeneratedExamples()
        .withoutInlineSchema().build();

    Swagger2MarkupConverter.from(new URL(url))
        .withConfig(config)
        .build()
        .toFolder(Paths.get("./docs/asciidoc/generated"));
  }
  /**
   * 生成AsciiDocs格式文档,并汇总成一个文件
   * @throws MalformedURLException
   */
  public static void generateAsciiDocsToFile() throws MalformedURLException {
    Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.ASCIIDOC)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL(url))
                .withConfig(config)
                .build()
                .toFile(Paths.get("./docs/asciidoc/generated/all"));
  }
  
  /**
   * 生成Markdown格式文档
   * @throws MalformedURLException
   */
  public static void generateMarkdownDocs() throws MalformedURLException {
    Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.MARKDOWN)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL(url))
                .withConfig(config)
                .build()
                .toFolder(Paths.get("./docs/markdown/generated"));
  }
  /**
   * 生成Markdown格式文档,并汇总成一个文件
   * @throws MalformedURLException
   */
  public static void generateMarkdownDocsToFile() throws MalformedURLException {
    Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.MARKDOWN)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL(url))
                .withConfig(config)
                .build()
                .toFile(Paths.get("./docs/markdown/generated/all"));
  }
  
  /**
   * 生成Confluence格式文档
   * @throws MalformedURLException
   */
  public static void generateConfluenceDocs() throws MalformedURLException {
    Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL(url))
                .withConfig(config)
                .build()
                .toFolder(Paths.get("./docs/confluence/generated"));
  }
  
  /**
   * 生成Confluence格式文档,并汇总成一个文件
   * @throws MalformedURLException
   */
  public static void generateConfluenceDocsToFile() throws MalformedURLException {
    Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL(url))
                .withConfig(config)
                .build()
                .toFile(Paths.get("./docs/confluence/generated/all"));
  }
  
  
}

使用测试 Controller

@RestController
@RequestMapping("/export")
@ApiIgnore
public class ExportController {

  
  @RequestMapping("/ascii")
  public String exportAscii() throws MalformedURLException{
    SwaggerUtils.generateAsciiDocs();
    return "success";
  }
  
  @RequestMapping("/asciiToFile")
  public String asciiToFile() throws MalformedURLException{
    SwaggerUtils.generateAsciiDocsToFile();
    return "success";
  }
  
  @RequestMapping("/markdown")
  public String exportMarkdown() throws MalformedURLException{
    SwaggerUtils.generateMarkdownDocs();
    return "success";
  }
  
  @RequestMapping("/markdownToFile")
  public String exportMarkdownToFile() throws MalformedURLException{
    SwaggerUtils.generateMarkdownDocsToFile();
    return "success";
  }
  
  @RequestMapping("/confluence")
  public String confluence() throws MalformedURLException{
    SwaggerUtils.generateConfluenceDocs();
    return "success";
  }
  
  @RequestMapping("/confluenceToFile")
  public String confluenceToFile() throws MalformedURLException{
    SwaggerUtils.generateConfluenceDocsToFile();
    return "success";
  }
}

2.导出 html、pdf、xml 格式

添加依赖

<!--离线文档 -->
    <dependency>
      <groupId>org.springframework.restdocs</groupId>
      <artifactId>spring-restdocs-mockmvc</artifactId>
      <scope>test</scope>
    </dependency>
    <!--springfox-staticdocs 生成静态文档 -->
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-staticdocs</artifactId>
      <version>2.6.1</version>
    </dependency>
<build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
          <groupId>io.github.swagger2markup</groupId>
          <artifactId>swagger2markup-maven-plugin</artifactId>
          <version>1.3.1</version>
          <configuration>
            <swaggerInput>http://127.0.0.1:8080/v2/api-docs</swaggerInput>
            <outputDir>./docs/asciidoc/generated</outputDir>
            <config>
              <swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage>
            </config>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.asciidoctor</groupId>
          <artifactId>asciidoctor-maven-plugin</artifactId>
          <version>1.5.3</version>
          <!-- <version>2.0.0-RC.1</version> -->
          <!-- Include Asciidoctor PDF for pdf generation -->
          <dependencies>
            <dependency>
              <groupId>org.asciidoctor</groupId>
              <artifactId>asciidoctorj-pdf</artifactId>
              <version>1.5.0-alpha.10.1</version>
            </dependency>
            <dependency>
              <groupId>org.jruby</groupId>
              <artifactId>jruby-complete</artifactId>
              <version>1.7.21</version>
            </dependency>
          </dependencies>
          <configuration>
            <sourceDirectory>./docs/asciidoc/generated</sourceDirectory>
            <outputDirectory>./docs/asciidoc/html</outputDirectory> 
            <backend>html</backend>
            <!-- <outputDirectory>./docs/asciidoc/pdf</outputDirectory>
            <backend>pdf</backend> -->
            <headerFooter>true</headerFooter> 
            <doctype>book</doctype> 
            <sourceHighlighter>coderay</sourceHighlighter>
            <attributes>
              <!-- 菜单栏在左边 -->
              <toc>left</toc>
              <!-- 多标题排列 -->
              <toclevels>3</toclevels>
              <!-- 自动打数字序号 -->
              <sectnums>true</sectnums>
            </attributes>
          </configuration>          
        </plugin>
      </plugins>
    </pluginManagement>

  </build>

可以修改此处 html 和 pdf,通过 mvn asciidoctor:process-asciidoc 可以导出相应格式文件

<outputDirectory>./docs/asciidoc/html</outputDirectory> 
            <backend>html</backend>

执行 mvn asciidoctor:process-asciidoc 后再执行 mvn generate-resources,可在 targt/generated-docs 目录下生成 xml 格式文件。

完整代码

https://github.com/zwqh1992/Spring-Boot-2.X/tree/master/spring-boot-swagger2

说句题外话,springboot全家桶技术交流群可以加我微信,但是坑位有限哦,由于忙于工作,有时不能及时回复大家,请多包涵。


猜你喜欢1、Java : 对象不再使用时,为什么要赋值为 null ?2、一份不可多得的 Lombok 学习指南3、为什么说++i比i++效率高?4、ZooKeeper基本原理5、在 IntelliJ IDEA 中使用 Git,太方便了!6、Redis实战--使用Jedis实现百万数据秒级插入7、7 个显著提升编码效率的IntelliJ IDEA必备插件8、免费版的 IDEA 为啥不能使用 Tomcat ?
强烈推荐一位大佬的公众号

好文章,我在看❤️
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring5 是一个重要的版本,距离SpringFramework4差不多四年。在此期间,大多数增强都是在 SpringBoot 项目中完成的。在本文中,我们将很快了解到Spring5发行版中的一些令人兴奋的特性。 1. 基准升级 要构建和运行 Spring5 应用程序,你至少需要 J2EE7 和 JDK8。以前的 JDK 和 JavaEE 版本不再支持。 JavaEE7 包含: Servlet 3.1 JMS 2.0 JPA 2.1 JAX-RS 2.0 Bean Validation 1.1 与 Java 基准类似,许多其他框架的基准也有变化。例如: Hibernate 5 Jackson 2.6 EhCache 2.10 JUnit 5 Tiles 3 另外,请记下各种服务器最低支持版本。 Tomcat 8.5+ Jetty 9.4+ WildFly 10+ Netty 4.1+ Undertow 1.4+ 2. 兼容 JDK9 运行时 Spring5 发行版与 JDK9 发行日期非常接近。目标是让 Spring Framework5 在 JDK9 的 GA 之后正确运行。 Spring5 版本的候选版本已经在 classpath 和 modulepath 上支持 Java9 了。 GA版本中你可以期待良好的 JDK9 支持。 3. 使用 JDK8 特性 获取免费Spring 5 新特性视频详解可以群:554355695 在 Spring4.3 之前,JDK基准版本是6。所以 Spring4 必须支持 Java6,7 和8,为了保持向后兼容性, Spring 框架没有适应 Java8 带来的许多新特性,比如 lambda 表达式。 Spring5 的基准版本为8,因此它使用了 Java8 和9的许多新特性。例如: Spring 接口中的默认方法 基于 Java8 反射增强的内部代码改进 在框架代码中使用函数式编程 - lambda表达式 和 stream流 4. 响应式编程支持 响应式编程是 SpringFramework5.0 最重要的特性之一。响应式编程提供了另一种编程风格,专注于构建对事件做出响应的应用程序。 SpringFramework5 包含响应流(定义响应性API的语言中立尝试)和 Reactor(由Spring Pivotal团队提供的 Reactive Stream 的Java实现), 以用于其自身的用途以及其许多核心APISpring Web Reactive 在 spring-webmvc 模块中现有的(而且很流行)Spring Web MVC旁边的新的 spring-web-reactive 模块中。 请注意,在 Spring5 中,传统的 SpringMVC 支持 Servlet3.1 上运行,或者支持 JavaEE7 的服务器。 5. 函数式web框架 除了响应式功能之外,Spring5 还提供了一个函数式Web框架。它提供了使用函数式编程风格来定义端点的特性。 该框架引入了两个基本组件:HandlerFunction 和 RouterFunction。 HandlerFunction 表示处理接收到的请求并生成响应的函数。 RouterFunction 替代了 @RequestMapping 注解。它用于将接收到的请求路由到处理函数。例如: RouterFunction route = route(GET("/hello-world"), request -> Response.ok().body(fromObject("Hello World"))); 6. Kotlin支持 Kotlin 是一种静态类型的JVM语言,它让代码具有表现力,简洁性和可读性。 Spring5.0 对 Kotlin 有很好的支持。 7. 移除的特性 随着 Java、JavaEE 和其他一些框架基准版本的增加,SpringFramework5 取消了对几个框架的支持。例如: Portlet Velocity JasperReports XMLBeans JDO Guava
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值