1. 相信无论是前端还是后端开发,都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。
  2. 你只需要按照Swagger的规范去定义接口及接口相关的信息。再通过Swagger衍生出来的一系列项目和工具,就可以做到生成各种格式的接口文档,生成多种语言的客户端和服务端的代码,以及在线接口调试页面等等。
  3. 开发新版本或者迭代版本的时候,只需要更新Swagger描述文件,就可以自动生成接口文档和客户端服务端代码,做到调用端代码、服务端代码以及接口文档的一致性。
  4. 通过在项目中引入Swagger,可以扫描相关的代码,生成该描述文件,进而生成与代码一致的接口文档和客户端代码。这种通过代码生成接口文档的形式,在后面需求持续迭代的项目中,显得尤为重要和高效。
  5. 下面介绍SpringBoot整合Swagger生成API文档的过程
  6. 新建一个SpringBoot工程springboot-swagger2
  7. 引入相关的Maven依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Swagger2依赖 -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.6.1</version>
    </dependency>
    <!-- Swagger2依赖 -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.6.1</version>
    </dependency>
    <!-- Mybatis依赖 -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.0</version>
    </dependency>
    <!-- druid依赖 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.10</version>
    </dependency>
    <!-- mysql依赖 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
  1. 在数据库中建立测试的表,SQL脚本如下
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `birthday` datetime DEFAULT NULL,
  `comment` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
  1. 新建Mybatis配置文件 resources\mybatis\config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <!--配置命名规则-->
        <setting name="mapUnderscoreToCamelCase" value="true" />
    </settings>
    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer" />
        <typeAlias alias="Long" type="java.lang.Long" />
        <typeAlias alias="HashMap" type="java.util.HashMap" />
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
        <typeAlias alias="ArrayList" type="java.util.ArrayList" />
        <typeAlias alias="LinkedList" type="java.util.LinkedList" />
    </typeAliases>
</configuration>
  1. 修改配置文件application.properties为application.yml,并添加下面的配置项
server:
  port: 8081

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

mybatis:
  config-location: classpath:mybatis/config.xml
  mapper-locations: classpath*:mybatis/mapper/**/*.xml
  1. 新建Swagger2的配置类
package com.kangswx.springbootswagger2.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

@Configuration
public class Swagger2 {

    /**
     * 生成API对象
     * @return
     */
    @Bean
    public Docket createRestApi(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //controller包的路径,生成controller对应的API文档
                .apis(RequestHandlerSelectors .basePackage("com.kangswx.springbootswagger2.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 生成API描述信息
     * @return
     */
    public ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("Spring整合Swagger2的API")
                .description("简单优雅的rest风格,")
                .termsOfServiceUrl("")
                .version("1.0")
                .build();
    }
}
  1. 新建User的实体类
import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {

    private Integer id;

    private String username;

    private String password;

    private Integer age;

    private Date birthday;

    private String comment;

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username == null ? null : username.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment == null ? null : comment.trim();
    }

}
  1. 新增UserMapper接口
import com.kangswx.springbootswagger2.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Repository
@Mapper
public interface UserMapper {

    int deleteByPrimaryKey(Integer id);

    int insert(User record);

    int insertSelective(User record);

    User selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(User record);

    int updateByPrimaryKey(User record);

}
  1. 新增UserMapper配置文件(resources\mybatis\mapper\UserMapper.xml)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.kangswx.springbootswagger2.mapper.UserMapper" >
  <resultMap id="BaseResultMap" type="com.kangswx.springbootswagger2.entity.User" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
    <result column="age" property="age" jdbcType="INTEGER" />
    <result column="birthday" property="birthday" jdbcType="TIMESTAMP" />
    <result column="comment" property="comment" jdbcType="VARCHAR" />
  </resultMap>

  <sql id="Base_Column_List" >
    id, username, password, age, birthday, comment
  </sql>

  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from t_user
    where id = #{id,jdbcType=INTEGER}
  </select>

  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
    delete from t_user
    where id = #{id,jdbcType=INTEGER}
  </delete>

  <insert id="insert" parameterType="com.kangswx.springbootswagger2.entity.User" >
    insert into t_user (id, username, password, 
      age, birthday, comment
      )
    values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
      #{age,jdbcType=INTEGER}, #{birthday,jdbcType=TIMESTAMP}, #{comment,jdbcType=VARCHAR}
      )
  </insert>

  <insert id="insertSelective" parameterType="com.kangswx.springbootswagger2.entity.User" >
    insert into t_user
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="username != null" >
        username,
      </if>
      <if test="password != null" >
        password,
      </if>
      <if test="age != null" >
        age,
      </if>
      <if test="birthday != null" >
        birthday,
      </if>
      <if test="comment != null" >
        comment,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=INTEGER},
      </if>
      <if test="username != null" >
        #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        #{password,jdbcType=VARCHAR},
      </if>
      <if test="age != null" >
        #{age,jdbcType=INTEGER},
      </if>
      <if test="birthday != null" >
        #{birthday,jdbcType=TIMESTAMP},
      </if>
      <if test="comment != null" >
        #{comment,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>

  <update id="updateByPrimaryKeySelective" parameterType="com.kangswx.springbootswagger2.entity.User" >
    update t_user
    <set >
      <if test="username != null" >
        username = #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        password = #{password,jdbcType=VARCHAR},
      </if>
      <if test="age != null" >
        age = #{age,jdbcType=INTEGER},
      </if>
      <if test="birthday != null" >
        birthday = #{birthday,jdbcType=TIMESTAMP},
      </if>
      <if test="comment != null" >
        comment = #{comment,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>

  <update id="updateByPrimaryKey" parameterType="com.kangswx.springbootswagger2.entity.User" >
    update t_user
    set username = #{username,jdbcType=VARCHAR},
      password = #{password,jdbcType=VARCHAR},
      age = #{age,jdbcType=INTEGER},
      birthday = #{birthday,jdbcType=TIMESTAMP},
      comment = #{comment,jdbcType=VARCHAR}
    where id = #{id,jdbcType=INTEGER}
  </update>
</mapper>
  1. 新增UserService接口
import com.kangswx.springbootswagger2.entity.User;

public interface UserService {

    User getByid(Integer id);

    int updateUser(User user);

    int deleteUserById(Integer id);

    int addUser(User user);
}
  1. 新增UserServiceImpl实现类
import com.kangswx.springbootswagger2.entity.User;
import com.kangswx.springbootswagger2.mapper.UserMapper;
import com.kangswx.springbootswagger2.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public User getByid(Integer id) {
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateUser(User user) {
        return userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public int deleteUserById(Integer id) {
        return userMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int addUser(User user) {
        return userMapper.insert(user);
    }

}
  1. 新增UserController,并为每个接口添加Swagger注解信息
import com.kangswx.springbootswagger2.entity.JsonData;
import com.kangswx.springbootswagger2.entity.User;
import com.kangswx.springbootswagger2.service.UserService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/v1/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 查询接口
     * @param id
     * @return
     */
    //ApiOperation生成的接口的API描述信息
    @ApiOperation(value = "查询用户信息", notes = "根据url的id来查询用户详细信息")
    //ApiImplicitParam生成的接口参数的API描述信息
    @ApiImplicitParam(name="id", value = "用户的id", required = true, dataType = "int", paramType = "path")
    @GetMapping(value = "{id}")
    public Object getById(@PathVariable int id){
        User user = userService.getByid(id);
        return JsonData.buildSuccess(user);
    }

    /**
     * 修改接口
     * @param user
     * @return
     */
    //ApiOperation生成的接口的API描述信息
    @ApiOperation(value = "修改用户信息", notes = "根据传入对象的非空字段值和id修改用户信息")
    //ApiImplicitParam生成的接口参数的API描述信息
    @ApiImplicitParam(name = "user", value = "用户对象", required = true, dataType = "Json", paramType = "body")
    @PutMapping()
    public Object updateUserById(@RequestBody User user){
        int ret = userService.updateUser(user);
        JsonData jsonData = null;
        if(ret > 0){
            jsonData = JsonData.buildSuccess("修改成功");
        } else {
            jsonData = JsonData.buildError("修改失败");
        }
        return jsonData;
    }

    /**
     * 添加接口
     * @param user
     * @return
     */
    //ApiOperation生成的接口的API描述信息
    @ApiOperation(value = "新增用户", notes = "将传入的用户对象添加到数据库")
    //ApiImplicitParam生成的接口参数的API描述信息
    @ApiImplicitParam(name = "user", value = "用户对象", required = true, dataType = "Json", paramType = "body")
    @PostMapping()
    public Object addUser(@RequestBody User user){
        int ret = userService.addUser(user);
        JsonData jsonData = null;
        if(ret > 0){
            jsonData = JsonData.buildSuccess("添加成功");
        } else {
            jsonData = JsonData.buildError("添加失败");
        }
        return jsonData;
    }

    /**
     * 删除接口
     * @param id
     * @return
     */
    //ApiOperation生成的接口的API描述信息
    @ApiOperation(value = "删除用户", notes = "根据url的id来删除数据库中对应的用户")
    //ApiImplicitParam生成的接口参数的API描述信息
    @ApiImplicitParam(name="id", value = "用户的id", required = true, dataType = "int", paramType = "path")
    @DeleteMapping("{id}")
    public Object deleteUser(@PathVariable int id){
        int ret = userService.deleteUserById(id);
        JsonData jsonData = null;
        if(ret > 0){
            jsonData = JsonData.buildSuccess("删除成功");
        } else {
            jsonData = JsonData.buildError("删除失败");
        }
        return jsonData;
    }

}
  1. 在启动类上添加MapperScan和EnableSwagger2的注解
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@MapperScan(basePackages = "com.kangswx.springbootswagger2.mapper")
@SpringBootApplication
@EnableSwagger2     //启动Swagger2
public class SpringbootSwagger2Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootSwagger2Application.class, args);
    }

}
  1. 启动SpringBoot项目,并访问 http://localhost:8081/swagger-ui.html
  2. 会看到Swagger生成的API文档
  3. 进行简单的测试,测试查询接口

输入id的参数后,点击Try it out!就会看到查询的结果

自动生成接口文档java_SpringBoot

  1. 测试添加

点击Try it out!,返回结果为

自动生成接口文档java_SpringBoot_02

  1. 测试删除

返回结果为

自动生成接口文档java_Swagger2_03