手写 Api 文档的几个痛点:
为了前后台更好的对接,为了以后交接方便,为了不再长篇大论的手写 api 文档,那么就来用Swagger吧(不是打广告,确实强),它可以轻松的整合到 Spring 中,它既可以减少我们手写 api 文档的时间,同时又将说明文档整合到我们的代码中,这样前台看着也方便,后台工作也舒坦。
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。Swagger 让部署管理和使用功能强大的API从未如此简单(其他好处网上自己搜在这里就不再多说了)。
官网地址: https://swagger.io/
本篇内容:
(1)构建多模块项目(可选单模块步骤)
(2)pom.xml 配置加载依赖
(3)Swagger 配置类(Bean)
(4)启动类配置
(5)创建工具类
(6)User 实例类
(7)定义 restful 接口(Controller 层)
为帮助快速入门上手使用,提供了简单的增删改查,使用的参数配置示例
本篇测试环境:
如果想使用多模块,请先构建项目(建议):
如果不想使用多模块(下面模块请根据自己项目修改)
Spring boot 项目都会有一些依赖,为了更直观,只贴必要的部分
为你的 Spring Boot 项目再增加下面两个依赖:
pom.xml 配置:
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>2.9.2version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>2.9.2version>
dependency>
注意:
用 @Configuration 注解该类,等价于XML中配置beans;
用 @Bean 标注方法等价于XML中配置bean
不是不可以使用 xml,提倡使用注解,是不是想起点什么?
SwaggerConfig.java 源代码:
package com.xpwi.main.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;
/**
* 描述:Swagger2 Config Bean
*
* @author Xiao Pengwei
* @since 2019-03-27
*/
@Configuration
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.xpwi"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("SpringBoot使用Swagger构建api文档")
.description("简单优雅的 restfun 风格 https://icode.blog.csdn.net")
.termsOfServiceUrl("https://icode.blog.csdn.net")
.version("1.0")
.build();
}
}
Application.class 加上注解 @EnableSwagger2 表示开启Swagger
package com.xpwi.main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.Date;
/**
* 描述:Spring Boot 多模块测试项目
* @author Xiao Pengwei
* @since 2019-03-25
*/
@EnableSwagger2
@SpringBootApplication
@RestController
//扫描 main,test 模块中的下的所有包
//在 pom 加载子模块依赖才可以扫包
@ComponentScan({"com.xpwi.main","com.xpwi.test","com.xpwi.login"})
public class App {
public static void main(String[] args) {
//启动 Web 容器
SpringApplication.run(App.class, args);
System.out.println("[启动成功]"+new Date());
}
}
用于返回通用数据格式的工具类
CommonResult.java 源代码:
package com.xpwi.main.util;
/**
* 描述:通用返回类型
* @author Xiao Pengwei
* @since 2019-03-27
*/
public class CommonResult {
private String status;
private Object result;
private Object message;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
public Object getMessage() {
return message;
}
public void setMessage(Object message) {
this.message = message;
}
}
User 模拟对应数据库字段的实体类
User.java 源代码:
package com.xpwi.main.entity;
import java.util.Date;
/**
* 描述:User 实体类
* @author Xiao Pengwei
* @since 2019-03-27
*/
public class User {
private String id;
private String username;
private int age;
private Date ctm;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getCtm() {
return ctm;
}
public void setCtm(Date ctm) {
this.ctm = ctm;
}
}
最重要的一步,也是开发中最常用的一步
创建 UserController.java 源代码:
package com.xpwi.main.controller;
import com.xpwi.main.entity.User;
import com.xpwi.main.util.CommonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.ResponseEntity;
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.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 描述:Controller 类
* @author Xiao Pengwei
* @since 2019-03-27
*/
@RestController
@Api(value = "用户测试模块")
public class UserController {
// 创建线程安全的Map
static Map<String, User> users = Collections.synchronizedMap(new HashMap<String, User>());
/**
* 根据ID查询用户
* @param id
* @return
*/
@ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String", paramType = "path")
@RequestMapping(value = "user/{id}", method = RequestMethod.GET)
public ResponseEntity<CommonResult> getUserById (@PathVariable(value = "id") String id){
CommonResult commonResult = new CommonResult();
try {
User user = users.get(id);
commonResult.setResult(user);
commonResult.setStatus("ok");
} catch (Exception e) {
commonResult.setResult(e.getClass().getName() + ":" + e.getMessage());
commonResult.setStatus("error");
e.printStackTrace();
}
return ResponseEntity.ok(commonResult);
}
/**
* 查询用户列表
* @return
*/
@ApiOperation(value="获取用户列表", notes="获取用户列表")
@RequestMapping(value = "users", method = RequestMethod.GET)
public ResponseEntity<CommonResult> getUserList (){
CommonResult commonResult = new CommonResult();
try {
List<User> userList = new ArrayList<User>(users.values());
commonResult.setResult(userList);
commonResult.setStatus("ok");
} catch (Exception e) {
commonResult.setResult(e.getClass().getName() + ":" + e.getMessage());
commonResult.setStatus("error");
e.printStackTrace();
}
return ResponseEntity.ok(commonResult);
}
/**
* 添加用户
* @param user
* @return
*/
@ApiOperation(value="创建用户", notes="根据User对象创建用户")
@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User")
@RequestMapping(value = "user", method = RequestMethod.POST)
public ResponseEntity<CommonResult> add (@RequestBody User user){
CommonResult commonResult = new CommonResult();
try {
users.put(user.getId(), user);
commonResult.setResult(user.getId());
commonResult.setStatus("ok");
} catch (Exception e) {
commonResult.setResult(e.getClass().getName() + ":" + e.getMessage());
commonResult.setStatus("error");
e.printStackTrace();
}
return ResponseEntity.ok(commonResult);
}
/**
* 根据id删除用户
* @param id
* @return
*/
@ApiOperation(value="删除用户", notes="根据url的id来指定删除用户")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String", paramType = "path")
@RequestMapping(value = "user/{id}", method = RequestMethod.DELETE)
public ResponseEntity<CommonResult> delete (@PathVariable(value = "id") String id){
CommonResult commonResult = new CommonResult();
try {
users.remove(id);
commonResult.setResult(id);
commonResult.setStatus("ok");
} catch (Exception e) {
commonResult.setResult(e.getClass().getName() + ":" + e.getMessage());
commonResult.setStatus("error");
e.printStackTrace();
}
return ResponseEntity.ok(commonResult);
}
/**
* 根据id修改用户信息
* @param user
* @return
*/
@ApiOperation(value="更新信息", notes="根据url的id来指定更新用户信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "String",paramType = "path"),
@ApiImplicitParam(name = "user", value = "用户实体user", required = true, dataType = "User")
})
@RequestMapping(value = "user/{id}", method = RequestMethod.PUT)
public ResponseEntity<CommonResult> update (@PathVariable("id") String id, @RequestBody User user){
CommonResult commonResult = new CommonResult();
try {
User user1 = users.get(id);
user1.setUsername(user.getUsername());
user1.setAge(user.getAge());
users.put(id, user1);
commonResult.setResult(user1);
commonResult.setStatus("ok");
} catch (Exception e) {
commonResult.setResult(e.getClass().getName() + ":" + e.getMessage());
commonResult.setStatus("error");
e.printStackTrace();
}
return ResponseEntity.ok(commonResult);
}
@ApiIgnore//使用该注解忽略这个API
@RequestMapping(value = "/hi", method = RequestMethod.GET)
public String jsonTest() {
return " hi you!";
}
}
只需访问:
http://localhost:8080/swagger-ui.html
swagger-ui.html 是默认的,不用担心自己没有创建这个文件,这个就是那个 UI 咯
swagger 提供的常用的注解有:
一般swagger需要一下api的权限,需要在对应的模块进行排除
http://localhost:8080/swagger-resources/configuration/ui
http://localhost:8080/swagger-resources
http://localhost:8080/api-docs
http://localhost:8080/swagger-ui.html
http://localhost:8080/swagger-resources/configuration/security
如果项目上线并且需要关闭swagger接口,可以通过配置权限,或者再SwaggerConfig里面
return new Docket的时候加多一个.enable(false)