写在前面

由于公司项目采用前后端分离,维护接口文档基本上是必不可少的工作。一个理想的状态是设计好后,接口文档发给前端和后端,大伙按照既定的规则各自开发,开发好了对接上了就可以上线了。当然这是一种非常理想的状态,而手写文档虽然可以解决一些问题,但是也存在以下痛点。

手写Api文档的几个痛点:

  1. 文档需要更新的时候,需要再次发送一份给前端,也就是文档更新交流不及时。
  2. 接口返回结果不明确
  3. 不能直接在线测试接口,通常需要使用工具,比如postman
  4. 接口文档太多,不好管理

还好,有一些工具可以减轻我们的工作量,Swagger2 就是其中之一。

本文以Demo示例展示一下在Spring Boot 中如何整合 Swagger2 。

Swagger2常用注解说明

swagger通过注解表明该接口会生成文档,包括接口名、请求方法、参数、返回信息的等等。

@Api:               修饰整个类,描述Controller的作用
@ApiOperation: 描述一个类的一个方法,或者说一个接口
@ApiParam: 单个参数描述
@ApiModel: 用对象来接收参数
@ApiModelProperty: 用对象接收参数时,描述对象的一个字段
@ApiResponse: HTTP响应其中1个描述
@ApiResponses: HTTP响应整体描述
@ApiIgnore: 使用该注解忽略这个API
@ApiError : 发生错误返回的信息
@ApiImplicitParam: 一个请求参数
@ApiImplicitParams: 多个请求参数

具体说明如下:

@Api:用在请求的类上,表示对类的说明
tags="说明该类的作用,可以在UI界面上看到的注解"
value="该参数没什么意义,在UI界面上也看到,所以不需要配置"
@ApiOperation:用在请求的方法上,说明方法的用途、作用
value="说明方法的用途、作用"
notes="方法的备注说明"
@ApiImplicitParams:用在请求的方法上,表示一组参数说明
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
name:参数名
value:参数的汉字说明、解释
required:参数是否必须传
paramType:参数放在哪个地方
· header --> 请求参数的获取:@RequestHeader
· query --> 请求参数的获取:@RequestParam
· path(用于restful接口)--> 请求参数的获取:@PathVariable
· body(不常用)
· form(不常用)
dataType:参数类型,默认String,其它值dataType="Integer"
defaultValue:参数的默认值
@ApiResponses:用在请求的方法上,表示一组响应
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
code:数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
@ApiModel:用于响应类上,表示一个返回响应数据的信息
(这种一般用在post创建的时候,使用@RequestBody这样的场景,
请求参数无法使用@ApiImplicitParam注解进行描述的时候)
@ApiModelProperty:用在属性上,描述响应类的属性

SpringBoot整合Swagger2进行CRUD操作

数据准备:

数据库名:springboottest,表名:ss_company

建表语句:

DROP TABLE IF EXISTS ss_company;
CREATE TABLE ss_company (
id varchar(40) NOT NULL COMMENT 'ID',
name varchar(255) DEFAULT NULL COMMENT '公司名称',
expiration_date datetime DEFAULT NULL COMMENT '到期时间',
address varchar(255) DEFAULT NULL COMMENT '公司地址',
license_id varchar(255) DEFAULT NULL COMMENT '营业执照-图片',
representative varchar(255) DEFAULT NULL COMMENT '法人代表',
phone varchar(255) DEFAULT NULL COMMENT '公司电话',
company_size varchar(255) DEFAULT NULL COMMENT '公司规模',
industry varchar(255) DEFAULT NULL COMMENT '所属行业',
remarks varchar(255) DEFAULT NULL COMMENT '备注',
state int(2) DEFAULT '' COMMENT '状态',
balance double DEFAULT NULL COMMENT '当前余额',
city varchar(20) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

数据插入语句:

INSERT INTO ss_company VALUES ('', '字节跳动', null, '北京', 'xxx002', '张某', '', '10000人以上', '互联网', '互联网公司', '', '', '北京');
INSERT INTO ss_company VALUES ('', '百度', null, '北京市海淀区', 'bzd001', '李某', '', '5000-10000人', '计算机', '', '', '', '北京');
INSERT INTO ss_company VALUES ('', '阿里巴巴', null, '中国杭州市滨江区', 'bzd002', '马某', '', '5000-10000人', '电子商务', '', '', '', '杭州');
INSERT INTO ss_company VALUES ('', '腾讯', null, '深圳市南山区', 'bzd003', '马某', '', '5000-10000人', '游戏', '', '', '', '深圳');

1>  创建SpringBoot工程,导入pom文件依赖

  application.yml配置:
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboottest?characterEncoding=utf-8
username: root
password: root server:
port: 8090

      pom依赖:

<dependencies>
<!-- SpringBoot 启动器 web依赖 -->
<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.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency> <!--jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency> <!--springboot支持的是jpa,mybatisplus自己做了启动器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- lombok插件依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency> <!-- SpringBoot测试启动依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

2>  创建pojo实体类

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import java.io.Serializable;
import java.util.Date; @Data
@TableName("ss_company")
@ApiModel(value = "公司实体类")
public class Company implements Serializable {
/**
* AUTO : AUTO(0, "数据库ID自增"),
* INPUT : INPUT(1, “用户输入ID”),
* ID_WORKER : ID_WORKER(2, "全局唯一ID"),默认值如果不设置会在用该策略
* UUID : UUID(3, "全局唯一ID"),
* NONE : NONE(4, "该类型为未设置主键类型"),
* ID_WORKER_STR : ID_WORKER_STR(5, "字符串全局唯一ID");
*/
@TableId(type = IdType.UUID)
@ApiModelProperty(value = "主键Id")
private String id; @ApiModelProperty(value = "公司名称")
private String name; @ApiModelProperty(value = "到期时间")
private Date expirationDate; @ApiModelProperty(value = "公司地址")
private String address; @ApiModelProperty(value = "营业执照")
private String licenseId; @ApiModelProperty(value = "法人代表")
private String representative; @ApiModelProperty(value = "公司电话")
private String phone; @ApiModelProperty(value = "公司规模")
private String companySize; @ApiModelProperty(value = "所属行业")
private String industry; @ApiModelProperty(value = "备注")
private String remarks; @ApiModelProperty(value = "公司状态")
private Integer state; @ApiModelProperty(value = "当前余额")
private Double balance; @ApiModelProperty(value = "公司所在地")
private String city; private static final long serialVersionUID = 1L;
}

3>  创建Result类(建议)

备注:Result类主要是在测试的时候,给出提示信息

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; @ApiModel(value = "返回结果类")
public class Result implements Serializable { @ApiModelProperty(value = "状态判断")
private boolean success; @ApiModelProperty(value = "返回消息内容")
private String message; public Result(boolean success,String message) {
this.message = message;
this.success = success;
} public boolean isSuccess() {
return success;
} public void setSuccess(boolean success) {
this.success = success;
} public String getMessage() {
return message;
} public void setMessage(String message) {
this.message = message;
}
}

4>  创建Dao接口

备注:由于com.baomidou.mybatisplus.core.mapper包已经封装了CRUD功能,所以这里的Dao接口只需继承对应的BaseMapper<Company>接口就可以了

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

public interface CompanyDao extends BaseMapper<Company> {
}

5>  创建Service接口

import java.util.List;

public interface CompanyService {
//查询所有
List<Company> findAll(); //单一查询
Company findOne(String id); //更新
void update(Company company); //添加
void add(Company company); //删除
void delete(String id);
}

6>  创建ServiceImpl实现类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.util.List; @Service
public class CompanyServiceImpl implements CompanyService {
@Autowired
private CompanyDao companyDao; @Override
public List<Company> findAll() {
return companyDao.selectList(null);
} @Override
public Company findOne(String id) {
return companyDao.selectById(id);
} @Override
public void update(Company company) {
companyDao.updateById(company);
} @Override
public void add(Company company) {
companyDao.insert(company);
} @Override
public void delete(String id) {
companyDao.deleteById(id);
}
}

7>   创建Controller类

import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import java.util.List; @Api("Swagger示例CRUD操作")
@RestController
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService; //查询所有
@ApiOperation("获取公司列表")
@GetMapping
public List<Company> findAll(){
return companyService.findAll();
} //查询单一
@ApiOperation(value = "根据id获取公司信息",notes = "id必须是数字")
@ApiImplicitParams({@ApiImplicitParam(name = "id",value = "id",required = true,paramType = "path")})
@ApiResponses({@ApiResponse(code=400,message="id为空")})
@GetMapping("/{id}")
public Company findById(@PathVariable("id") String id){
return companyService.findOne(id);
} //添加
@ApiOperation("新增公司信息")
@ApiImplicitParam(name = "company", value = "单个公司信息", dataType = "Company")
@PostMapping
public Result add(@RequestBody Company company){
try {
companyService.add(company);
return new Result(true,"新增成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"新增失败");
}
} //修改
@ApiOperation("修改公司信息")
@ApiImplicitParam(name = "company", value = "单个公司信息", dataType = "Company")
@PutMapping
public Result update(@RequestBody Company company){
try {
companyService.update(company);
return new Result(true,"修改成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"修改失败");
}
} //删除
@ApiOperation("删除用户")
@ApiImplicitParam(name = "id", value = "单个用户信息", dataType = "String")
@DeleteMapping("/{id}")
public Result delete(@PathVariable("id") String id){
try {
companyService.delete(id);
return new Result(true,"删除成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"删除失败");
}
}
}

8>  创建Controller类

import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import java.util.List; @Api(tags = "Swagger示例CRUD操作")
@RestController
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService; //查询所有
@ApiOperation("获取公司列表")
@GetMapping
public List<Company> findAll(){
return companyService.findAll();
} //查询单一
@ApiOperation(value = "根据id获取公司信息",notes = "id必须是数字")
@ApiImplicitParams({@ApiImplicitParam(name = "id",value = "id",required = true,paramType = "path")})
@ApiResponses({@ApiResponse(code=400,message="id为空")})
@GetMapping("/{id}")
public Company findById(@PathVariable("id") String id){
return companyService.findOne(id);
} //添加
@ApiOperation("新增公司信息")
@ApiImplicitParam(name = "company", value = "单个公司信息", dataType = "Company")
@PostMapping
public Result add(@RequestBody Company company){
try {
companyService.add(company);
return new Result(true,"新增成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"新增失败");
}
} //修改
@ApiOperation("修改公司信息")
@ApiImplicitParam(name = "company", value = "单个公司信息", dataType = "Company")
@PutMapping
public Result update(@RequestBody Company company){
try {
companyService.update(company);
return new Result(true,"修改成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"修改失败");
}
} //删除
@ApiOperation("删除用户")
@ApiImplicitParam(name = "id", value = "单个用户信息", dataType = "String")
@DeleteMapping("/{id}")
public Result delete(@PathVariable("id") String id){
try {
companyService.delete(id);
return new Result(true,"删除成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"删除失败");
}
}
}

9>  创建Swagger2配置类

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;
import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(restApiInfo())
.select()
// 指定包名
.apis(RequestHandlerSelectors.basePackage("com.darren.springbootswaggerdemo.controller"))
.paths(PathSelectors.any())
.build();
} private ApiInfo restApiInfo() {
return new ApiInfoBuilder()
.title("springboot利用swagger2构建api文档")
.description("简单优雅的restful风格")
.termsOfServiceUrl("no terms of serviceUrl")
.version("1.0")
.build();
}
}

备注说明:

这里提供的配置类,首先通过 @EnableSwagger2 注解启用 Swagger2 ,然后配置一个 Docket Bean,这个 Bean 中,配置映射路径和要扫描的接口的位置,

在 apiInfo 中,主要配置一下 Swagger2 文档网站的信息,例如网站的 title,网站的描述,联系人信息,使用的协议,版本信息,许可证信息等等。

至此,SpringBoot整合Swagger2示例Demo已配置完成,下面启动SpringBoot启动类测试,然后打开浏览器,在地址栏中输入:

http://localhost:8090/swagger-ui.html

能够看到如下界面,说明配置已成功

 可以看到,所有的接口这里都列出来了,包括接口请求方式,接口地址以及接口的名字等,点开一个接口,可以看到如下信息,

点击右上角的 Try it out,就可以进行接口测试:

点击 Execute 按钮,表示发送请求进行测试。测试结果会展示在下面的 Response 中。

 除此之外,其他的功能测试,还有一些响应值的注解,大家也都可以自己摸索下。

至此,SpringBoot整合Swagger2示例已完成,又可以浪一会啦。。。。。。。。。。。。。。。。

SpringBoot整合Swagger2(Demo示例)的更多相关文章

  1. SpringBoot整合Swagger2详细教程

    1. 简介   随着前后端分离开发模式越来越流行,编写接口文档变成了开发人员非常头疼的事.而Swagger是一个规范且完整的web框架,用于生成.描述.调用可视化的RESTful风格的在线接口文档,并 ...

  2. SpringBoot(七):SpringBoot整合Swagger2

    原文地址:https://blog.csdn.net/saytime/article/details/74937664 手写Api文档的几个痛点: 文档需要更新的时候,需要再次发送一份给前端,也就是文 ...

  3. SpringBoot整合Swagger2

    相信各位在公司写API文档数量应该不少,当然如果你还处在自己一个人开发前后台的年代,当我没说,如今为了前后台更好的对接,还是为了以后交接方便,都有要求写API文档. 手写Api文档的几个痛点: 文档需 ...

  4. springboot 整合Swagger2的使用

    Swagger2相较于传统Api文档的优点 手写Api文档的几个痛点: 文档需要更新的时候,需要再次发送一份给前端,也就是文档更新交流不及时. 接口返回结果不明确 不能直接在线测试接口,通常需要使用工 ...

  5. SpringBoot整合Swagger2案例,以及报错:java.lang.NumberFormatException: For input string: ""原因和解决办法

    原文链接:https://blog.csdn.net/weixin_43724369/article/details/89341949 SpringBoot整合Swagger2案例 先说SpringB ...

  6. SpringBoot整合Swagger2及使用

    简介 swagger是一个流行的API开发框架,这个框架以"开放API声明"(OpenAPI Specification,OAS)为基础, 对整个API的开发周期都提供了相应的解决 ...

  7. SpringBoot整合websocket简单示例

    依赖 <!-- springboot整合websocket --> <dependency> <groupId>org.springframework.boot&l ...

  8. SpringBoot整合Swagger2,再也不用维护接口文档了!

    前后端分离后,维护接口文档基本上是必不可少的工作.一个理想的状态是设计好后,接口文档发给前端和后端,大伙按照既定的规则各自开发,开发好了对接上了就可以上线了.当然这是一种非常理想的状态,实际开发中却很 ...

  9. Java学习之SpringBoot整合SSM Demo

    背景:在Java Web中Spring家族有着很重要的地位,之前JAVA开发需要做很多的配置,一堆的配置文件和部署调试一直是JavaWeb开发中的一大诟病,但现在Spring推出了SpringBoot ...

随机推荐

  1. freemarker常见语法

    FreeMarker的插值有如下两种类型:1,通用插值${expr};2,数字格式化插值:#{expr}或#{expr;format}  ${basketball.name?if_exists } / ...

  2. mybatis <=或这个>=提示错误Tag name expecte问题解决

    解决方案: 1.将<号或者>号进行转义 DATE_SUB(CURDATE(), INTERVAL 31 DAY) <= DATE(created) 2.使用<![CDATA[ ...

  3. jQuery三级联动效果代码(省、市、区)

    很长时间都不用jquery了,有人问我jquery写三级联动的插件我就写好了发出来吧,正好需要的人都可以看看. 一.html代码 <!DOCTYPE html> <html> ...

  4. 【maven的使用】2使用maven与pom文件

    一.使用maven:首先需要知道的是,在我们开发人员中有一句话叫做:约定优于配置.比如,如果我们写代码有多种可选方案:硬编码形式:obj.setPath("d:/xxxx") .配 ...

  5. mac下idea中安装docker插件

    idea中安装docker插件: 点击Intellij IDEA->Preferences...->Plugins->Browse repositories...如下: 点击Inst ...

  6. 利用npm安装/删除/查看包信息

    查看远程服务器上的包的版本信息 npm view webpack version //查看npm服务器上包webpack的最新版本 npm view webpack versions //查看服务器上 ...

  7. 【NOIP模拟赛】小奇挖矿 2

    [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿石交易市场,以便为飞船升级无限非概率引擎. [问题描述] 现在有m+1个星球,从左到右标号为0到m,小奇最初在0 ...

  8. 【元学习】Meta Learning 介绍

    目录 元学习(Meta-learning) 元学习被用在了哪些地方? Few-Shot Learning(小样本学习) 最近的元学习方法如何工作 Model-Agnostic Meta-Learnin ...

  9. ubuntu使用uwsgi+nginx部署django

    ls -lha export WORKON_HOME=~/venv source /usr/local/bin/vitualenvwrapper.sh VIRTUALENVWRAPPER_PYTHON ...

  10. ZGC介绍

    zgc是一款可拓展的低时延,为实现以下几个目标而诞生的垃圾回收器: 停顿时间不超过10ms 停顿时间不会导致堆大小增长 堆大小范围可支持几G到几T 再看一下zgc的标签: region-based ( ...