简介:
RESTful作为一种软件设计风格得到越来越多的人的认可;同时开发接口文档的整理、更新及调试也一直是项目开发及维护过程中可以说是一个诟病。相信下面所展示的Swagger2构建RESTful API文档能够很好的解决大部分问题。
环境:
jdk1.8;spring boot2.0.2;Maven3.3;swagger 2.8.0
步骤:
1.添加依赖
本文引用最新的2.8.0
<!-- 引入swagger依赖最新版本2.8.0 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
2.配置Swagger2配置类
Swagger2.java类需放在与Application.java同级
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.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
//引入注解启用Swagger2
@Configuration
@EnableSwagger2
public class Swagger2 {
/**
* 通过createRestApi函数创建Docket的Bean之后,apiInfo()用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。
* select()函数返回一个ApiSelectorBuilder实例用来控制哪些接口暴露给Swagger来展现, 本例采用指定扫描的包路径来定义,
* Swagger会扫描该包下所有Controller定义的API,并产生文档内容(除了被@ApiIgnore指定的请求)。
*
* @return
*/
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
.apis(RequestHandlerSelectors.basePackage("com.example.demo")).paths(PathSelectors.any()).build();
}
/**
* 构建api主页信息
*
* @return
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("Spring Boot2.0学习")
.description("更多Spring Boot2.0相关文章请关注https://blog.csdn.net/u010904188/article/category/7690462")
.termsOfServiceUrl("https://blog.csdn.net/")
.contact(
new Contact("cc", "https://blog.csdn.net/u010904188/article/category/7690462", "880888@qq.com"))
.version("1.0").build();
}
}
3.接口添加注解
一般依次会添加类说明(@Api),方法说明(@ApiOperation),参数说明(@ApiImplicitParam或@ApiImplicitParams);
若不想方法和类添加到swagger api中则使用注解@ApiIgnore
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 com.example.demo.test1.pojo.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;
//Spring4之后加入的注解,原来在@Controller中返回json需要@ResponseBody来配合,
//如果直接用@RestController替代@Controller就不需要再配置@ResponseBody,默认返回json格式。
@RestController
@RequestMapping(value = "/testSwagger")
// 指明类作用,前端展示格式为tags+description
@Api(value = "testSwaggerController", tags = { "用户管理接口" }, description = "测试Swagger2")
public class TestSwaggerController {
// 创建线程安全的Map
static Map<Long, User> users = Collections.synchronizedMap(new HashMap<Long, User>());
@ApiOperation(value = "获取用户列表", notes = "")
@RequestMapping(value = { "" }, method = RequestMethod.GET)
public List<User> getUserList() {
List<User> r = new ArrayList<User>(users.values());
return r;
}
// 添加方法描述
@ApiOperation(value = "创建用户", notes = "根据User对象创建用户")
// 添加参数描述
@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User", paramType = "body")
@RequestMapping(value = "", method = RequestMethod.POST)
// 指明参数取值类型为RequestBody
public String postUser(@RequestBody User user) {
users.put(user.getId(), user);
return "success";
}
@ApiOperation(value = "获取用户详细信息", notes = "根据url的id来获取用户详细信息")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long", paramType = "path")
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
// 指明参数取值类型为PathVariable
public User getUser(@PathVariable Long id) {
return users.get(id);
}
@ApiOperation(value = "更新用户详细信息", notes = "根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息")
// 多个参数添加说明方式
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long", paramType = "path"),
@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User", paramType = "query") })
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public String putUser(@PathVariable Long id, @RequestBody User user) {
User u = users.get(id);
u.setName(user.getName());
u.setAge(user.getAge());
users.put(id, u);
return "success";
}
@ApiOperation(value = "删除用户", notes = "根据url的id来指定删除对象")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long", paramType = "path")
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public String deleteUser(@PathVariable Long id) {
users.remove(id);
return "success";
}
// 标注此注解则不添加到 Swagger Api中;也可直接标注到类上
@ApiIgnore
@RequestMapping(value = { "testApiIgnore" }, method = RequestMethod.GET)
public List<User> testApiIgnore() {
List<User> r = new ArrayList<User>(users.values());
return r;
}
}
4.实体添加注解
进行models管理,使用@ApiModel和@ApiModelProperty注解:
注意的是@ApiModel的value值需要和@ApiImplicitParam的dateType值一一对应;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "User", description = "用户对象user")
public class User {
// @ApiModelProperty()用于方法,字段; 表示对model属性的说明或者数据操作更改
// value–字段说明
// name–重写属性名字
// dataType–重写属性类型
// required–是否必填
// example–举例说明
// hidden–隐藏
@ApiModelProperty(value = "id", name = "id", example = "1", required = true)
private Long id;
@ApiModelProperty(value = "名称", name = "id", example = "cc")
private String name;
@ApiModelProperty(value = "年龄", name = "id", example = "18", hidden = true)
private Integer age;
}
5.访问时使用
访问路径问baseurl+/swagger-ui.html;效果如下图:
可使用Try it out按钮进行接口参数编写,点击蓝色按钮execute进行接口请求,返回请求信息;
6.RESTful格式test类
如下,注意参数和请求类型
@Test
public void testSwagger2() {
MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
form.set("id", 1);
form.set("name", "cc");
form.set("age", 18);
ResponseEntity<String> entity = this.restTemplate.exchange("/testSwagger/users/", HttpMethod.POST,
new HttpEntity<>(form, null), String.class);
System.out.println(entity.getStatusCode());
System.out.println(entity.getBody());
ResponseEntity<String> entity1 = this.restTemplate.exchange("/testSwagger/users/", HttpMethod.GET,
new HttpEntity<>(form, null), String.class);
System.out.println(entity1.getStatusCode());
System.out.println(entity1.getBody());
ResponseEntity<String> entity2 = this.restTemplate.exchange("/testSwagger/users/1?id=1&name=ccc&age=28", HttpMethod.PUT,
new HttpEntity<>(null, null), String.class);
System.out.println(entity2.getStatusCode());
System.out.println(entity2.getBody());
ResponseEntity<String> entity3 = this.restTemplate.exchange("/testSwagger/users/", HttpMethod.GET,
new HttpEntity<>(form, null), String.class);
System.out.println(entity3.getStatusCode());
System.out.println(entity3.getBody());
}
常用注解参考:
- @Api:用在类上,说明该类的作用
- @ApiOperation:用在方法上,说明方法的作用
- @ApiImplicitParams:用在方法上包含一组参数说明
- @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
- paramType:参数放在哪个地方
- header-->请求参数的获取:@RequestHeader
- query-->请求参数的获取:@RequestParam
- path(用于restful接口)-->请求参数的获取:@PathVariable
- body(不常用)
- form(不常用)
- name:参数名
- dataType:参数类型
- required:参数是否必须传
- value:参数的意思
- defaultValue:参数的默认值
- paramType:参数放在哪个地方
- @ApiResponses:用于表示一组响应
- @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
- code:数字,例如400
- message:信息,例如"请求参数没填好"
- response:抛出异常的类
- @ApiModel:描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候)
- @ApiModelProperty:描述一个model的属性、
- value:字段说明
- name:属性名称
- dataType:属性类型
- required:是否必填
- example:举例说明
- hidden:隐藏