swagger使用指南
前言:作為一個(gè)以前后端分離為模式開發(fā)小組,我們每隔一段時(shí)間都進(jìn)行這樣一個(gè)場景:前端人員和后端開發(fā)在一起熱烈的討論"哎,你這參數(shù)又變了啊","接口怎么又請求不通了啊","你再試試,我打個(gè)斷點(diǎn)調(diào)試一下.."。可以看到在前后端溝通中出現(xiàn)了不少問題。對于這樣的問題,之前一直沒有很好的解決方案,直到它的出現(xiàn),沒錯(cuò)...這就是我們今天要討論的神器:swagger,一款致力于解決接口規(guī)范化、標(biāo)準(zhǔn)化、文檔化的開源庫,一款真正的開發(fā)神器。
目錄
一:swagger是什么?
二:為什么要使用swaager?
三:如何搭一個(gè)swagger?
四:如何在項(xiàng)目中集成swagger
五:使用swagger需要注意的問題
六:總結(jié)
一:swagger是什么?
? ? Swagger是一款RESTFUL接口的文檔在線自動(dòng)生成+功能測試功能軟件。Swagger是一個(gè)規(guī)范和完整的框架,用于生成、描述、調(diào)用和可視化RESTful風(fēng)格的Web服務(wù)。目標(biāo)是使客戶端和文件系統(tǒng)作為服務(wù)器以同樣的速度來更新文件的方法,參數(shù)和模型緊密集成到服務(wù)器。這個(gè)解釋簡單點(diǎn)來講就是說,swagger是一款可以根據(jù)resutful風(fēng)格生成的生成的接口開發(fā)文檔,并且支持做測試的一款中間軟件。
二:為什么要使用swaager?
2.1:對于后端開發(fā)人員來說
①:不用再手寫WiKi接口拼大量的參數(shù),避免手寫錯(cuò)誤
②:對代碼侵入性低,采用全注解的方式,開發(fā)簡單
③:方法參數(shù)名修改、增加、減少參數(shù)都可以直接生效,不用手動(dòng)維護(hù)
④:缺點(diǎn):增加了開發(fā)成本,寫接口還得再寫一套參數(shù)配置
2.2:對于前端開發(fā)來說
?①:后端只需要定義好接口,會(huì)自動(dòng)生成文檔,接口功能、參數(shù)一目了然
②:聯(lián)調(diào)方便,如果出問題,直接測試接口,實(shí)時(shí)檢查參數(shù)和返回值,就可以快速定位是前端還是后端的問題
2.3:對于測試
①對于某些沒有前端界面UI的功能,可以用它來測試接口?
②操作簡單,不用了解具體代碼就可以操作
三:如何搭一個(gè)swagger
3.1:引入swagger的依賴,目前推薦使用2.7.0版本,因?yàn)?.6.0版本有bug,而其他版本又沒有經(jīng)過驗(yàn)證,所以在比較保守的情況下,我比較推薦的版本是2.7.0,并且它是經(jīng)過我驗(yàn)證的。
一:引入Swagger依賴庫 <!--引入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
springboot整合swagger,只需要添加一個(gè)swagger的配置類,添加上@bean注解,就可以實(shí)現(xiàn)Bean的注入,然后添加一個(gè)ApiInfo的配置,添加注解掃描,其實(shí)對于掃描這里,配置分類兩類,一個(gè)是包的路徑掃描,一個(gè)是按照注解的掃描,我比價(jià)推薦的方式是按照注解,因?yàn)樵趕wageer的實(shí)際使用中,你得在每個(gè)api中添加@APi的注解,但是如果配置成包的話,有可能會(huì)有遺漏,或者新增加包路徑可能忘了配置,就導(dǎo)致配置無效。
@Configuration @EnableSwagger2 public?class?SwaggerConfig {@Beanpublic?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的核心在于注解,接下來就著重講一下swagger的注解:
這是我整理的一個(gè)表格,基本上囊括了swagger的常用注解,表格說的很清晰了,我就不一一贅述了,下面會(huì)給出具體的應(yīng)用實(shí)際例子:
?四:在項(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 = { "電影訪問接口" }) @RequestMapping("/film") public class FilmController {@Autowiredprivate 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");//電影idLong 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í)體對象") @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:訪問本地鏈接?http://localhost:8080/swagger-ui.html#/
可以看出訪問的url都很清晰的展示在它最終的頁面上,我們打開一個(gè)方法:可以看出方法的請求參數(shù)清晰的的羅列出來,包括方法的返回值。并且有一個(gè)很重要的功能,只需要點(diǎn)下方的try it out就可以進(jìn)行接口測試,
?五:使用swagger需要注意的問題
①:對于只有一個(gè)HttpServletRequest參數(shù)的方法,如果參數(shù)小于5個(gè),推薦使用?? @ApiImplicitParams的方式單獨(dú)封裝每一個(gè)參數(shù);如果參數(shù)大于5個(gè),采用定義一個(gè)對象去封裝所有參數(shù)的屬性,然后使用@APiParam的方式
②默認(rèn)的訪問地址:ip:port/swagger-ui.html#/,但是在shiro中,會(huì)攔截所有的請求,必須加上默認(rèn)訪問路徑(比如項(xiàng)目中,就是ip:port/context/swagger-ui.html#/),然后登陸后才可以看到?
③在GET請求中,參數(shù)在Body體里面,不能使用@RequestBody。在POST請求,可以使用@RequestBody和@RequestParam,如果使用@RequestBody,對于參數(shù)轉(zhuǎn)化的配置必須統(tǒng)一
④?controller必須指定請求類型,否則swagger會(huì)把所有的類型(6種)都生成出來
?
⑤: swagger在生產(chǎn)環(huán)境不能對外暴露,可以使用@Profile({“dev”, “prod”,“pre”})指定可以使用的環(huán)境
六:總結(jié)
? swagger作為一款輔助性的工具,能大大提升我們的和前端的溝通效率,接口是一個(gè)非常重要的傳遞數(shù)據(jù)的媒介,每個(gè)接口的簽名、方法參數(shù)都非常重要。一個(gè)良好的文檔非常重要,如果采用手寫的方式非常容易拼寫錯(cuò)誤,而swagger可以自動(dòng)化生成參數(shù)文檔,這一切都加快了我們的溝通效率。并且可以替代postman的作用。實(shí)在是開發(fā)編程必備良品啊。
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/wyq178/p/10291447.html
超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的swagger使用指南的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux脚本中$#、$0、$1、$@、
- 下一篇: 简易的CRM系统案例之SpringMVC