转自https://blog.csdn.net/sanyaoxu_2/article/details/80555328

1:认识Swagger

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。

作用:

    1. 接口的文档在线自动生成。

    2. 功能测试。

 Swagger是一组开源项目,其中主要要项目如下:

1.   Swagger-tools:提供各种与Swagger进行集成和交互的工具。例如模式检验、Swagger 1.2文档转换成Swagger 2.0文档等功能。

2.   Swagger-core: 用于Java/Scala的的Swagger实现。与JAX-RS(Jersey、Resteasy、CXF...)、Servlets和Play框架进行集成。

3.   Swagger-js: 用于JavaScript的Swagger实现。

4.   Swagger-node-express: Swagger模块,用于node.js的Express web应用框架。

5.   Swagger-ui:一个无依赖的HTML、JS和CSS集合,可以为Swagger兼容API动态生成优雅文档。

6.   Swagger-codegen:一个模板驱动引擎,通过分析用户Swagger资源声明以各种语言生成客户端代码。

2:Maven

版本号请根据实际情况自行更改。

<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>

3:创建Swagger2配置类

在Application.java同级创建Swagger2的配置类Swagger2

  1.  
    package com.swaggerTest;
  2.  
     
  3.  
    import org.springframework.context.annotation.Bean;
  4.  
    import org.springframework.context.annotation.Configuration;
  5.  
     
  6.  
    import springfox.documentation.builders.ApiInfoBuilder;
  7.  
    import springfox.documentation.builders.PathSelectors;
  8.  
    import springfox.documentation.builders.RequestHandlerSelectors;
  9.  
    import springfox.documentation.service.ApiInfo;
  10.  
    import springfox.documentation.spi.DocumentationType;
  11.  
    import springfox.documentation.spring.web.plugins.Docket;
  12.  
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
  13.  
     
  14.  
    /**
  15.  
    * Swagger2配置类
  16.  
    * 在与spring boot集成时,放在与Application.java同级的目录下。
  17.  
    * 通过@Configuration注解,让Spring来加载该类配置。
  18.  
    * 再通过@EnableSwagger2注解来启用Swagger2。
  19.  
    */
  20.  
    @Configuration
  21.  
    @EnableSwagger2
  22.  
    public class Swagger2 {
  23.  
     
  24.  
    /**
  25.  
    * 创建API应用
  26.  
    * apiInfo() 增加API相关信息
  27.  
    * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现,
  28.  
    * 本例采用指定扫描的包路径来定义指定要建立API的目录。
  29.  
    *
  30.  
    * @return
  31.  
    */
  32.  
    @Bean
  33.  
    public Docket createRestApi() {
  34.  
    return new Docket(DocumentationType.SWAGGER_2)
  35.  
    .apiInfo(apiInfo())
  36.  
    .select()
  37.  
    .apis(RequestHandlerSelectors.basePackage("com.swaggerTest.controller"))
  38.  
    .paths(PathSelectors.any())
  39.  
    .build();
  40.  
    }
  41.  
     
  42.  
    /**
  43.  
    * 创建该API的基本信息(这些基本信息会展现在文档页面中)
  44.  
    * 访问地址:http://项目实际地址/swagger-ui.html
  45.  
    * @return
  46.  
    */
  47.  
    private ApiInfo apiInfo() {
  48.  
    return new ApiInfoBuilder()
  49.  
    .title("Spring Boot中使用Swagger2构建RESTful APIs")
  50.  
    .description("更多请关注http://www.baidu.com")
  51.  
    .termsOfServiceUrl("http://www.baidu.com")
  52.  
    .contact("sunf")
  53.  
    .version("1.0")
  54.  
    .build();
  55.  
    }
  56.  
    }

如上代码所示,通过createRestApi函数创建Docket的Bean之后,apiInfo()用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。

4:添加文档内容

在完成了上述配置后,其实已经可以生产文档内容,但是这样的文档主要针对请求本身,描述的主要来源是函数的命名,对用户并不友好,我们通常需要自己增加一些说明来丰富文档内容。

Swagger使用的注解及其说明:

@Api:用在类上,说明该类的作用。

@ApiOperation:注解来给API增加方法说明。

@ApiImplicitParams : 用在方法上包含一组参数说明。

@ApiImplicitParam:用来注解来给方法入参增加说明。

@ApiResponses:用于表示一组响应

@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息

l   code:数字,例如400

l   message:信息,例如"请求参数没填好"

l   response:抛出异常的类

@ApiModel:描述一个Model的信息(一般用在请求参数无法使用@ApiImplicitParam注解进行描述的时候)

l   @ApiModelProperty:描述一个model的属性

注意:@ApiImplicitParam的参数说明:

paramType:指定参数放在哪个地方

header:请求参数放置于Request Header,使用@RequestHeader获取

query:请求参数放置于请求地址,使用@RequestParam获取

path:(用于restful接口)-->请求参数的获取:@PathVariable

body:(不常用)

form(不常用)

name:参数名

dataType:参数类型

required:参数是否必须传

true | false

value:说明参数的意思

defaultValue:参数的默认值

例子:

  1.  
    package com.swaggerTest.controller;
  2.  
     
  3.  
    import org.springframework.stereotype.Controller;
  4.  
    import org.springframework.util.StringUtils;
  5.  
    import org.springframework.web.bind.annotation.RequestMapping;
  6.  
    import org.springframework.web.bind.annotation.RequestMethod;
  7.  
    import org.springframework.web.bind.annotation.RequestParam;
  8.  
    import org.springframework.web.bind.annotation.ResponseBody;
  9.  
     
  10.  
    import io.swagger.annotations.Api;
  11.  
    import io.swagger.annotations.ApiImplicitParam;
  12.  
    import io.swagger.annotations.ApiImplicitParams;
  13.  
    import io.swagger.annotations.ApiOperation;
  14.  
     
  15.  
    /**
  16.  
    * 一个用来测试swagger注解的控制器
  17.  
    * 注意@ApiImplicitParam的使用会影响程序运行,如果使用不当可能造成控制器收不到消息
  18.  
    *
  19.  
    * @author SUNF
  20.  
    */
  21.  
    @Controller
  22.  
    @RequestMapping("/say")
  23.  
    @Api(value = "SayController|一个用来测试swagger注解的控制器")
  24.  
    public class SayController {
  25.  
     
  26.  
    @ResponseBody
  27.  
    @RequestMapping(value ="/getUserName", method= RequestMethod.GET)
  28.  
    @ApiOperation(value="根据用户编号获取用户姓名", notes="test: 仅1和2有正确返回")
  29.  
    @ApiImplicitParam(paramType="query", name = "userNumber", value = "用户编号", required = true, dataType = "Integer")
  30.  
    public String getUserName(@RequestParam Integer userNumber){
  31.  
    if(userNumber == 1){
  32.  
    return "张三丰";
  33.  
    }
  34.  
    else if(userNumber == 2){
  35.  
    return "慕容复";
  36.  
    }
  37.  
    else{
  38.  
    return "未知";
  39.  
    }
  40.  
    }
  41.  
     
  42.  
    @ResponseBody
  43.  
    @RequestMapping("/updatePassword")
  44.  
    @ApiOperation(value="修改用户密码", notes="根据用户id修改密码")
  45.  
    @ApiImplicitParams({
  46.  
    @ApiImplicitParam(paramType="query", name = "userId", value = "用户ID", required = true, dataType = "Integer"),
  47.  
    @ApiImplicitParam(paramType="query", name = "password", value = "旧密码", required = true, dataType = "String"),
  48.  
    @ApiImplicitParam(paramType="query", name = "newPassword", value = "新密码", required = true, dataType = "String")
  49.  
    })
  50.  
    public String updatePassword(@RequestParam(value="userId") Integer userId, @RequestParam(value="password") String password,
  51.  
    @RequestParam(value="newPassword") String newPassword){
  52.  
    if(userId <= 0 || userId > 2){
  53.  
    return "未知的用户";
  54.  
    }
  55.  
    if(StringUtils.isEmpty(password) || StringUtils.isEmpty(newPassword)){
  56.  
    return "密码不能为空";
  57.  
    }
  58.  
    if(password.equals(newPassword)){
  59.  
    return "新旧密码不能相同";
  60.  
    }
  61.  
    return "密码修改成功!";
  62.  
    }
  63.  
    }

完成上述代码添加上,启动Spring Boot程序,访问:http://localhost:8080/swagger-ui.html

如上图,可以看到暴漏出来的控制器信息,点击进入可以看到详细信息。

两个注意点:

1.  paramType会直接影响程序的运行期,如果paramType与方法参数获取使用的注解不一致,会直接影响到参数的接收。

例如:

使用Sawgger UI进行测试,接收不到!

2.  还有一个需要注意的地方:

Conntroller中定义的方法必须在@RequestMapper中显示的指定RequestMethod类型,否则SawggerUi会默认为全类型皆可访问, API列表中会生成多条项目。

如上图:updatePassword()未指定requestMethod,结果生成了7条API信息。所以如果没有特殊需求,建议根据实际情况加上requestMethod。

5:Swagger UI面板说明

6:参考

http://blog.didispace.com/springbootswagger2/

http://blog.csdn.net/jia20003/article/details/50700736

Swagger官网 :http://swagger.io/

Spring Boot & Swagger UI : http://fruzenshtein.com/spring-boot-swagger-ui/

Github:https://github.com/swagger-api/swagger-core/wiki/Annotations

---------------------------------------------------------------------------------------

7:接收对象传参的例子

在POJO上增加

  1.  
    package com.zhongying.api.model.base;
  2.  
     
  3.  
    import io.swagger.annotations.ApiModel;
  4.  
    import io.swagger.annotations.ApiModelProperty;
  5.  
     
  6.  
    /**
  7.  
    * 医生对象模型,不要使用该类
  8.  
    * @author SUNF
  9.  
    *
  10.  
    */
  11.  
    @ApiModel(value="医生对象模型")
  12.  
    public class DemoDoctor{
  13.  
    @ApiModelProperty(value="id" ,required=true)
  14.  
    private Integer id;
  15.  
    @ApiModelProperty(value="医生姓名" ,required=true)
  16.  
    private String name;
  17.  
     
  18.  
     
  19.  
    public Integer getId() {
  20.  
    return id;
  21.  
    }
  22.  
     
  23.  
    public void setId(Integer id) {
  24.  
    this.id = id;
  25.  
    }
  26.  
     
  27.  
    public String getName() {
  28.  
    return name;
  29.  
    }
  30.  
     
  31.  
    public void setName(String name) {
  32.  
    this.name = name;
  33.  
    }
  34.  
     
  35.  
    @Override
  36.  
    public String toString() {
  37.  
    return "DemoDoctor [id=" + id + ", name=" + name + "]";
  38.  
    }
  39.  
     
  40.  
    }
  41.  
     

注意: 在后台采用对象接收参数时,Swagger自带的工具采用的是JSON传参,    测试时需要在参数上加入@RequestBody,正常运行采用form或URL提交时候请删除。

  1.  
    package com.zhongying.api.controller.app;
  2.  
     
  3.  
    import java.util.ArrayList;
  4.  
    import java.util.List;
  5.  
     
  6.  
    import javax.servlet.http.HttpServletRequest;
  7.  
     
  8.  
    import org.springframework.stereotype.Controller;
  9.  
    import org.springframework.web.bind.annotation.RequestBody;
  10.  
    import org.springframework.web.bind.annotation.RequestMapping;
  11.  
    import org.springframework.web.bind.annotation.RequestMethod;
  12.  
    import org.springframework.web.bind.annotation.RequestParam;
  13.  
    import org.springframework.web.bind.annotation.ResponseBody;
  14.  
     
  15.  
    import com.github.pagehelper.PageInfo;
  16.  
    import com.zhongying.api.exception.HttpStatus401Exception;
  17.  
    import com.zhongying.api.model.base.DemoDoctor;
  18.  
     
  19.  
    import io.swagger.annotations.Api;
  20.  
    import io.swagger.annotations.ApiImplicitParam;
  21.  
    import io.swagger.annotations.ApiImplicitParams;
  22.  
    import io.swagger.annotations.ApiOperation;
  23.  
     
  24.  
    /**
  25.  
    * 医生类(模拟)
  26.  
    * @author SUNF
  27.  
    */
  28.  
    @RequestMapping("/api/v1")
  29.  
    @Controller
  30.  
    @Api(value = "DoctorTestController-医生信息接口模拟")
  31.  
    public class DoctorTestController {
  32.  
     
  33.  
    /**
  34.  
    * 添加医生
  35.  
    *
  36.  
    * 在使用对象封装参数进行传参时,需要在该对象添加注解,将其注册到swagger中
  37.  
    * @link com.zhongying.api.model.base.DemoDoctor
  38.  
    *
  39.  
    * 注意: 在后台采用对象接收参数时,Swagger自带的工具采用的是JSON传参,
  40.  
    * 测试时需要在参数上加入@RequestBody,正常运行采用form或URL提交时候请删除。
  41.  
    *
  42.  
    * @param doctor 医生类对象
  43.  
    * @return
  44.  
    * @throws Exception
  45.  
    */
  46.  
    @ResponseBody
  47.  
    @RequestMapping(value="/doctor", method= RequestMethod.POST )
  48.  
    @ApiOperation(value="添加医生信息", notes="")
  49.  
    public String addDoctor(@RequestBody DemoDoctor doctor) throws Exception{
  50.  
    if(null == doctor || doctor.getId() == null){
  51.  
    throw new HttpStatus401Exception("添加医生失败","DT3388","未知原因","请联系管理员");
  52.  
    }
  53.  
    try {
  54.  
    System.out.println("成功----------->"+doctor.getName());
  55.  
    } catch (Exception e) {
  56.  
    throw new HttpStatus401Exception("添加医生失败","DT3388","未知原因","请联系管理员");
  57.  
    }
  58.  
     
  59.  
    return doctor.getId().toString();
  60.  
    }
  61.  
     
  62.  
    /**
  63.  
    * 删除医生
  64.  
    * @param doctorId 医生ID
  65.  
    * @return
  66.  
    */
  67.  
    @ResponseBody
  68.  
    @RequestMapping(value="/doctor/{doctorId}", method= RequestMethod.DELETE )
  69.  
    @ApiOperation(value="删除医生信息", notes="")
  70.  
    @ApiImplicitParam(paramType="query", name = "doctorId", value = "医生ID", required = true, dataType = "Integer")
  71.  
    public String deleteDoctor(@RequestParam Integer doctorId){
  72.  
    if(doctorId > 2){
  73.  
    return "删除失败";
  74.  
    }
  75.  
    return "删除成功";
  76.  
    }
  77.  
     
  78.  
    /**
  79.  
    * 修改医生信息
  80.  
    * @param doctorId 医生ID
  81.  
    * @param doctor 医生信息
  82.  
    * @return
  83.  
    * @throws HttpStatus401Exception
  84.  
    */
  85.  
    @ResponseBody
  86.  
    @RequestMapping(value="/doctor/{doctorId}", method= RequestMethod.POST )
  87.  
    @ApiOperation(value="修改医生信息", notes="")
  88.  
    @ApiImplicitParam(paramType="query", name = "doctorId", value = "医生ID", required = true, dataType = "Integer")
  89.  
    public String updateDoctor(@RequestParam Integer doctorId, @RequestBody DemoDoctor doctor) throws HttpStatus401Exception{
  90.  
    if(null == doctorId || null == doctor){
  91.  
    throw new HttpStatus401Exception("修改医生信息失败","DT3391","id不能为空","请修改");
  92.  
    }
  93.  
    if(doctorId > 5 ){
  94.  
    throw new HttpStatus401Exception("医生不存在","DT3392","错误的ID","请更换ID");
  95.  
    }
  96.  
    System.out.println(doctorId);
  97.  
    System.out.println(doctor);
  98.  
    return "修改成功";
  99.  
    }
  100.  
     
  101.  
    /**
  102.  
    * 获取医生详细信息
  103.  
    * @param doctorId 医生ID
  104.  
    * @return
  105.  
    * @throws HttpStatus401Exception
  106.  
    */
  107.  
    @ResponseBody
  108.  
    @RequestMapping(value="/doctor/{doctorId}", method= RequestMethod.GET )
  109.  
    @ApiOperation(value="获取医生详细信息", notes="仅返回姓名..")
  110.  
    @ApiImplicitParam(paramType="query", name = "doctorId", value = "医生ID", required = true, dataType = "Integer")
  111.  
    public DemoDoctor getDoctorDetail(@RequestParam Integer doctorId) throws HttpStatus401Exception{
  112.  
    System.out.println(doctorId);
  113.  
    if(null == doctorId){
  114.  
    throw new HttpStatus401Exception("查看医生信息失败","DT3390","未知原因","请联系管理员");
  115.  
    }
  116.  
    if(doctorId > 3){
  117.  
    throw new HttpStatus401Exception("医生不存在","DT3392","错误的ID","请更换ID");
  118.  
    }
  119.  
    DemoDoctor doctor = new DemoDoctor();
  120.  
    doctor.setId(1);
  121.  
    doctor.setName("测试员");
  122.  
    return doctor;
  123.  
    }
  124.  
     
  125.  
    /**
  126.  
    * 获取医生列表
  127.  
    * @param pageIndex 当前页数
  128.  
    * @param pageSize 每页记录数
  129.  
    * @param request
  130.  
    * @return
  131.  
    * @throws HttpStatus401Exception
  132.  
    */
  133.  
    @ResponseBody
  134.  
    @RequestMapping(value="/doctor", method= RequestMethod.GET )
  135.  
    @ApiOperation(value="获取医生列表", notes="目前一次全部取,不分页")
  136.  
    @ApiImplicitParams({
  137.  
    @ApiImplicitParam(paramType="header", name = "token", value = "token", required = true, dataType = "String"),
  138.  
    @ApiImplicitParam(paramType="query", name = "pageIndex", value = "当前页数", required = false, dataType = "String"),
  139.  
    @ApiImplicitParam(paramType="query", name = "pageSize", value = "每页记录数", required = true, dataType = "String"),
  140.  
    })
  141.  
    public PageInfo<DemoDoctor> getDoctorList(@RequestParam(value = "pageIndex", required = false, defaultValue = "1") Integer pageIndex,
  142.  
    @RequestParam(value = "pageSize", required = false) Integer pageSize,
  143.  
    HttpServletRequest request) throws HttpStatus401Exception{
  144.  
     
  145.  
    String token = request.getHeader("token");
  146.  
    if(null == token){
  147.  
    throw new HttpStatus401Exception("没有权限","SS8888","没有权限","请查看操作文档");
  148.  
    }
  149.  
    if(null == pageSize){
  150.  
    throw new HttpStatus401Exception("每页记录数不粗安在","DT3399","不存在pageSize","请查看操作文档");
  151.  
    }
  152.  
     
  153.  
    DemoDoctor doctor1 = new DemoDoctor();
  154.  
    doctor1.setId(1);
  155.  
    doctor1.setName("测试员1");
  156.  
    DemoDoctor doctor2 = new DemoDoctor();
  157.  
    doctor2.setId(2);
  158.  
    doctor2.setName("测试员2");
  159.  
     
  160.  
    List<DemoDoctor> doctorList = new ArrayList<DemoDoctor>();
  161.  
    doctorList.add(doctor1);
  162.  
    doctorList.add(doctor2);
  163.  
    return new PageInfo<DemoDoctor>(doctorList);
  164.  
    }
  165.  
     
  166.  
     
  167.  
    }

增加header:

现在很多请求需要在header增加额外参数,可以参考getDoctorList()的做法,使用request接收。

最新文章

  1. ******IT公司面试题汇总+优秀技术博客汇总
  2. Duilib源码分析(三)XML解析器—CMarkup
  3. Something about &quot;if&quot;
  4. HTML中的下拉列表 select
  5. JStorm第一个程序WordCount详解
  6. HDU 4718 The LCIS on the Tree(树链剖分)
  7. MVC模型 简介
  8. 【Noip2012】解题报告【字符】【贪心】【高精度】【倍增】【set】
  9. leetcode 24
  10. CentOS 普通用户设置sudo权限
  11. C# 读XML文件
  12. OpenJudge/Poj 1664 放苹果
  13. 本博客css style
  14. nginx配置文件中的location详解
  15. ASP.NET所谓前台调用后台、后台调用前台想到HTTP——实践篇
  16. Struts2 属性驱动、模型驱动、异常机制
  17. Animate自定义动画
  18. log.go 源码阅读
  19. vue实现数据双向绑定的原理
  20. 目标指定法——S.M.A.R.T.

热门文章

  1. SpringSecurity权限管理系统实战—四、整合SpringSecurity(上)
  2. unity探索者之微信支付,非第三方插件
  3. eclipse git提交项目以及down项目大致步骤
  4. CSS动画实例:小圆球的海洋
  5. Logistic回归分析之二元Logistic回归
  6. Hive SQL 优化面试题整理
  7. oracle练习前期准备
  8. CF1270B Interesting Subarray 题解
  9. 百度支持链接的nofollow属性吗
  10. soso官方:网页分类技术介绍