• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

swagger使用指南

技术杂谈 勤劳的小蚂蚁 2个月前 (02-06) 76次浏览 已收录 0个评论 扫描二维码

前言:作为一个以前后端分离为模式开发小组,我们每隔一段时间都进行这样一个场景:前端人员和后端开发在一起热烈的讨论”哎,你这参数又变了啊”,”接口怎么又请求不通了啊”,”你再试试,我打个断点调试一下..”。可以看到在前后端沟通中出现了不少问题。
对于这样的问题,之前一直没有很好的解决方案,直到它的出现,没错…这就是我们今天要讨论的神器:swagger,一款致力于解决接口规范化、标准化、文档化的开源库,一款真正的开发神器。

目录

  • swagger是什么?
  • 为什么要使用swaager?
  • 如何搭一个swagger?
  • 如何在项目中集成swagger
  • 使用swagger需要注意的问题
  • 总结

一:swagger是什么?

Swagger是一款RESTFUL接口的文档在线自动生成+功能测试功能软件。Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的Web服务。目标是使客户端和文件系统作为服务器以同样的速度来更新文件的方法,参数和模型紧密集成到服务器。
这个解释简单点来讲就是说,swagger是一款可以根据resutful风格生成的生成的接口开发文档,并且支持做测试的一款中间软件。

二:为什么要使用swaager?

2.1:对于后端开发人员来说

  • 不用再手写WiKi接口拼大量的参数,避免手写错误
  • 对代码侵入性低,采用全注解的方式,开发简单
  • 方法参数名修改、增加、减少参数都可以直接生效,不用手动维护
  • 缺点:增加了开发成本,写接口还得再写一套参数配置

2.2:对于前端开发来说

  • 后端只需要定义好接口,会自动生成文档,接口功能、参数一目了然
  • 联调方便,如果出问题,直接测试接口,实时检查参数和返回值,就可以快速定位是前端还是后端的问题

2.3:对于测试

  • 对于某些没有前端界面UI的功能,可以用它来测试接口
  • 操作简单,不用了解具体代码就可以操作
  • 操作简单,不用了解具体代码就可以操作

三:如何搭一个swagger

3.1:引入swagger的依赖

目前推荐使用2.7.0版本,因为2.6.0版本有bug,而其他版本又没有经过验证
  1. <!--引入swagger-->
  2. <dependency>
  3.    <groupId>io.springfox</groupId>
  4.    <artifactId>springfox-swagger2</artifactId>
  5.    <version>2.7.0</version>
  6. </dependency>
  7. <dependency>
  8.    <groupId>io.springfox</groupId>
  9.    <artifactId>springfox-swagger-ui</artifactId>
  10.    <version>2.7.0</version>
  11. </dependency>

3.2:springBoot整合swagger

  1. @Configuration
  2. @EnableSwagger2
  3. publicclassSwaggerConfig{
  4.    @Bean
  5.    publicDocket productApi(){
  6.        returnnewDocket(DocumentationType.SWAGGER_2)
  7.                .apiInfo(apiInfo())
  8.                .select()
  9.                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))  //添加ApiOperiation注解的被扫描
  10.                .paths(PathSelectors.any())
  11.                .build();

  12.    }

  13.    privateApiInfo apiInfo(){
  14.        returnnewApiInfoBuilder().title(”swaggerspringBoot整合“).description(”swaggerAPI文档")
  15.                .version("1.0").build();
  16.    }

  17. }

3.3:swagger的注解

swagger的核心在于注解,接下来就着重讲一下swagger的注解:

四:在项目中集成swagger

4.1:在controller中使用注解

  1. package com.youjia.swagger.controller;

  2. import com.youjia.swagger.constants.CommonConstants;
  3. import com.youjia.swagger.model.Film;
  4. import com.youjia.swagger.model.ResultModel;
  5. import com.youjia.swagger.service.FilmService;
  6. import io.swagger.annotations.Api;
  7. import io.swagger.annotations.ApiImplicitParam;
  8. import io.swagger.annotations.ApiImplicitParams;
  9. import io.swagger.annotations.ApiOperation;
  10. import io.swagger.annotations.ApiParam;
  11. import io.swagger.annotations.ApiResponse;
  12. import io.swagger.annotations.ApiResponses;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.util.CollectionUtils;
  15. import org.springframework.util.StringUtils;
  16. import org.springframework.web.bind.annotation.GetMapping;
  17. import org.springframework.web.bind.annotation.PathVariable;
  18. import org.springframework.web.bind.annotation.PostMapping;
  19. import org.springframework.web.bind.annotation.RequestBody;
  20. import org.springframework.web.bind.annotation.RequestMapping;
  21. import org.springframework.web.bind.annotation.RequestParam;
  22. import org.springframework.web.bind.annotation.RestController;

  23. import javax.servlet.http.HttpServletRequest;
  24. import java.text.DateFormat;
  25. import java.text.SimpleDateFormat;
  26. import java.util.Date;
  27. import java.util.List;
  28. import java.util.Objects;

  29. /**
  30. * @Auther: wyq
  31. * @Date: 2018/12/29 14:50
  32. */
  33. @RestController
  34. @Api(value ="电影Controller", tags ={"电影访问接口"})
  35. @RequestMapping("/film")
  36. publicclassFilmController{

  37.    @Autowired
  38.    privateFilmService filmService;

  39.    /**
  40.     * 添加一个电影数据
  41.     *
  42.     * @param
  43.     * @return
  44.     */
  45.    @ApiOperation(value ="添加一部电影")
  46.    @PostMapping("/addFilm")
  47.    @ApiResponses(value ={@ApiResponse(code =1000, message ="成功"),@ApiResponse(code =1001, message ="失败"),
  48.            @ApiResponse(code =1002, response =Film.class,message ="缺少参数")})
  49.    publicResultModel addFilm(@ApiParam("电影名称")@RequestParam("filmName")String filmName,
  50.                               @ApiParam(value ="分数", allowEmptyValue =true)@RequestParam("score")Short score,
  51.                               @ApiParam("发布时间")@RequestParam(value ="publishTime",required =false)String publishTime,
  52.                               @ApiParam("创建者id")@RequestParam("creatorId")Long creatorId){

  53.        if(Objects.isNull(filmName)||Objects.isNull(score)||Objects.isNull(publishTime)||StringUtils
  54.                .isEmpty(creatorId)){
  55.            returnnewResultModel(ResultModel.failed,"参数错误");
  56.        }
  57.        Film filmPOM =newFilm();
  58.        filmPOM.setFilmName(filmName);
  59.        filmPOM.setScore(score);
  60.        DateFormat simpleDateFormat =newSimpleDateFormat("yyyy-MM-dd");
  61.        Date publishTimeDate =null;
  62.        try{
  63.            publishTimeDate = simpleDateFormat.parse(publishTime);
  64.        }catch(Exception ex){
  65.            ex.printStackTrace();
  66.        }
  67.        filmPOM.setPublishTime(publishTimeDate);
  68.        filmPOM.setCreatorId(creatorId);
  69.        Boolean result = filmService.addFilm(filmPOM);
  70.        if(result){
  71.            returnnewResultModel(CommonConstants.SUCCESSMSG);
  72.        }
  73.        returnnewResultModel(CommonConstants.FAILD_MSG);
  74.    }

  75.    /**
  76.     * 根据电影名字获取电影
  77.     *
  78.     * @param fileName
  79.     * @return
  80.     */
  81.    @GetMapping("/getFilms")
  82.    @ApiOperation(value ="根据名字获取电影")
  83.    @ApiResponses(value ={@ApiResponse(code =1000, message ="成功"),@ApiResponse(code =1001, message ="失败"),
  84.            @ApiResponse(code =1002, message ="缺少参数")})
  85.    publicResultModel getFilmsByName(@ApiParam("电影名称")@RequestParam("fileName")String fileName){
  86.        if(StringUtils.isEmpty(fileName)){
  87.            returnCommonConstants.getErrorResultModel();
  88.        }

  89.        List<Film> films = filmService.getFilmByName(fileName);
  90.        if(!CollectionUtils.isEmpty(films)){
  91.            returnnewResultModel(films);
  92.        }
  93.        returnCommonConstants.getErrorResultModel();

  94.    }

  95.    /**
  96.     * 根据电影名更新
  97.     *
  98.     * @return
  99.     */
  100.    @PostMapping("/updateScore")
  101.    @ApiOperation(value ="根据电影名修改分数")
  102.    @ApiResponses(value ={@ApiResponse(code =1000, message ="成功"),@ApiResponse(code =1001, message ="失败"),
  103.            @ApiResponse(code =1002, message ="缺少参数")})
  104.    publicResultModel updateFilmScore(@ApiParam("电影名称")@RequestParam("fileName")String fileName,
  105.                                       @ApiParam("分数")@RequestParam("score")Short score){
  106.        if(StringUtils.isEmpty(fileName)||Objects.isNull(score)){
  107.            returnCommonConstants.getErrorResultModel();
  108.        }

  109.        filmService.updateScoreByName(fileName, score);
  110.        returnCommonConstants.getSuccessResultModel();
  111.    }

  112.    /**
  113.     * 根据电影名删除电影
  114.     *
  115.     * @param request
  116.     * @return
  117.     */
  118.    @PostMapping("/delFilm")
  119.    @ApiOperation(value ="根据电影名删除电影")
  120.    @ApiImplicitParams({@ApiImplicitParam(name ="filmName",
  121.            value ="电影名",
  122.            dataType ="String",
  123.            paramType ="query",
  124.            required =true),@ApiImplicitParam(name ="id", value ="电影id", dataType ="int", paramType ="query")})
  125.    publicResultModel deleteFilmByNameOrId(HttpServletRequest request){
  126.        //电影名
  127.        String filmName = request.getParameter("filmName");
  128.        //电影id
  129.        Long filmId =Long.parseLong(request.getParameter("id"));

  130.        filmService.deleteFilmOrId(filmName,filmId);


  131.        returnCommonConstants.getSuccessResultModel();
  132.    }

  133.    /**
  134.     * 根据id获取电影
  135.     *
  136.     * @param id
  137.     * @return
  138.     */
  139.    @PostMapping("/{id}")
  140.    @ApiOperation("根据id获取电影")
  141.    @ApiImplicitParam(name ="id", value ="电影id", dataType ="long", paramType ="path", required =true)
  142.    publicResultModel getFilmById(@PathVariableLong id){

  143.        if(Objects.isNull(id)){
  144.            returnCommonConstants.getLessParamResultModel();
  145.        }
  146.        Film film = filmService.getFilmById(id);
  147.        if(Objects.nonNull(film)){
  148.            returnnewResultModel(film);
  149.        }
  150.        returnCommonConstants.getErrorResultModel();
  151.    }

  152.    /**
  153.     * 修改整个电影
  154.     *
  155.     * @param film
  156.     * @return
  157.     */
  158.    @PostMapping("/insertFilm")
  159.    @ApiOperation("插入一部电影")
  160.    publicResultModel insertFilm(@ApiParam("电影实体对象")@RequestBodyFilm film){
  161.        if(Objects.isNull(film)){
  162.            returnCommonConstants.getLessParamResultModel();
  163.        }
  164.        Boolean isSuccess = filmService.insertFilm(film);
  165.        if(isSuccess){
  166.            returnCommonConstants.getSuccessResultModel();
  167.        }
  168.        returnCommonConstants.getErrorResultModel();
  169.    }
  170. }

4.2:访问本地链接

可以看出访问的url都很清晰的展示在它最终的页面上,我们打开一个方法:可以看出方法的请求参数清晰的的罗列出来,包括方法的返回值。并且有一个很重要的功能,只需要点下方的try it out就可以进行接口测试,

五:使用swagger需要注意的问题

  • 对于只有一个HttpServletRequest参数的方法,如果参数小于5个,推荐使用 @ApiImplicitParams的方式单独封装每一个参数;如果参数大于5个,采用定义一个对象去封装所有参数的属性,然后使用@APiParam的方式
  • 默认的访问地址:ip:port/swagger-ui.html#/,但是在shiro中,会拦截所有的请求,必须加上默认访问路径(比如项目中,就是ip:port/context/swagger-ui.html#/),然后登陆后才可以看到
  • 在GET请求中,参数在Body体里面,不能使用@RequestBody。在POST请求,可以使用@RequestBody和@RequestParam,如果使用@RequestBody,对于参数转化的配置必须统一
  • controller必须指定请求类型,否则swagger会把所有的类型(6种)都生成出来
  • swagger在生产环境不能对外暴露,可以使用@Profile({“dev”, “prod”,“pre”})指定可以使用的环境

六:总结

swagger作为一款辅助性的工具,能大大提升我们的和前端的沟通效率,接口是一个非常重要的传递数据的媒介,每个接口的签名、方法参数都非常重要。一个良好的文档非常重要,如果采用手写的方式非常容易拼写错误,而swagger可以自动化生成参数文档,这一切都加快了我们的沟通效率。并且可以替代postman的作用。实在是开发编程必备良品啊。

丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:swagger使用指南
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00