Spring MVC中使用Swagger生成API文档和完整项目示例Demo,swagger-server-api

    xiaoxiao2021-03-25  137

    Spring MVC中使用Swagger生成API文档和完整项目示例Demo,swagger-server-api

    标签: swaggerspring mvcAPI文档文档自动化生成swagger-server-api 16125人阅读 评论(14) 收藏 举报 本文章已收录于: 分类: 研发架构(44) 作者同类文章 X •互联网公司的技术体系 •提高生产力:小雷之问和京东之答 •悖论:早期互联网项目,是否需要技术含量? •互联网研发团队-岗位职责 更多 本文作者:小雷FansUnion-一个有创业和投资经验的资深程序员-全球最大中文IT社区知名博主-排名第119   实际项目中非常需要写文档,提高Java服务端和Web前端以及移动端的对接效率。   听说Swagger这个工具,还不错,就网上找了些资料,自己实践了下。

    一:Swagger介绍

    Swagger是当前最好用的Restful API文档生成的开源项目,通过swagger-spring项目

    实现了与SpingMVC框架的无缝集成功能,方便生成spring restful风格的接口文档,

    同时swagger-ui还可以测试spring restful风格的接口功能。

    官方网站为:http://swagger.io/

    中文网站:http://www.sosoapi.com 二:Swagger与Spring MVC集成步骤 1.Maven关键配置          [html] view plain copy print ? <dependency>              <groupId>com.mangofactory</groupId>              <artifactId>swagger-springmvc</artifactId>              <version>1.0.2</version>          </dependency>     <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-webmvc</artifactId>          <version>4.1.6.RELEASE</version>        </dependency>   <dependency> <groupId>com.mangofactory</groupId> <artifactId>swagger-springmvc</artifactId> <version>1.0.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.1.6.RELEASE</version> </dependency> 2. 插件配置    CustomJavaPluginConfig 3.复制swagger的相关js等静态资源到webapp目录。    swagger-ui.js之类的。    我copy过一次,但是有问题,最后从网上下载了一个项目,可以直接用的那种。    然后自己再逐步改造。 4.启动项目    http://localhost:8080/ 三、常见swagger注解一览与使用 最常用的5个注解

    @Api:修饰整个类,描述Controller的作用

    @ApiOperation:描述一个类的一个方法,或者说一个接口

    @ApiParam:单个参数描述

    @ApiModel:用对象来接收参数

    @ApiProperty:用对象接收参数时,描述对象的一个字段

    其它若干

    @ApiResponse:HTTP响应其中1个描述

    @ApiResponses:HTTP响应整体描述

    @ApiClass

    @ApiError

    @ApiErrors

    @ApiParamImplicit

    @ApiParamsImplicit

    四、关键代码和实际例子     例子1:     [java] view plain copy print ? @ApiOperation(value = "获得用户列表", notes = "列表信息", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)      @ResponseBody      @RequestMapping(value = "list", method = RequestMethod.POST)      public Result<User> list(              @ApiParam(value = "分类ID", required = true@RequestParam Long categoryId,              @ApiParam(value = "token", required = true@RequestParam String token) {          Result<User> result = new Result<User>();          User user = new User();          result.setData(user);          return result;      }   @ApiOperation(value = "获得用户列表", notes = "列表信息", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody @RequestMapping(value = "list", method = RequestMethod.POST) public Result<User> list( @ApiParam(value = "分类ID", required = true) @RequestParam Long categoryId, @ApiParam(value = "token", required = true) @RequestParam String token) { Result<User> result = new Result<User>(); User user = new User(); result.setData(user); return result; }    @ApiParam(value = "token", required = true) @RequestParam String token Web前端/移动端HTTP请求方式:直接把参数附带到URL后面,或者用AJAX方法,表单提交。   例子2: [java] view plain copy print ? @ApiOperation(value = "update用户", notes = ")", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)    @ResponseBody    @RequestMapping(value = "update", method = RequestMethod.GET/*,produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE*/)    public Result<String> update(User user) {        String u = findUser(user);        System.out.println(u);        return null;    }   @ApiOperation(value = "update用户", notes = ")", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody @RequestMapping(value = "update", method = RequestMethod.GET/*,produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE*/) public Result<String> update(User user) { String u = findUser(user); System.out.println(u); return null; }  当参数太多的时候,需要定义太多的参数,排版看起来很不舒服。 这个时候,可以使用对象来接收。 @ApiModel(value = "用户对象",description="user2")  public class User extends CommonParam{ } Web前端/移动端HTTP请求方式:直接把参数附带到URL后面,或者用AJAX方法,表单提交。 这里面存在一个小问题,当后端用对象User来接收参数的时候,Swagger自带的工具是这样的:   这种形式,并不是表单提交,或者把参数附加到URL的后面。 我们只能手动构造URL,附带参数去提交。 如果需要测试的话! 例子3: [java] view plain copy print ? public Result<String> add(@RequestBody User user) {      String u = findUser(user);      System.out.println(u);      return null;  }   public Result<String> add(@RequestBody User user) { String u = findUser(user); System.out.println(u); return null; } Web前端/移动端HTTP请求方式:必须把参数,放到request请求的body中去。 后端不能直接用request.getParam("token")这种。 获得request body中的数据,手动转换成目标数据。     String charReader(HttpServletRequest request) throws IOException {         BufferedReader br = request.getReader();         String str, wholeStr = "";         while ((str = br.readLine()) != null) {             wholeStr += str;         }         return wholeStr;     } 个人推荐 1.参数不多的时候,用例子1,用@ApiParam注解生成文档。   swagger可视化界面,可以直接设置参数,发送请求来测试 2.参数比较多的时候,用例子2,用对象来接收参数,在对象里针对每个字段,@ApiModelProperty注解生成文档。    swagger可视化界面,可以直接设置参数,但是无法接收到。   因此,推荐使用其它HTTP请求或POST模拟工具,发送请求,模拟测试。 不推荐例子3,不通用,局限性比较大。 五、若干截图   六、源代码 [java] view plain copy print ? package cn.fansunion.swagger.serverapi.controller;    import org.springframework.http.MediaType;  import org.springframework.stereotype.Controller;  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.RequestParam;  import org.springframework.web.bind.annotation.ResponseBody;    import com.wordnik.swagger.annotations.Api;  import com.wordnik.swagger.annotations.ApiOperation;  import com.wordnik.swagger.annotations.ApiParam;    /**  * 小雷FansUnion-一个有创业和投资经验的资深程序员-全球最大中文IT社区知名博主-排名第119  * 博客:http://blog.csdn.net/fansunion  *  */  @Api(value = "user", description = "用户管理", produces = MediaType.APPLICATION_JSON_VALUE)  @Controller  @RequestMapping("user")  public class UserController {        // 列出某个类目的所有规格      @ApiOperation(value = "获得用户列表", notes = "列表信息", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)      @ResponseBody      @RequestMapping(value = "list", method = RequestMethod.POST)      public Result<User> list(              @ApiParam(value = "分类ID", required = true@RequestParam Long categoryId,              @ApiParam(value = "分类ID", required = true@RequestParam Long categoryId2,              @ApiParam(value = "token", required = true@RequestParam String token) {          Result<User> result = new Result<User>();          User user = new User();          result.setData(user);          return result;      }        @ApiOperation(value = "添加用户", notes = "获取商品信息(用于数据同步)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)      @ResponseBody      @RequestMapping(value = "add", method = RequestMethod.POST)      // @RequestBody只能有1个      // 使用了@RequestBody,不能在拦截器中,获得流中的数据,再json转换,拦截器中,也不清楚数据的类型,无法转换成java对象      // 只能手动调用方法      public Result<String> add(@RequestBody User user) {          String u = findUser(user);          System.out.println(u);          return null;      }        @ApiOperation(value = "update用户", notes = "获取商品信息(用于数据同步)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)      @ResponseBody      @RequestMapping(value = "update", method = RequestMethod.GET)      public Result<String> update(User user) {          String u = findUser(user);          System.out.println(u);          return null;      }        private String findUser(User user) {          String token = user.getToken();          return token;      }  }   package cn.fansunion.swagger.serverapi.controller; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; 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.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.wordnik.swagger.annotations.Api; import com.wordnik.swagger.annotations.ApiOperation; import com.wordnik.swagger.annotations.ApiParam; /** * 小雷FansUnion-一个有创业和投资经验的资深程序员-全球最大中文IT社区知名博主-排名第119 * 博客:http://blog.csdn.net/fansunion * */ @Api(value = "user", description = "用户管理", produces = MediaType.APPLICATION_JSON_VALUE) @Controller @RequestMapping("user") public class UserController { // 列出某个类目的所有规格 @ApiOperation(value = "获得用户列表", notes = "列表信息", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody @RequestMapping(value = "list", method = RequestMethod.POST) public Result<User> list( @ApiParam(value = "分类ID", required = true) @RequestParam Long categoryId, @ApiParam(value = "分类ID", required = true) @RequestParam Long categoryId2, @ApiParam(value = "token", required = true) @RequestParam String token) { Result<User> result = new Result<User>(); User user = new User(); result.setData(user); return result; } @ApiOperation(value = "添加用户", notes = "获取商品信息(用于数据同步)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody @RequestMapping(value = "add", method = RequestMethod.POST) // @RequestBody只能有1个 // 使用了@RequestBody,不能在拦截器中,获得流中的数据,再json转换,拦截器中,也不清楚数据的类型,无法转换成java对象 // 只能手动调用方法 public Result<String> add(@RequestBody User user) { String u = findUser(user); System.out.println(u); return null; } @ApiOperation(value = "update用户", notes = "获取商品信息(用于数据同步)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody @RequestMapping(value = "update", method = RequestMethod.GET) public Result<String> update(User user) { String u = findUser(user); System.out.println(u); return null; } private String findUser(User user) { String token = user.getToken(); return token; } } [java] view plain copy print ? package cn.fansunion.swagger.serverapi.controller;    import com.wordnik.swagger.annotations.ApiModel;  import com.wordnik.swagger.annotations.ApiModelProperty;    /**  * 小雷FansUnion-一个有创业和投资经验的资深程序员-全球最大中文IT社区知名博主-排名第119  * 博客:http://blog.csdn.net/fansunion  *  */  @ApiModel(value = "用户对象", description = "user2")  public class User extends CommonParam {        @ApiModelProperty(value = "商品信息", required = true)      private String name;      @ApiModelProperty(value = "密码", required = true)      private String password;        @ApiModelProperty(value = "性别")      private Integer sex;      @ApiModelProperty(value = "密码", required = true)      private String token;        public String getToken() {          return token;      }        public void setToken(String token) {          this.token = token;      }        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }        public String getPassword() {          return password;      }        public void setPassword(String password) {          this.password = password;      }        public Integer getSex() {          return sex;      }        public void setSex(Integer sex) {          this.sex = sex;      }    }   package cn.fansunion.swagger.serverapi.controller; import com.wordnik.swagger.annotations.ApiModel; import com.wordnik.swagger.annotations.ApiModelProperty; /** * 小雷FansUnion-一个有创业和投资经验的资深程序员-全球最大中文IT社区知名博主-排名第119 * 博客:http://blog.csdn.net/fansunion * */ @ApiModel(value = "用户对象", description = "user2") public class User extends CommonParam { @ApiModelProperty(value = "商品信息", required = true) private String name; @ApiModelProperty(value = "密码", required = true) private String password; @ApiModelProperty(value = "性别") private Integer sex; @ApiModelProperty(value = "密码", required = true) private String token; public String getToken() { return token; } public void setToken(String token) { this.token = token; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getSex() { return sex; } public void setSex(Integer sex) { this.sex = sex; } } [java] view plain copy print ? package cn.fansunion.swagger.serverapi.swagger;    import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.context.annotation.Bean;  import org.springframework.context.annotation.Configuration;  import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;  import org.springframework.web.servlet.config.annotation.EnableWebMvc;  import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;    import com.mangofactory.swagger.configuration.SpringSwaggerConfig;  import com.mangofactory.swagger.models.dto.ApiInfo;  import com.mangofactory.swagger.paths.SwaggerPathProvider;  import com.mangofactory.swagger.plugin.EnableSwagger;  import com.mangofactory.swagger.plugin.SwaggerSpringMvcPlugin;    @Configuration  @EnableWebMvc  @EnableSwagger  public class CustomJavaPluginConfig extends WebMvcConfigurerAdapter {        private SpringSwaggerConfig springSwaggerConfig;        @Autowired      public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) {          this.springSwaggerConfig = springSwaggerConfig;      }        /**      * 链式编程 来定制API样式 后续会加上分组信息      *       * @return      */      @Bean      public SwaggerSpringMvcPlugin customImplementation() {          return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)                  .apiInfo(apiInfo()).includePatterns(".*")                  .useDefaultResponseMessages(false)              //  .pathProvider(new GtPaths())                  .apiVersion("0.1").swaggerGroup("user");        }        private ApiInfo apiInfo() {          ApiInfo apiInfo = new ApiInfo("小雷移动端API接口平台",                  "提供详细的后台所有Restful接口""http://blog.csdn.net/FansUnion",                  "FansUnion@qq.com""小雷博客""http://blog.csdn.net/FansUnion");          return apiInfo;      }        @Override      public void configureDefaultServletHandling(              DefaultServletHandlerConfigurer configurer) {          configurer.enable();      }        class GtPaths extends SwaggerPathProvider {            @Override          protected String applicationPath() {              return "/restapi";          }            @Override          protected String getDocumentationPath() {              return "/restapi";          }      }    }   package cn.fansunion.swagger.serverapi.swagger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import com.mangofactory.swagger.configuration.SpringSwaggerConfig; import com.mangofactory.swagger.models.dto.ApiInfo; import com.mangofactory.swagger.paths.SwaggerPathProvider; import com.mangofactory.swagger.plugin.EnableSwagger; import com.mangofactory.swagger.plugin.SwaggerSpringMvcPlugin; @Configuration @EnableWebMvc @EnableSwagger public class CustomJavaPluginConfig extends WebMvcConfigurerAdapter { private SpringSwaggerConfig springSwaggerConfig; @Autowired public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) { this.springSwaggerConfig = springSwaggerConfig; } /** * 链式编程 来定制API样式 后续会加上分组信息 * * @return */ @Bean public SwaggerSpringMvcPlugin customImplementation() { return new SwaggerSpringMvcPlugin(this.springSwaggerConfig) .apiInfo(apiInfo()).includePatterns(".*") .useDefaultResponseMessages(false) // .pathProvider(new GtPaths()) .apiVersion("0.1").swaggerGroup("user"); } private ApiInfo apiInfo() { ApiInfo apiInfo = new ApiInfo("小雷移动端API接口平台", "提供详细的后台所有Restful接口", "http://blog.csdn.net/FansUnion", "FansUnion@qq.com", "小雷博客", "http://blog.csdn.net/FansUnion"); return apiInfo; } @Override public void configureDefaultServletHandling( DefaultServletHandlerConfigurer configurer) { configurer.enable(); } class GtPaths extends SwaggerPathProvider { @Override protected String applicationPath() { return "/restapi"; } @Override protected String getDocumentationPath() { return "/restapi"; } } } 七、项目下载地址   http://git.oschina.net/fansunion/swagger-server-api/tree/master/ 八、参考资料 http://blog.csdn.net/jia20003/article/details/50700736 http://www.cnblogs.com/quanyongan/archive/2013/04/16/3024741.html http://www.cnblogs.com/h9527/p/5506956.html http://www.cnblogs.com/yuananyun/p/4993426.html 小雷FansUnion-一个有创业和投资经验的资深程序员-全球最大中文IT社区知名博主-排名第119 博客:http://blog.csdn.net/fansunion  2016年7月16日 湖北-武汉    顶 4 踩 1     上一篇隆中对,程序员修炼之道,技术学习前进之路 下一篇互联网研发团队-岗位职责

    我的同类文章

    研发架构(44) http://blog.csdn.net •互联网公司的技术体系2016-09-29阅读3122 •悖论:早期互联网项目,是否需要技术含量?2016-07-30阅读546 •一个互联网研发团队的标准配置2016-07-10阅读5334 •一个电商项目的功能模块梳理2016-07-07阅读2463 •Java代码规范和一些常见问题2016-04-19阅读4397 •提高生产力:小雷之问和京东之答2016-09-25阅读274 •互联网研发团队-岗位职责2016-07-17阅读2471 •一个电商项目的功能模块梳理22016-07-07阅读954 •优先使用单表查询,而非联合查询2016-07-04阅读1548 •某电商网站,研发升级和优化,一点建议2016-04-19阅读3223 更多文章
    转载请注明原文地址: https://ju.6miu.com/read-11797.html

    最新回复(0)