# springboot-swagger-learn **Repository Path**: MRLH/springboot-swagger-learn ## Basic Information - **Project Name**: springboot-swagger-learn - **Description**: springboot集成swagger示例 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2017-12-06 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Spring Boot中使用Swagger2构建强大的RESTful API文档 由于Spring Boot能够快速开发、便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API。而我们构建RESTful API的目的通常都是由于多终端的原因,这些终端会共用很多底层业务逻辑,因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端。 这样一来,我们的RESTful API就有可能要面对多个开发人员或多个开发团队:IOS开发、Android开发或是Web开发等。为了减少与其他团队平时开发期间的频繁沟通成本,传统做法我们会创建一份RESTful API文档来记录所有接口细节,然而这样的做法有以下几个问题: - 由于接口众多,并且细节复杂(需要考虑不同的HTTP请求类型、HTTP头部信息、HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳。 - 随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象。 为了解决上面这样的问题,本文将介绍RESTful API的重磅好伙伴Swagger2,它可以轻松的整合到Spring Boot中,并与Spring MVC程序配合组织出强大RESTful API文档。它既可以减少我们创建文档的工作量,同时说明内容又整合入实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API。 下面来具体介绍,如果在Spring Boot中使用Swagger2。首先,我们需要一个Spring Boot实现的RESTful API工程。 ## 添加Swagger2依赖 在`pom.xml`中加入Swagger2的依赖 ```xml io.springfox springfox-swagger2 2.7.0 io.springfox springfox-swagger-ui 2.7.0 ``` ## 创建Swagger2配置类 在`Application.java`同级创建Swagger2的配置类Swagger2。 ```java @Configuration @EnableSwagger2 public class Swagger2 { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.learn.demo.web")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Spring Boot中使用Swagger2构建RESTful APIs") .description("api文档") .termsOfServiceUrl("localhost") .contact("xxx") .version("1.0") .build(); } } ``` 如上代码所示,通过`@Configuration`注解,让Spring来加载该类配置。再通过`@EnableSwagger2`注解来启用Swagger2。 再通过`createRestApi`函数创建`Docket`的Bean之后,`apiInfo()`用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。`select()`函数返回一个`ApiSelectorBuilder`实例用来控制哪些接口暴露给Swagger来展现,本例采用指定扫描的包路径来定义,Swagger会扫描该包下所有Controller定义的API,并产生文档内容(除了被`@ApiIgnore`指定的请求)。 ## 添加文档内容 在完成了上述配置后,其实已经可以生产文档内容,但是这样的文档主要针对请求本身,而描述主要来源于函数等命名产生,对用户并不友好,我们通常需要自己增加一些说明来丰富文档内容。如下所示,我们通过`@ApiOperation`注解来给API增加说明、通过`@ApiImplicitParams`、`@ApiImplicitParam`注解来给参数增加说明。 ```java @RestController @RequestMapping(value="/users") // 通过这里配置使下面的映射都在/users下,可去除 public class UserController { static Map users = Collections.synchronizedMap(new HashMap()); @ApiOperation(value="获取用户列表", notes="") @RequestMapping(value={""}, method=RequestMethod.GET) public List getUserList() { List r = new ArrayList(users.values()); return r; } @ApiOperation(value="创建用户", notes="根据User对象创建用户") @RequestMapping(value="", method=RequestMethod.POST) @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "用户ID",defaultValue = "1", required = true, paramType = "form", dataType = "Long"), @ApiImplicitParam(name = "name", value = "用户姓名",defaultValue = "test", required = true, paramType = "form", dataType = "String"), @ApiImplicitParam(name = "age", value = "年龄", defaultValue = "22", required = true, paramType = "form", dataType = "Integer") }) public String postUser(@ModelAttribute User user) { users.put(user.getId(), user); return "success"; } @ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息") @ApiImplicitParam(name = "id", value = "用户ID",paramType = "path", required = true, dataType = "Long") @RequestMapping(value="/{id}", method=RequestMethod.GET) public User getUser(@PathVariable Long id) { return users.get(id); } @ApiOperation(value="更新用户详细信息", notes="根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "用户ID", required = true, paramType = "path", dataType = "Long"), @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User", paramType = "body") }) @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来指定删除对象") @RequestMapping(value="/{id}", method=RequestMethod.DELETE) public String deleteUser(@PathVariable Long id) { users.remove(id); return "success"; } } ``` 完成上述代码添加上,启动Spring Boot程序,访问:http://localhost:8080/swagger-ui.html。 就能看到RESTful API的页面。 ## 生产环境屏蔽Swagger2 配置文件中加上注解 ```java @Configuration @EnableSwagger2 @Profile("!prod") public class Swagger2 { //... } ``` 新增`DisableSwaggerUiController`禁用swagger-ui.html ```java @Profile("prod") @RestController @ApiIgnore public class DisableSwaggerUiController { // prod禁用swagger-ui.html @RequestMapping(value = "swagger-ui.html", method = RequestMethod.GET) public void getSwagger(HttpServletResponse httpResponse) throws IOException { httpResponse.setStatus(HttpStatus.NOT_FOUND.value()); } } ``` ## Api注解说明 |作用范围 | API | 使用位置| |---|---|---| |对象属性 |@ApiModelProperty |用在出入参数对象的字段上| |协议集描述 |@Api |用于controller类上| |协议描述 |@ApiOperation |用在controller的方法上| |Response集 |@ApiResponses |用在controller的方法上| |Response |@ApiResponse |用在 @ApiResponses里边| |非对象参数集 |@ApiImplicitParams |用在controller的方法上| |非对象参数描述 |@ApiImplicitParam |用在@ApiImplicitParams的方法里边| |描述返回对象的意义 |@ApiModel |用在返回对象类上| ### @ApiImplicitParam |属性 |取值 |作用| |---|---|---| |paramType | | 查询参数类型 | | |path |以地址的形式提交数据| | |query |直接跟参数完成自动映射赋值| | |body |以流的形式提交 仅支持POST| | |header |参数在request headers 里边提交| | |form |以form表单的形式提交 仅支持POST| |dataType| | 参数的数据类型 只作为标志说明,并没有实际验证| | |Long| | | |String | | |name | |接收参数名| |value | |接收参数的意义描述| |required | | 参数是否必填| | |true |必填| | |false |非必填| |defaultValue | | 默认值| ### 参数类型(paramType)示例 - path ```java @RestController @RequestMapping(value="/users") public class UserController { @ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息") @ApiImplicitParam(name = "id", value = "用户ID",paramType = "path", required = true, dataType = "Long") @RequestMapping(value="/{id}", method=RequestMethod.GET) public User getUser(@PathVariable Long id) { return users.get(id); } } ``` - query ```java @RestController @RequestMapping(value="/users") public class UserController { @ApiOperation(value="根据id查询用户", notes="根据id查询用户") @RequestMapping(value="/getUserById", method=RequestMethod.GET) @ApiImplicitParam(name = "id", value = "用户ID",paramType = "query", required = true, dataType = "Long") public User getUserById(@RequestParam Long id) { return users.get(id); } } ``` - body (接收json格式类型) ```java @RestController @RequestMapping(value="/users") public class UserController { @ApiOperation(value="更新用户", notes="json数据") @RequestMapping(value="/updateUser", method=RequestMethod.POST) @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User", paramType = "body") public String updateUser(@RequestBody User user) { if (users.get(user.getId()) == null) { return "failed"; } users.put(user.getId(), user); return "success"; } } ``` - form ```java @RestController @RequestMapping(value="/users") public class UserController { @ApiOperation(value="添加用户", notes="form数据") @RequestMapping(value="/addUser", method=RequestMethod.POST) @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "用户id",defaultValue = "1", required = true, paramType = "form", dataType = "String"), @ApiImplicitParam(name = "name", value = "用户姓名",defaultValue = "test", required = true, paramType = "form", dataType = "String"), @ApiImplicitParam(name = "age", value = "年龄", defaultValue = "22", required = true, paramType = "form", dataType = "Integer") }) public String addUser(@ModelAttribute User user) { users.put(user.getId(), user); return "success"; } } ``` 本文参考文章: http://blog.didispace.com/springbootproperties/ http://blog.didispace.com/springbootswagger2/ http://blog.csdn.net/xupeng874395012/article/details/68946676