Spring Boot多模块项目 整合Swagger2

LoveEmperor-王子様
本人项目demo(spring boot多模块):https://github.com/LoveEmperor/iproject
转载:https://blog.csdn.net/saytime/article/details/74937664

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

手写Api文档的几个痛点:

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

Swagger也就是为了解决这个问题,当然也不能说Swagger就一定是完美的,当然也有缺点,最明显的就是代码移入性比较强。

其他的不多说,想要了解Swagger的,可以去Swagger官网,可以直接使用Swagger editor编写接口文档,当然我们这里讲解的是SpringBoot整合Swagger2,直接生成接口文档的方式。

一、依赖


    
    
  1. <dependency>
  2. <groupId>io.springfox </groupId>
  3. <artifactId>springfox-swagger2 </artifactId>
  4. <version>2.6.1 </version>
  5. </dependency>
  6. <dependency>
  7. <groupId>io.springfox </groupId>
  8. <artifactId>springfox-swagger-ui </artifactId>
  9. <version>2.6.1 </version>
  10. </dependency>

二、Swagger配置类

其实这个配置类,只要了解具体能配置哪些东西就好了,毕竟这个东西配置一次之后就不用再动了。 特别要注意的是里面配置了api文件也就是controller包的路径,不然生成的文档扫描不到接口。


    
    
  1. package cn.saytime;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import springfox.documentation.builders.ApiInfoBuilder;
  5. import springfox.documentation.builders.PathSelectors;
  6. import springfox.documentation.builders.RequestHandlerSelectors;
  7. import springfox.documentation.service.ApiInfo;
  8. import springfox.documentation.spi.DocumentationType;
  9. import springfox.documentation.spring.web.plugins.Docket;
  10. /**
  11. * @author zh
  12. * @ClassName cn.saytime.Swgger2
  13. * @Description
  14. * @date 2017-07-10 22:12:31
  15. */
  16. @Configuration
  17. public class Swagger2 {
  18. @Bean
  19. public Docket createRestApi() {
  20. return new Docket(DocumentationType.SWAGGER_2)
  21. .apiInfo(apiInfo())
  22. .select()
  23. .apis(RequestHandlerSelectors.basePackage( "cn.saytime.web"))
  24. .paths(PathSelectors.any())
  25. .build();
  26. }
  27. private ApiInfo apiInfo() {
  28. return new ApiInfoBuilder()
  29. .title( "springboot利用swagger构建api文档")
  30. .description( "简单优雅的restfun风格,http://blog.csdn.net/saytime")
  31. .termsOfServiceUrl( "http://blog.csdn.net/saytime")
  32. .version( "1.0")
  33. .build();
  34. }
  35. }

用@Configuration注解该类,等价于XML中配置beans;用@Bean标注方法等价于XML中配置bean。

Application.class 加上注解@EnableSwagger2 表示开启Swagger


    
    
  1. package cn.saytime;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import springfox.documentation.swagger2.annotations.EnableSwagger2;
  5. @SpringBootApplication
  6. @EnableSwagger2
  7. public class SpringbootSwagger2Application {
  8. public static void main(String[] args) {
  9. SpringApplication.run(SpringbootSwagger2Application. class, args);
  10. }
  11. }

三、Restful 接口


    
    
  1. package cn.saytime.web;
  2. import cn.saytime.bean.JsonResult;
  3. import cn.saytime.bean.User;
  4. import io.swagger.annotations.Api;
  5. import io.swagger.annotations.ApiImplicitParam;
  6. import io.swagger.annotations.ApiImplicitParams;
  7. import io.swagger.annotations.ApiOperation;
  8. import org.springframework.http.ResponseEntity;
  9. import org.springframework.web.bind. annotation.PathVariable;
  10. import org.springframework.web.bind. annotation.RequestBody;
  11. import org.springframework.web.bind. annotation.RequestMapping;
  12. import org.springframework.web.bind. annotation.RequestMethod;
  13. import org.springframework.web.bind. annotation.RestController;
  14. import springfox.documentation.annotations.ApiIgnore;
  15. import java.util.ArrayList;
  16. import java.util.Collections;
  17. import java.util.HashMap;
  18. import java.util.List;
  19. import java.util.Map;
  20. /**
  21. * @author zh
  22. * @ClassName cn.saytime.web.UserController
  23. * @Description
  24. */
  25. @RestController
  26. public class UserController {
  27. // 创建线程安全的Map
  28. static Map<Integer, User> users = Collections.synchronizedMap( new HashMap<Integer, User>());
  29. /**
  30. * 根据ID查询用户
  31. * @param id
  32. * @return
  33. */
  34. @ApiOperation (value= "获取用户详细信息" , notes= "根据url的id来获取用户详细信息" )
  35. @ApiImplicitParam (name = "id" , value = "用户ID" , required = true , dataType = "Integer" , paramType = "path" )
  36. @RequestMapping (value = "user/{id}" , method = RequestMethod.GET)
  37. public ResponseEntity<JsonResult> getUserById ( @PathVariable (value = "id" ) Integer id){
  38. JsonResult r = new JsonResult();
  39. try {
  40. User user = users. get(id);
  41. r.setResult(user);
  42. r.setStatus( "ok");
  43. } catch (Exception e) {
  44. r.setResult(e.getClass().getName() + ":" + e.getMessage());
  45. r.setStatus( "error");
  46. e.printStackTrace();
  47. }
  48. return ResponseEntity.ok(r);
  49. }
  50. /**
  51. * 查询用户列表
  52. * @return
  53. */
  54. @ApiOperation (value= "获取用户列表" , notes= "获取用户列表" )
  55. @RequestMapping (value = "users" , method = RequestMethod.GET)
  56. public ResponseEntity<JsonResult> getUserList (){
  57. JsonResult r = new JsonResult();
  58. try {
  59. List<User> userList = new ArrayList<User>(users.values());
  60. r.setResult(userList);
  61. r.setStatus( "ok");
  62. } catch (Exception e) {
  63. r.setResult(e.getClass().getName() + ":" + e.getMessage());
  64. r.setStatus( "error");
  65. e.printStackTrace();
  66. }
  67. return ResponseEntity.ok(r);
  68. }
  69. /**
  70. * 添加用户
  71. * @param user
  72. * @return
  73. */
  74. @ApiOperation (value= "创建用户" , notes= "根据User对象创建用户" )
  75. @ApiImplicitParam (name = "user" , value = "用户详细实体user" , required = true , dataType = "User" )
  76. @RequestMapping (value = "user" , method = RequestMethod.POST)
  77. public ResponseEntity<JsonResult> add ( @RequestBody User user){
  78. JsonResult r = new JsonResult();
  79. try {
  80. users.put(user.getId(), user);
  81. r.setResult(user.getId());
  82. r.setStatus( "ok");
  83. } catch (Exception e) {
  84. r.setResult(e.getClass().getName() + ":" + e.getMessage());
  85. r.setStatus( "error");
  86. e.printStackTrace();
  87. }
  88. return ResponseEntity.ok(r);
  89. }
  90. /**
  91. * 根据id删除用户
  92. * @param id
  93. * @return
  94. */
  95. @ApiOperation (value= "删除用户" , notes= "根据url的id来指定删除用户" )
  96. @ApiImplicitParam (name = "id" , value = "用户ID" , required = true , dataType = "Long" , paramType = "path" )
  97. @RequestMapping (value = "user/{id}" , method = RequestMethod.DELETE)
  98. public ResponseEntity<JsonResult> delete ( @PathVariable (value = "id" ) Integer id){
  99. JsonResult r = new JsonResult();
  100. try {
  101. users.remove(id);
  102. r.setResult(id);
  103. r.setStatus( "ok");
  104. } catch (Exception e) {
  105. r.setResult(e.getClass().getName() + ":" + e.getMessage());
  106. r.setStatus( "error");
  107. e.printStackTrace();
  108. }
  109. return ResponseEntity.ok(r);
  110. }
  111. /**
  112. * 根据id修改用户信息
  113. * @param user
  114. * @return
  115. */
  116. @ApiOperation (value= "更新信息" , notes= "根据url的id来指定更新用户信息" )
  117. @ApiImplicitParams ({
  118. @ApiImplicitParam (name = "id" , value = "用户ID" , required = true , dataType = "Long" ,paramType = "path" ),
  119. @ApiImplicitParam (name = "user" , value = "用户实体user" , required = true , dataType = "User" )
  120. })
  121. @RequestMapping (value = "user/{id}" , method = RequestMethod.PUT)
  122. public ResponseEntity<JsonResult> update ( @PathVariable ( "id" ) Integer id, @RequestBody User user){
  123. JsonResult r = new JsonResult();
  124. try {
  125. User u = users. get(id);
  126. u.setUsername(user.getUsername());
  127. u.setAge(user.getAge());
  128. users.put(id, u);
  129. r.setResult(u);
  130. r.setStatus( "ok");
  131. } catch (Exception e) {
  132. r.setResult(e.getClass().getName() + ":" + e.getMessage());
  133. r.setStatus( "error");
  134. e.printStackTrace();
  135. }
  136. return ResponseEntity.ok(r);
  137. }
  138. @ApiIgnore //使用该注解忽略这个API
  139. @RequestMapping (value = "/hi" , method = RequestMethod.GET)
  140. public String jsonTest() {
  141. return " hi you!";
  142. }
  143. }

Json格式输出类 JsonResult.class

扫描二维码关注公众号,回复: 1874461 查看本文章

    
    
  1. package cn.saytime.bean;
  2. public class JsonResult {
  3. private String status = null;
  4. private Object result = null;
  5. // Getter Setter
  6. }

实体User.class


    
    
  1. package cn.saytime.bean;
  2. import java.util.Date;
  3. /**
  4. * @author zh
  5. * @ClassName cn.saytime.bean.User
  6. * @Description
  7. */
  8. public class User {
  9. private int id;
  10. private String username;
  11. private int age;
  12. private Date ctm;
  13. // Getter Setter
  14. }

项目结构:

这里写图片描述

四、Swagger2文档

启动SpringBoot项目,访问 http://localhost:8080/swagger-ui.html

这里写图片描述

具体里面的内容以及接口测试,应该一看就懂了。这里就不一一截图了。

五、Swagger注解

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

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



            </div>

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

手写Api文档的几个痛点:

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

Swagger也就是为了解决这个问题,当然也不能说Swagger就一定是完美的,当然也有缺点,最明显的就是代码移入性比较强。

其他的不多说,想要了解Swagger的,可以去Swagger官网,可以直接使用Swagger editor编写接口文档,当然我们这里讲解的是SpringBoot整合Swagger2,直接生成接口文档的方式。

一、依赖


  
  
  1. <dependency>
  2. <groupId>io.springfox </groupId>
  3. <artifactId>springfox-swagger2 </artifactId>
  4. <version>2.6.1 </version>
  5. </dependency>
  6. <dependency>
  7. <groupId>io.springfox </groupId>
  8. <artifactId>springfox-swagger-ui </artifactId>
  9. <version>2.6.1 </version>
  10. </dependency>

二、Swagger配置类

其实这个配置类,只要了解具体能配置哪些东西就好了,毕竟这个东西配置一次之后就不用再动了。 特别要注意的是里面配置了api文件也就是controller包的路径,不然生成的文档扫描不到接口。


  
  
  1. package cn.saytime;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import springfox.documentation.builders.ApiInfoBuilder;
  5. import springfox.documentation.builders.PathSelectors;
  6. import springfox.documentation.builders.RequestHandlerSelectors;
  7. import springfox.documentation.service.ApiInfo;
  8. import springfox.documentation.spi.DocumentationType;
  9. import springfox.documentation.spring.web.plugins.Docket;
  10. /**
  11. * @author zh
  12. * @ClassName cn.saytime.Swgger2
  13. * @Description
  14. * @date 2017-07-10 22:12:31
  15. */
  16. @Configuration
  17. public class Swagger2 {
  18. @Bean
  19. public Docket createRestApi() {
  20. return new Docket(DocumentationType.SWAGGER_2)
  21. .apiInfo(apiInfo())
  22. .select()
  23. .apis(RequestHandlerSelectors.basePackage( "cn.saytime.web"))
  24. .paths(PathSelectors.any())
  25. .build();
  26. }
  27. private ApiInfo apiInfo() {
  28. return new ApiInfoBuilder()
  29. .title( "springboot利用swagger构建api文档")
  30. .description( "简单优雅的restfun风格,http://blog.csdn.net/saytime")
  31. .termsOfServiceUrl( "http://blog.csdn.net/saytime")
  32. .version( "1.0")
  33. .build();
  34. }
  35. }

用@Configuration注解该类,等价于XML中配置beans;用@Bean标注方法等价于XML中配置bean。

Application.class 加上注解@EnableSwagger2 表示开启Swagger


  
  
  1. package cn.saytime;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import springfox.documentation.swagger2.annotations.EnableSwagger2;
  5. @SpringBootApplication
  6. @EnableSwagger2
  7. public class SpringbootSwagger2Application {
  8. public static void main(String[] args) {
  9. SpringApplication.run(SpringbootSwagger2Application. class, args);
  10. }
  11. }

三、Restful 接口


  
  
  1. package cn.saytime.web;
  2. import cn.saytime.bean.JsonResult;
  3. import cn.saytime.bean.User;
  4. import io.swagger.annotations.Api;
  5. import io.swagger.annotations.ApiImplicitParam;
  6. import io.swagger.annotations.ApiImplicitParams;
  7. import io.swagger.annotations.ApiOperation;
  8. import org.springframework.http.ResponseEntity;
  9. import org.springframework.web.bind. annotation.PathVariable;
  10. import org.springframework.web.bind. annotation.RequestBody;
  11. import org.springframework.web.bind. annotation.RequestMapping;
  12. import org.springframework.web.bind. annotation.RequestMethod;
  13. import org.springframework.web.bind. annotation.RestController;
  14. import springfox.documentation.annotations.ApiIgnore;
  15. import java.util.ArrayList;
  16. import java.util.Collections;
  17. import java.util.HashMap;
  18. import java.util.List;
  19. import java.util.Map;
  20. /**
  21. * @author zh
  22. * @ClassName cn.saytime.web.UserController
  23. * @Description
  24. */
  25. @RestController
  26. public class UserController {
  27. // 创建线程安全的Map
  28. static Map<Integer, User> users = Collections.synchronizedMap( new HashMap<Integer, User>());
  29. /**
  30. * 根据ID查询用户
  31. * @param id
  32. * @return
  33. */
  34. @ApiOperation (value= "获取用户详细信息" , notes= "根据url的id来获取用户详细信息" )
  35. @ApiImplicitParam (name = "id" , value = "用户ID" , required = true , dataType = "Integer" , paramType = "path" )
  36. @RequestMapping (value = "user/{id}" , method = RequestMethod.GET)
  37. public ResponseEntity<JsonResult> getUserById ( @PathVariable (value = "id" ) Integer id){
  38. JsonResult r = new JsonResult();
  39. try {
  40. User user = users. get(id);
  41. r.setResult(user);
  42. r.setStatus( "ok");
  43. } catch (Exception e) {
  44. r.setResult(e.getClass().getName() + ":" + e.getMessage());
  45. r.setStatus( "error");
  46. e.printStackTrace();
  47. }
  48. return ResponseEntity.ok(r);
  49. }
  50. /**
  51. * 查询用户列表
  52. * @return
  53. */
  54. @ApiOperation (value= "获取用户列表" , notes= "获取用户列表" )
  55. @RequestMapping (value = "users" , method = RequestMethod.GET)
  56. public ResponseEntity<JsonResult> getUserList (){
  57. JsonResult r = new JsonResult();
  58. try {
  59. List<User> userList = new ArrayList<User>(users.values());
  60. r.setResult(userList);
  61. r.setStatus( "ok");
  62. } catch (Exception e) {
  63. r.setResult(e.getClass().getName() + ":" + e.getMessage());
  64. r.setStatus( "error");
  65. e.printStackTrace();
  66. }
  67. return ResponseEntity.ok(r);
  68. }
  69. /**
  70. * 添加用户
  71. * @param user
  72. * @return
  73. */
  74. @ApiOperation (value= "创建用户" , notes= "根据User对象创建用户" )
  75. @ApiImplicitParam (name = "user" , value = "用户详细实体user" , required = true , dataType = "User" )
  76. @RequestMapping (value = "user" , method = RequestMethod.POST)
  77. public ResponseEntity<JsonResult> add ( @RequestBody User user){
  78. JsonResult r = new JsonResult();
  79. try {
  80. users.put(user.getId(), user);
  81. r.setResult(user.getId());
  82. r.setStatus( "ok");
  83. } catch (Exception e) {
  84. r.setResult(e.getClass().getName() + ":" + e.getMessage());
  85. r.setStatus( "error");
  86. e.printStackTrace();
  87. }
  88. return ResponseEntity.ok(r);
  89. }
  90. /**
  91. * 根据id删除用户
  92. * @param id
  93. * @return
  94. */
  95. @ApiOperation (value= "删除用户" , notes= "根据url的id来指定删除用户" )
  96. @ApiImplicitParam (name = "id" , value = "用户ID" , required = true , dataType = "Long" , paramType = "path" )
  97. @RequestMapping (value = "user/{id}" , method = RequestMethod.DELETE)
  98. public ResponseEntity<JsonResult> delete ( @PathVariable (value = "id" ) Integer id){
  99. JsonResult r = new JsonResult();
  100. try {
  101. users.remove(id);
  102. r.setResult(id);
  103. r.setStatus( "ok");
  104. } catch (Exception e) {
  105. r.setResult(e.getClass().getName() + ":" + e.getMessage());
  106. r.setStatus( "error");
  107. e.printStackTrace();
  108. }
  109. return ResponseEntity.ok(r);
  110. }
  111. /**
  112. * 根据id修改用户信息
  113. * @param user
  114. * @return
  115. */
  116. @ApiOperation (value= "更新信息" , notes= "根据url的id来指定更新用户信息" )
  117. @ApiImplicitParams ({
  118. @ApiImplicitParam (name = "id" , value = "用户ID" , required = true , dataType = "Long" ,paramType = "path" ),
  119. @ApiImplicitParam (name = "user" , value = "用户实体user" , required = true , dataType = "User" )
  120. })
  121. @RequestMapping (value = "user/{id}" , method = RequestMethod.PUT)
  122. public ResponseEntity<JsonResult> update ( @PathVariable ( "id" ) Integer id, @RequestBody User user){
  123. JsonResult r = new JsonResult();
  124. try {
  125. User u = users. get(id);
  126. u.setUsername(user.getUsername());
  127. u.setAge(user.getAge());
  128. users.put(id, u);
  129. r.setResult(u);
  130. r.setStatus( "ok");
  131. } catch (Exception e) {
  132. r.setResult(e.getClass().getName() + ":" + e.getMessage());
  133. r.setStatus( "error");
  134. e.printStackTrace();
  135. }
  136. return ResponseEntity.ok(r);
  137. }
  138. @ApiIgnore //使用该注解忽略这个API
  139. @RequestMapping (value = "/hi" , method = RequestMethod.GET)
  140. public String jsonTest() {
  141. return " hi you!";
  142. }
  143. }

Json格式输出类 JsonResult.class


  
  
  1. package cn.saytime.bean;
  2. public class JsonResult {
  3. private String status = null;
  4. private Object result = null;
  5. // Getter Setter
  6. }

实体User.class


  
  
  1. package cn.saytime.bean;
  2. import java.util.Date;
  3. /**
  4. * @author zh
  5. * @ClassName cn.saytime.bean.User
  6. * @Description
  7. */
  8. public class User {
  9. private int id;
  10. private String username;
  11. private int age;
  12. private Date ctm;
  13. // Getter Setter
  14. }

项目结构:

这里写图片描述

四、Swagger2文档

启动SpringBoot项目,访问 http://localhost:8080/swagger-ui.html

这里写图片描述

具体里面的内容以及接口测试,应该一看就懂了。这里就不一一截图了。

五、Swagger注解

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

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



            </div>

猜你喜欢

转载自blog.csdn.net/qq_31424825/article/details/80909698