swagger是一個非常簡單,強大的框架。快速上手,只需要引入jar包 , 使用注解就可以生成一個漂亮的在線api文檔
pom.xml
<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>
寫一個總的標題,對整個文檔的描述
waggerConfig.java
package com.lzh; import java.util.ArrayList; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ParameterBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.schema.ModelRef; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.service.Parameter; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class Swagger2 { /** * @Description:swagger2的配置文件,這里可以配置swagger2的一些基本的內容,比如掃描的包等等 */ @Bean public Docket createRestApi() { // 為swagger添加header參數可供輸入 ParameterBuilder userTokenHeader = new ParameterBuilder(); ParameterBuilder userIdHeader = new ParameterBuilder(); List<Parameter> pars = new ArrayList<Parameter>(); userTokenHeader.name("headerUserToken").description("userToken") .modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); userIdHeader.name("headerUserId").description("userId") .modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); pars.add(userTokenHeader.build()); pars.add(userIdHeader.build()); return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() .apis(RequestHandlerSelectors.basePackage("com.lzh.controller")) .paths(PathSelectors.any()).build() .globalOperationParameters(pars); } /** * @Description: 構建 api文檔的信息 */ private ApiInfo apiInfo() { return new ApiInfoBuilder() // 設置頁面標題 .title("使用swagger2構建短視頻后端api接口文檔") // 設置聯系人 .contact(new Contact("敲代碼的卡卡羅特", "http://www.imooc.com", "imooc@163.com")) // 描述 .description("歡迎訪問短視頻接口文檔,這里是描述信息") // 定義版本號 .version("1.0").build(); } }
然后在controller中寫上需要注釋的方法,一般需要這幾種就可以滿足我們了 。
1.注釋方法名字 @ApiOperation("上傳文件")
2.注釋方法中所需的參數的意思 (參數是封裝的對象,寫在pojo的字段上) @ApiModelProperty("用戶密碼")
2.注釋方法中所需的參數的意思 (參數是普通的類型,寫在方法的參數上) @ApiParam("文件file對象")
3.對接口類的描述 @Api(value="用戶注冊登錄的接口", tags= {"注冊和登錄的controller"})
情景1:當方法的參數是一個對象的時候,比如登陸注冊。我們就需要在user對象中寫注解。
package com.lzh.controller; import com.lzh.pojo.Users; import com.lzh.service.UserService; import com.lzh.utils.IMoocJSONResult; import com.lzh.utils.MD5Utils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; /** * Created by 敲代碼的卡卡羅特 * on 2018/11/2 12:37. */ @RestController @Api(value="用戶注冊登錄的接口", tags= {"注冊和登錄的controller"}) public class RegistLoginController { @Autowired private UserService userService; @ApiOperation(value="用戶注冊", notes="用戶注冊的接口") @PostMapping("/regist") public IMoocJSONResult regist( @RequestBody Users user) throws Exception { // 1. 判斷用戶名和密碼必須不為空 if (StringUtils.isBlank(user.getUsername()) || StringUtils.isBlank(user.getPassword())) { return IMoocJSONResult.errorMsg("用戶名和密碼不能為空"); } // 2. 判斷用戶名是否存在 boolean usernameIsExist = userService.queryUsernameIsExist(user.getUsername()); // 3. 保存用戶,注冊信息 if (!usernameIsExist) { user.setNickname(user.getUsername()); user.setPassword(MD5Utils.getMD5Str(user.getPassword())); user.setFansCounts(0); user.setReceiveLikeCounts(0); user.setFollowCounts(0); userService.saveUser(user); } else { return IMoocJSONResult.errorMsg("用戶名已經存在,請換一個再試"); } user.setPassword(""); // UsersVO userVO = setUserRedisSessionToken(user); return IMoocJSONResult.ok(user); } }
對應的pojo
package com.lzh.pojo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import javax.persistence.Column; import javax.persistence.Id; @ApiModel(value="用戶對象", description="這是用戶對象") public class Users { @ApiModelProperty(hidden=true) @Id private String id; /** * 用戶名 */ @ApiModelProperty(value="用戶名", name="username", example="imoocuser", required=true) private String username; /** * 密碼 */ @ApiModelProperty(value="密碼", name="password", example="123456", required=true) private String password; /** * 我的頭像,如果沒有默認給一張 */ @ApiModelProperty(hidden=true) @Column(name = "face_image") private String faceImage; /** * 昵稱 */ @ApiModelProperty(hidden=true) private String nickname; /** * 我的粉絲數量 */ @ApiModelProperty(hidden=true) @Column(name = "fans_counts") private Integer fansCounts; /** * 我關注的人總數 */ @ApiModelProperty(hidden=true) @Column(name = "follow_counts") private Integer followCounts; /** * 我接受到的贊美/收藏 的數量 */ @ApiModelProperty(hidden=true) @Column(name = "receive_like_counts") private Integer receiveLikeCounts; public Users() { super(); } public Users(String id, String username, String password, String faceImage, String nickname, Integer fansCounts, Integer followCounts, Integer receiveLikeCounts) { super(); this.id = id; this.username = username; this.password = password; this.faceImage = faceImage; this.nickname = nickname; this.fansCounts = fansCounts; this.followCounts = followCounts; this.receiveLikeCounts = receiveLikeCounts; } /** * @return id */ public String getId() { return id; } /** * @param id */ public void setId(String id) { this.id = id; } /** * 獲取用戶名 * * @return username - 用戶名 */ public String getUsername() { return username; } /** * 設置用戶名 * * @param username 用戶名 */ public void setUsername(String username) { this.username = username; } /** * 獲取密碼 * * @return password - 密碼 */ public String getPassword() { return password; } /** * 設置密碼 * * @param password 密碼 */ public void setPassword(String password) { this.password = password; } /** * 獲取我的頭像,如果沒有默認給一張 * * @return face_image - 我的頭像,如果沒有默認給一張 */ public String getFaceImage() { return faceImage; } /** * 設置我的頭像,如果沒有默認給一張 * * @param faceImage 我的頭像,如果沒有默認給一張 */ public void setFaceImage(String faceImage) { this.faceImage = faceImage; } /** * 獲取昵稱 * * @return nickname - 昵稱 */ public String getNickname() { return nickname; } /** * 設置昵稱 * * @param nickname 昵稱 */ public void setNickname(String nickname) { this.nickname = nickname; } /** * 獲取我的粉絲數量 * * @return fans_counts - 我的粉絲數量 */ public Integer getFansCounts() { return fansCounts; } /** * 設置我的粉絲數量 * * @param fansCounts 我的粉絲數量 */ public void setFansCounts(Integer fansCounts) { this.fansCounts = fansCounts; } /** * 獲取我關注的人總數 * * @return follow_counts - 我關注的人總數 */ public Integer getFollowCounts() { return followCounts; } /** * 設置我關注的人總數 * * @param followCounts 我關注的人總數 */ public void setFollowCounts(Integer followCounts) { this.followCounts = followCounts; } /** * 獲取我接受到的贊美/收藏 的數量 * * @return receive_like_counts - 我接受到的贊美/收藏 的數量 */ public Integer getReceiveLikeCounts() { return receiveLikeCounts; } /** * 設置我接受到的贊美/收藏 的數量 * * @param receiveLikeCounts 我接受到的贊美/收藏 的數量 */ public void setReceiveLikeCounts(Integer receiveLikeCounts) { this.receiveLikeCounts = receiveLikeCounts; } }
情景2:當參數是普通類型時,比如查詢操作(1個參數時),我們可以在方法的上面寫注解
@ApiOperation(value="用戶注銷", notes="用戶注銷的接口") @ApiImplicitParam(name="userId", value="用戶id", required=true, dataType="String", paramType="query") @PostMapping("/logout") public IMoocJSONResult logout(String userId) throws Exception { redis.del(USER_REDIS_SESSION + ":" + userId); return IMoocJSONResult.ok(); }
情景3:當參數是普通類型時,比如查詢操作(多個參數時)
@ApiOperation(value="上傳視頻", notes="上傳視頻的接口") @ApiImplicitParams({ @ApiImplicitParam(name="userId", value="用戶id", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="bgmId", value="背景音樂id", required=false, dataType="String", paramType="form"), @ApiImplicitParam(name="videoSeconds", value="背景音樂播放長度", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="videoWidth", value="視頻寬度", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="videoHeight", value="視頻高度", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="desc", value="視頻描述", required=false, dataType="String", paramType="form") }) @PostMapping(value="/upload", headers="content-type=multipart/form-data") public IMoocJSONResult upload(String userId, String bgmId, double videoSeconds, int videoWidth, int videoHeight, String desc, @ApiParam(value="短視頻", required=true) MultipartFile file) throws Exception { if (StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用戶id不能為空..."); } // 文件保存的命名空間 // String fileSpace = "C:/imooc_videos_dev"; // 保存到數據庫中的相對路徑 String uploadPathDB = "/" + userId + "/video"; String coverPathDB = "/" + userId + "/video"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; // 文件上傳的最終保存路徑 String finalVideoPath = ""; try { if (file != null) { String fileName = file.getOriginalFilename(); // abc.mp4 String arrayFilenameItem[] = fileName.split("\\."); String fileNamePrefix = ""; for (int i = 0 ; i < arrayFilenameItem.length-1 ; i ++) { fileNamePrefix += arrayFilenameItem[i]; } // fix bug: 解決小程序端OK,PC端不OK的bug,原因:PC端和小程序端對臨時視頻的命名不同 // String fileNamePrefix = fileName.split("\\.")[0]; if (StringUtils.isNotBlank(fileName)) { finalVideoPath = FILE_SPACE + uploadPathDB + "/" + fileName; // 設置數據庫保存的路徑 uploadPathDB += ("/" + fileName); coverPathDB = coverPathDB + "/" + fileNamePrefix + ".jpg"; File outFile = new File(finalVideoPath); if (outFile.getParentFile() != null || !outFile.getParentFile().isDirectory()) { // 創建父文件夾 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = file.getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } } else { return IMoocJSONResult.errorMsg("上傳出錯..."); } } catch (Exception e) { e.printStackTrace(); return IMoocJSONResult.errorMsg("上傳出錯..."); } finally { if (fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } // 判斷bgmId是否為空,如果不為空, // 那就查詢bgm的信息,並且合並視頻,生產新的視頻 if (StringUtils.isNotBlank(bgmId)) { Bgm bgm = bgmService.queryBgmById(bgmId); String mp3InputPath = FILE_SPACE + bgm.getPath(); MergeVideoMp3 tool = new MergeVideoMp3(FFMPEG_EXE); String videoInputPath = finalVideoPath; String videoOutputName = UUID.randomUUID().toString() + ".mp4"; uploadPathDB = "/" + userId + "/video" + "/" + videoOutputName; finalVideoPath = FILE_SPACE + uploadPathDB; tool.convertor(videoInputPath, mp3InputPath, videoSeconds, finalVideoPath); } System.out.println("uploadPathDB=" + uploadPathDB); System.out.println("finalVideoPath=" + finalVideoPath); // 對視頻進行截圖 FetchVideoCover videoInfo = new FetchVideoCover(FFMPEG_EXE); videoInfo.getCover(finalVideoPath, FILE_SPACE + coverPathDB); // 保存視頻信息到數據庫 Videos video = new Videos(); video.setAudioId(bgmId); video.setUserId(userId); video.setVideoSeconds((float)videoSeconds); video.setVideoHeight(videoHeight); video.setVideoWidth(videoWidth); video.setVideoDesc(desc); video.setVideoPath(uploadPathDB); video.setCoverPath(coverPathDB); video.setStatus(VideoStatusEnum.SUCCESS.value); video.setCreateTime(new Date()); String videoId = videoService.saveVideo(video); return IMoocJSONResult.ok(videoId); }
最后:訪問 http://localhost:8080/swagger-ui.html
推薦一篇寫的不錯的博客:https://www.cnblogs.com/jiekzou/p/9207458.html
