SpringBoot實戰電商項目mall(20k+star)地址: https://github.com/macrozheng/mall
本文主要講解mall是如何經過整合Swagger-UI來實現一份至關完善的在線API文檔的。html
Swagger-UI是HTML, Javascript, CSS的一個集合,能夠動態地根據註解生成在線API文檔。
在pom.xml中新增Swagger-UI相關依賴
<!--Swagger-UI API文檔生產工具--> <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>
添加Swagger-UI的Java配置文件
注意:Swagger對生成API文檔的範圍有三種不一樣的選擇java
package com.macro.mall.tiny.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /** * Swagger2API文檔的配置 */ @Configuration @EnableSwagger2 public class Swagger2Config { @Bean public Docket createRestApi(){ return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() //爲當前包下controller生成API文檔 .apis(RequestHandlerSelectors.basePackage("com.macro.mall.tiny.controller")) //爲有@Api註解的Controller生成API文檔 // .apis(RequestHandlerSelectors.withClassAnnotation(Api.class)) //爲有@ApiOperation註解的方法生成API文檔 // .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("SwaggerUI演示") .description("mall-tiny") .contact("macro") .version("1.0") .build(); } }
給原有的品牌管理Controller添加上Swagger註解
package com.macro.mall.tiny.controller; import com.macro.mall.tiny.common.api.CommonPage; import com.macro.mall.tiny.common.api.CommonResult; import com.macro.mall.tiny.mbg.model.PmsBrand; import com.macro.mall.tiny.service.PmsBrandService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import java.util.List; /** * 品牌管理Controller * Created by macro on 2019/4/19. */ @Api(tags = "PmsBrandController", description = "商品品牌管理") @Controller @RequestMapping("/brand") public class PmsBrandController { @Autowired private PmsBrandService brandService; private static final Logger LOGGER = LoggerFactory.getLogger(PmsBrandController.class); @ApiOperation("獲取全部品牌列表") @RequestMapping(value = "listAll", method = RequestMethod.GET) @ResponseBody public CommonResult<List<PmsBrand>> getBrandList() { return CommonResult.success(brandService.listAllBrand()); } @ApiOperation("添加品牌") @RequestMapping(value = "/create", method = RequestMethod.POST) @ResponseBody public CommonResult createBrand(@RequestBody PmsBrand pmsBrand) { CommonResult commonResult; int count = brandService.createBrand(pmsBrand); if (count == 1) { commonResult = CommonResult.success(pmsBrand); LOGGER.debug("createBrand success:{}", pmsBrand); } else { commonResult = CommonResult.failed("操做失敗"); LOGGER.debug("createBrand failed:{}", pmsBrand); } return commonResult; } @ApiOperation("更新指定id品牌信息") @RequestMapping(value = "/update/{id}", method = RequestMethod.POST) @ResponseBody public CommonResult updateBrand(@PathVariable("id") Long id, @RequestBody PmsBrand pmsBrandDto, BindingResult result) { CommonResult commonResult; int count = brandService.updateBrand(id, pmsBrandDto); if (count == 1) { commonResult = CommonResult.success(pmsBrandDto); LOGGER.debug("updateBrand success:{}", pmsBrandDto); } else { commonResult = CommonResult.failed("操做失敗"); LOGGER.debug("updateBrand failed:{}", pmsBrandDto); } return commonResult; } @ApiOperation("刪除指定id的品牌") @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET) @ResponseBody public CommonResult deleteBrand(@PathVariable("id") Long id) { int count = brandService.deleteBrand(id); if (count == 1) { LOGGER.debug("deleteBrand success :id={}", id); return CommonResult.success(null); } else { LOGGER.debug("deleteBrand failed :id={}", id); return CommonResult.failed("操做失敗"); } } @ApiOperation("分頁查詢品牌列表") @RequestMapping(value = "/list", method = RequestMethod.GET) @ResponseBody public CommonResult<CommonPage<PmsBrand>> listBrand(@RequestParam(value = "pageNum", defaultValue = "1") @ApiParam("頁碼") Integer pageNum, @RequestParam(value = "pageSize", defaultValue = "3") @ApiParam("每頁數量") Integer pageSize) { List<PmsBrand> brandList = brandService.listBrand(pageNum, pageSize); return CommonResult.success(CommonPage.restPage(brandList)); } @ApiOperation("獲取指定id的品牌詳情") @RequestMapping(value = "/{id}", method = RequestMethod.GET) @ResponseBody public CommonResult<PmsBrand> brand(@PathVariable("id") Long id) { return CommonResult.success(brandService.getBrand(id)); } }
CommentGenerator爲MyBatis Generator的自定義註釋生成器,修改addFieldComment方法使其生成Swagger的@ApiModelProperty註解來取代原來的方法註釋,添加addJavaFileComment方法,使其能在import中導入@ApiModelProperty,不然須要手動導入該類,在須要生成大量實體類時,是一件很是麻煩的事。
package com.macro.mall.tiny.mbg; import org.mybatis.generator.api.IntrospectedColumn; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.dom.java.CompilationUnit; import org.mybatis.generator.api.dom.java.Field; import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType; import org.mybatis.generator.internal.DefaultCommentGenerator; import org.mybatis.generator.internal.util.StringUtility; import java.util.Properties; /** * 自定義註釋生成器 * Created by macro on 2018/4/26. */ public class CommentGenerator extends DefaultCommentGenerator { private boolean addRemarkComments = false; private static final String EXAMPLE_SUFFIX="Example"; private static final String API_MODEL_PROPERTY_FULL_CLASS_NAME="io.swagger.annotations.ApiModelProperty"; /** * 設置用戶配置的參數 */ @Override public void addConfigurationProperties(Properties properties) { super.addConfigurationProperties(properties); this.addRemarkComments = StringUtility.isTrue(properties.getProperty("addRemarkComments")); } /** * 給字段添加註釋 */ @Override public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { String remarks = introspectedColumn.getRemarks(); //根據參數和備註信息判斷是否添加備註信息 if(addRemarkComments&&StringUtility.stringHasValue(remarks)){ // addFieldJavaDoc(field, remarks); //數據庫中特殊字符須要轉義 if(remarks.contains("\"")){ remarks = remarks.replace("\"","'"); } //給model的字段添加swagger註解 field.addJavaDocLine("@ApiModelProperty(value = \""+remarks+"\")"); } } /** * 給model的字段添加註釋 */ private void addFieldJavaDoc(Field field, String remarks) { //文檔註釋開始 field.addJavaDocLine("/**"); //獲取數據庫字段的備註信息 String[] remarkLines = remarks.split(System.getProperty("line.separator")); for(String remarkLine:remarkLines){ field.addJavaDocLine(" * "+remarkLine); } addJavadocTag(field, false); field.addJavaDocLine(" */"); } @Override public void addJavaFileComment(CompilationUnit compilationUnit) { super.addJavaFileComment(compilationUnit); //只在model中添加swagger註解類的導入 if(!compilationUnit.isJavaInterface()&&!compilationUnit.getType().getFullyQualifiedName().contains(EXAMPLE_SUFFIX)){ compilationUnit.addImportedType(new FullyQualifiedJavaType(API_MODEL_PROPERTY_FULL_CLASS_NAME)); } } }
運行com.macro.mall.tiny.mbg.Generator的main方法,從新生成mbg中的代碼,能夠看到PmsBrand類中已經自動根據數據庫註釋添加了@ApiModelProperty註解
接口地址:http://localhost:8080/swagger-ui.htmlgit
https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-02github
mall項目全套學習教程連載中,關注公衆號第一時間獲取。web