<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          后端 API 接口文檔 Swagger 使用指南

          共 9393字,需瀏覽 19分鐘

           ·

          2021-04-09 21:58


          來(lái)源:cnblogs.com/wyq178


          • 前言
          • 一:swagger是什么?
          • 二:為什么要使用swaager?
            • 2.1:對(duì)于后端開(kāi)發(fā)人員來(lái)說(shuō)
            • 2.2:對(duì)于前端開(kāi)發(fā)來(lái)說(shuō)
            • 2.3:對(duì)于測(cè)試
          • 三:如何搭一個(gè)swagger
            • 3.1:引入swagger的依賴
            • 3.2:springBoot整合swagger
            • 3.3:swagger的注解
          • 四:在項(xiàng)目中集成swagger
            • 4.1:在controller中使用注解
            • 4.2:訪問(wèn)本地鏈接
          • 五:使用swagger需要注意的問(wèn)題
          • 六:總結(jié)

          前言

          作為一個(gè)以前后端分離為模式開(kāi)發(fā)小組,我們每隔一段時(shí)間都進(jìn)行這樣一個(gè)場(chǎng)景:前端人員和后端開(kāi)發(fā)在一起熱烈的討論"哎,你這參數(shù)又變了啊","接口怎么又請(qǐng)求不通了啊","你再試試,我打個(gè)斷點(diǎn)調(diào)試一下.."??梢钥吹皆谇昂蠖藴贤ㄖ谐霈F(xiàn)了不少問(wèn)題。

          對(duì)于這樣的問(wèn)題,之前一直沒(méi)有很好的解決方案,直到它的出現(xiàn),沒(méi)錯(cuò)...這就是我們今天要討論的神器:swagger,一款致力于解決接口規(guī)范化、標(biāo)準(zhǔn)化、文檔化的開(kāi)源庫(kù),一款真正的開(kāi)發(fā)神器。

          一:swagger是什么?

          Swagger是一款RESTFUL接口的文檔在線自動(dòng)生成+功能測(cè)試功能軟件。Swagger是一個(gè)規(guī)范和完整的框架,用于生成、描述、調(diào)用和可視化RESTful風(fēng)格的Web服務(wù)。目標(biāo)是使客戶端和文件系統(tǒng)作為服務(wù)器以同樣的速度來(lái)更新文件的方法,參數(shù)和模型緊密集成到服務(wù)器。

          這個(gè)解釋簡(jiǎn)單點(diǎn)來(lái)講就是說(shuō),swagger是一款可以根據(jù)resutful風(fēng)格生成的生成的接口開(kāi)發(fā)文檔,并且支持做測(cè)試的一款中間軟件。

          二:為什么要使用swaager?

          2.1:對(duì)于后端開(kāi)發(fā)人員來(lái)說(shuō)

          • 不用再手寫WiKi接口拼大量的參數(shù),避免手寫錯(cuò)誤
          • 對(duì)代碼侵入性低,采用全注解的方式,開(kāi)發(fā)簡(jiǎn)單
          • 方法參數(shù)名修改、增加、減少參數(shù)都可以直接生效,不用手動(dòng)維護(hù)
          • 缺點(diǎn):增加了開(kāi)發(fā)成本,寫接口還得再寫一套參數(shù)配置

          2.2:對(duì)于前端開(kāi)發(fā)來(lái)說(shuō)

          • 后端只需要定義好接口,會(huì)自動(dòng)生成文檔,接口功能、參數(shù)一目了然
          • 聯(lián)調(diào)方便,如果出問(wèn)題,直接測(cè)試接口,實(shí)時(shí)檢查參數(shù)和返回值,就可以快速定位是前端還是后端的問(wèn)題

          2.3:對(duì)于測(cè)試

          • 對(duì)于某些沒(méi)有前端界面UI的功能,可以用它來(lái)測(cè)試接口
          • 操作簡(jiǎn)單,不用了解具體代碼就可以操作
          • 操作簡(jiǎn)單,不用了解具體代碼就可以操作

          三:如何搭一個(gè)swagger

          3.1:引入swagger的依賴

          目前推薦使用2.7.0版本,因?yàn)?.6.0版本有bug,而其他版本又沒(méi)有經(jīng)過(guò)驗(yàn)證

          一:引入Swagger依賴庫(kù)
          <!--引入swagger-->
          <dependency>
          <groupId>io.springfox</groupId>
          <artifactId>springfox-swagger2</artifactId>
          <version>2.7.0</version>
          </dependency>
          <dependency>
          <groupId>io.springfox</groupId>
          <artifactId>springfox-swagger-ui</artifactId>
          <version>2.7.0</version>
          </dependency>

          3.2:springBoot整合swagger

          @Configuration
          @EnableSwagger2
          public class SwaggerConfig {
          @Bean
          public Docket productApi() {
          return new Docket(DocumentationType.SWAGGER_2)
          .apiInfo(apiInfo())
          .select()
          .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) //添加ApiOperiation注解的被掃描
          .paths(PathSelectors.any())
          .build();

          }

          private ApiInfo apiInfo() {
          return new ApiInfoBuilder().title(”swagger和springBoot整合“).description(”swagger的API文檔")
          .version("
          1.0").build();
          }

          }

          3.3:swagger的注解

          swagger的核心在于注解,接下來(lái)就著重講一下swagger的注解:

          四:在項(xiàng)目中集成swagger

          4.1:在controller中使用注解

          package com.youjia.swagger.controller;

          import com.youjia.swagger.constants.CommonConstants;
          import com.youjia.swagger.model.Film;
          import com.youjia.swagger.model.ResultModel;
          import com.youjia.swagger.service.FilmService;
          import io.swagger.annotations.Api;
          import io.swagger.annotations.ApiImplicitParam;
          import io.swagger.annotations.ApiImplicitParams;
          import io.swagger.annotations.ApiOperation;
          import io.swagger.annotations.ApiParam;
          import io.swagger.annotations.ApiResponse;
          import io.swagger.annotations.ApiResponses;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.util.CollectionUtils;
          import org.springframework.util.StringUtils;
          import org.springframework.web.bind.annotation.GetMapping;
          import org.springframework.web.bind.annotation.PathVariable;
          import org.springframework.web.bind.annotation.PostMapping;
          import org.springframework.web.bind.annotation.RequestBody;
          import org.springframework.web.bind.annotation.RequestMapping;
          import org.springframework.web.bind.annotation.RequestParam;
          import org.springframework.web.bind.annotation.RestController;

          import javax.servlet.http.HttpServletRequest;
          import java.text.DateFormat;
          import java.text.SimpleDateFormat;
          import java.util.Date;
          import java.util.List;
          import java.util.Objects;

          /**
          * @Auther: wyq
          * @Date: 2018/12/29 14:50
          */

          @RestController
          @Api(value = "電影Controller", tags = { "電影訪問(wèn)接口" })
          @RequestMapping("/film")
          public class FilmController {

          @Autowired
          private FilmService filmService;

          /**
          * 添加一個(gè)電影數(shù)據(jù)
          *
          * @param
          * @return
          */

          @ApiOperation(value = "添加一部電影")
          @PostMapping("/addFilm")
          @ApiResponses(value = { @ApiResponse(code = 1000, message = "成功"), @ApiResponse(code = 1001, message = "失敗"),
          @ApiResponse(code = 1002, response = Film.class,message = "缺少參數(shù)") })
          public ResultModel addFilm(@ApiParam("電影名稱") @RequestParam("filmName") String filmName,
          @ApiParam(value = "分?jǐn)?shù)", allowEmptyValue = true) @RequestParam("score") Short score,
          @ApiParam("發(fā)布時(shí)間") @RequestParam(value = "publishTime",required = false) String publishTime,
          @ApiParam("創(chuàng)建者id") @RequestParam("creatorId") Long creatorId)
          {

          if (Objects.isNull(filmName) || Objects.isNull(score) || Objects.isNull(publishTime) || StringUtils
          .isEmpty(creatorId)) {
          return new ResultModel(ResultModel.failed, "參數(shù)錯(cuò)誤");
          }
          Film filmPOM = new Film();
          filmPOM.setFilmName(filmName);
          filmPOM.setScore(score);
          DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
          Date publishTimeDate = null;
          try {
          publishTimeDate = simpleDateFormat.parse(publishTime);
          } catch (Exception ex) {
          ex.printStackTrace();
          }
          filmPOM.setPublishTime(publishTimeDate);
          filmPOM.setCreatorId(creatorId);
          Boolean result = filmService.addFilm(filmPOM);
          if (result) {
          return new ResultModel(CommonConstants.SUCCESSMSG);
          }
          return new ResultModel(CommonConstants.FAILD_MSG);
          }

          /**
          * 根據(jù)電影名字獲取電影
          *
          * @param fileName
          * @return
          */

          @GetMapping("/getFilms")
          @ApiOperation(value = "根據(jù)名字獲取電影")
          @ApiResponses(value = { @ApiResponse(code = 1000, message = "成功"), @ApiResponse(code = 1001, message = "失敗"),
          @ApiResponse(code = 1002, message = "缺少參數(shù)") })
          public ResultModel getFilmsByName(@ApiParam("電影名稱") @RequestParam("fileName") String fileName) {
          if (StringUtils.isEmpty(fileName)) {
          return CommonConstants.getErrorResultModel();
          }

          List<Film> films = filmService.getFilmByName(fileName);
          if (!CollectionUtils.isEmpty(films)) {
          return new ResultModel(films);
          }
          return CommonConstants.getErrorResultModel();

          }

          /**
          * 根據(jù)電影名更新
          *
          * @return
          */

          @PostMapping("/updateScore")
          @ApiOperation(value = "根據(jù)電影名修改分?jǐn)?shù)")
          @ApiResponses(value = { @ApiResponse(code = 1000, message = "成功"), @ApiResponse(code = 1001, message = "失敗"),
          @ApiResponse(code = 1002, message = "缺少參數(shù)") })
          public ResultModel updateFilmScore(@ApiParam("電影名稱") @RequestParam("fileName") String fileName,
          @ApiParam("分?jǐn)?shù)") @RequestParam("score") Short score)
          {
          if (StringUtils.isEmpty(fileName) || Objects.isNull(score)) {
          return CommonConstants.getErrorResultModel();
          }

          filmService.updateScoreByName(fileName, score);
          return CommonConstants.getSuccessResultModel();
          }

          /**
          * 根據(jù)電影名刪除電影
          *
          * @param request
          * @return
          */

          @PostMapping("/delFilm")
          @ApiOperation(value = "根據(jù)電影名刪除電影")
          @ApiImplicitParams({ @ApiImplicitParam(name = "filmName",
          value = "電影名",
          dataType = "String",
          paramType = "query",
          required = true), @ApiImplicitParam(name = "id", value = "電影id", dataType = "int", paramType = "query") })
          public ResultModel deleteFilmByNameOrId(HttpServletRequest request) {
          //電影名
          String filmName = request.getParameter("filmName");
          //電影id
          Long filmId = Long.parseLong(request.getParameter("id"));

          filmService.deleteFilmOrId(filmName,filmId);


          return CommonConstants.getSuccessResultModel();
          }

          /**
          * 根據(jù)id獲取電影
          *
          * @param id
          * @return
          */

          @PostMapping("/{id}")
          @ApiOperation("根據(jù)id獲取電影")
          @ApiImplicitParam(name = "id", value = "電影id", dataType = "long", paramType = "path", required = true)
          public ResultModel getFilmById(@PathVariable Long id) {

          if (Objects.isNull(id)) {
          return CommonConstants.getLessParamResultModel();
          }
          Film film = filmService.getFilmById(id);
          if (Objects.nonNull(film)) {
          return new ResultModel(film);
          }
          return CommonConstants.getErrorResultModel();
          }

          /**
          * 修改整個(gè)電影
          *
          * @param film
          * @return
          */

          @PostMapping("/insertFilm")
          @ApiOperation("插入一部電影")
          public ResultModel insertFilm(@ApiParam("電影實(shí)體對(duì)象") @RequestBody Film film) {
          if (Objects.isNull(film)) {
          return CommonConstants.getLessParamResultModel();
          }
          Boolean isSuccess = filmService.insertFilm(film);
          if (isSuccess) {
          return CommonConstants.getSuccessResultModel();
          }
          return CommonConstants.getErrorResultModel();
          }
          }

          4.2:訪問(wèn)本地鏈接

          http://localhost:8080/swagger-ui.html#/

          可以看出訪問(wèn)的url都很清晰的展示在它最終的頁(yè)面上,我們打開(kāi)一個(gè)方法:可以看出方法的請(qǐng)求參數(shù)清晰的的羅列出來(lái),包括方法的返回值。并且有一個(gè)很重要的功能,只需要點(diǎn)下方的try it out就可以進(jìn)行接口測(cè)試,

          五:使用swagger需要注意的問(wèn)題

          • 對(duì)于只有一個(gè)HttpServletRequest參數(shù)的方法,如果參數(shù)小于5個(gè),推薦使用 @ApiImplicitParams的方式單獨(dú)封裝每一個(gè)參數(shù);如果參數(shù)大于5個(gè),采用定義一個(gè)對(duì)象去封裝所有參數(shù)的屬性,然后使用@APiParam的方式
          • 默認(rèn)的訪問(wèn)地址:ip:port/swagger-ui.html#/,但是在shiro中,會(huì)攔截所有的請(qǐng)求,必須加上默認(rèn)訪問(wèn)路徑(比如項(xiàng)目中,就是ip:port/context/swagger-ui.html#/),然后登陸后才可以看到
          • 在GET請(qǐng)求中,參數(shù)在Body體里面,不能使用@RequestBody。在POST請(qǐng)求,可以使用@RequestBody和@RequestParam,如果使用@RequestBody,對(duì)于參數(shù)轉(zhuǎn)化的配置必須統(tǒng)一
          • controller必須指定請(qǐng)求類型,否則swagger會(huì)把所有的類型(6種)都生成出來(lái)
          • swagger在生產(chǎn)環(huán)境不能對(duì)外暴露,可以使用@Profile({“dev”, “prod”,“pre”})指定可以使用的環(huán)境

          六:總結(jié)

          swagger作為一款輔助性的工具,能大大提升我們的和前端的溝通效率,接口是一個(gè)非常重要的傳遞數(shù)據(jù)的媒介,每個(gè)接口的簽名、方法參數(shù)都非常重要。一個(gè)良好的文檔非常重要,如果采用手寫的方式非常容易拼寫錯(cuò)誤,而swagger可以自動(dòng)化生成參數(shù)文檔,這一切都加快了我們的溝通效率。并且可以替代postman的作用。實(shí)在是開(kāi)發(fā)編程必備良品啊。

          瀏覽 68
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产乱子伦| 午夜福利无码视频 | 中国免费毛片网络 | 99国产精品久久久久久久 | 人妻中文一区在线 |