why
现在的开发开始倾向于前后端分离的方式,而前后端分离必然会有API文档来为前后端提供一个交互的桥梁。传统的word文档不仅编写麻烦,后期的版本维护也是一大问题。
waht
Swagger就能满足我们对维护和测试API文档提供用户友好的UI界面, 现在Swagger已被Spring集成,更加方便我们在spring项目中使用。
Swagger说明链接
这里就不给发官方网址了,但想要更准确的了解swagger还是去官网更好
how
- 添加swagger依赖
<!-- swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency>
- swagger的配置
Swagger2.java 源码文件要放在Application.java 同一包下
package com.demo.swagger;
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;
/**
* Swagger2 培养类
* 在与spring boot集成时,放在Application.java文件同包下
* @Configuration 用于启动这个类地配置
* @EnableSwagger2 用来启动Swagger2
*/
@Configuration
@EnableSwagger2
public class Swagger2 {
/**
* 创建api应用
* apiInfo()增加API相关信息
* 通过select函数返回一个ApiSelectorBuilder实例,用来控制将哪些接口保罗给swagger管理
* 本例采用扫描指定包路径来ding'yi要建立地api地目录
* @return
*/
@Bean
public Docket CreateRestApi(){
return new Docket(DocumentationType.SWAGGER_2).
apiInfo(apiInfo()).
select().
apis(RequestHandlerSelectors.basePackage("com.demo.swagger.controller")).
paths(PathSelectors.any()).
build();
}
/**
* 创建api的基本信息,这些信息会展示在文档页面
* 访问地址:http://项目实际地址/swagger-ui.html
* @return
*/
private ApiInfo apiInfo(){
return new ApiInfoBuilder().
title("在spring boot中使用swagger2 来构建RESTFUL APIS").
description("更多关注com.gz").termsOfServiceUrl("http://www.baidu.com").
contact("sunf").version("1.0").build();
}
}
- controller层调用样例
package com.demo.swagger.controller;
import com.alibaba.fastjson.JSONObject;
import com.demo.swagger.entity.User;
import com.demo.swagger.mapper.UserDao;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("user")
@Api("用户信息操作接口集")
public class HelloController {
@Autowired
UserDao userDao;
/**
* @GetMapping 可以不设置参数 这里拦截的是 /user/ Get
* @ApiOperation value 用于描述这个接口的功能,notes 用户更详细地说明用法
* @ApiImplicatitParam 用于说明一个入参信息,paramType 描述参数存放地位置(header、query、path、body、form)
* name 描述参数的名称 value 描述参数的含义 dataType 描述参数的基本类型
* @ApiImplicatitParams 用于说明一组入参信息,当有多个入参时需要用这个将上一个注解包含起来
* @ApiResponse 描述返回的信息, code 指的状态编码, message 指的具体描述, response 能返回一个实体类, 这个注解一般用于说明异常的情况
* @ApiResponses 可以包含多个上一个注解,上一个注解单独使用时没有生效
* @param userName
* @return
*/
@GetMapping
@ApiOperation(value = "获取用户信息", notes = "根据用户名获取用户信息")
@ApiImplicitParam(paramType = "query", name = "userName", value = "用户名", dataType = "String")
@ApiResponses({
@ApiResponse(code = 401, message = "没找到用户", response = Exception.class)
})
public User getUserInfo(@RequestParam String userName) {
return userDao.selectByUserName(userName);
}
/**
* 添加用户信息
* @param user
* @return
*/
@PostMapping
@ApiOperation(value = "添加用户", notes = "用户名、密码 必填")
@ApiResponses({
@ApiResponse(code = 401, message = "错误的用户", response = User.class)
})
public Object addUserInfo(@RequestBody @ApiParam(name = "用户对象", value = "传入json格式", required = true) User user){
userDao.insertUser(user);
return userDao.selects();
}
/**
* 修改用户密码
* @param userName
* @param password
* @return
*/
@PutMapping
@ApiOperation(value = "修改用户密码", notes = "输入用户名和密码")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "query", name = "userName", value = "用户名", dataType = "string"),
@ApiImplicitParam(paramType = "query", name = "password", value = "密码", dataType = "string")
})
@ApiResponses({
@ApiResponse(code = 500, message = "没有找到用户", response = User.class)
})
public Object updateUserPassword(@RequestParam String userName, @RequestParam String password){
userDao.updateUserPassword(userName, password);
return userDao.selectByUserName(userName);
}
/**
* 删除指定用户
* @param userName
* @return
*/
@DeleteMapping
@ApiOperation(value = "删除用户", notes = "根据指定用户名删除用户")
@ApiImplicitParam(paramType = "query", name = "userName", value = "用户名")
public Object deleteUser(@RequestParam String userName){
userDao.deleteByUserName(userName);
return userDao.selects();
}
}
-
附上注解说明
- 与模型相关的注解
两个注解:
@ApiModel:用在模型类上,对模型类做注释;
@ApiModelProperty:用在属性上,对属性做注释 - 与接口相关的注解
六个注解:
@Api:用在controller上,对controller进行注释;
@ApiOperation:用在API方法上,对该API做注释,说明API的作用;
@ApiImplicitParams:用来包含API的一组参数注解,可以简单的理解为参数注解的集合声明;
@ApiImplicitParam:用在@ApiImplicitParams注解中,也可以单独使用,说明一个请求参数的各个方面,该注解包含的常用选项有:
paramType:参数所放置的地方,包含query、header、path、body以及form,最常用的是前四个。
name:参数名;
dataType:参数类型,可以是基础数据类型,也可以是一个class;
required:参数是否必须传;
value:参数的注释,说明参数的意义;
defaultValue:参数的默认值;
@ApiResponses:通常用来包含接口的一组响应注解,可以简单的理解为响应注解的集合声明;
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
code:即httpCode,例如400
message:信息,例如"请求参数没填好"
- 与模型相关的注解
-
个人总结
- @Api 和 @ApiOperation 这两个注解是必须的,分别加载类上和方法上
- @ApiImplicitParam 在使用时,paramType 一般使用query, 但在涉及对象传入时就需要在对象上添加@ApiModel,在对象属性上加@ApiModelproperty,并在传入时,采用类似这种方式:
public Object addUserInfo( @RequestBody @ApiParam(name = "用户对象", value = "传入json格式", required = true) User user) { }
- @ApiResponses 一般时结合我们自定义的返回结果集类来使用,并且 不能单独写@ApiResponse, 必须要在外面包含一层@ApiResponses