利用Swagger2自動生成對外接口的文檔
一直以來做對外的接口文檔都比較原始,基本上都是手寫的文檔傳來傳去,最近發現了一個新玩具,可以在接口上省去不少麻煩。
swagger是一款方便展示的API文檔框架。它可以將接口的類型最全面的展示給對方開發人員,避免了手寫文檔的片面和誤差行為。
swagger目前有兩種swagger和swagger2兩種,1比較麻煩,所以不考慮使用。本文主要記錄我用swagger2做對外接口的兩種方式,方面后面查閱。
一、使用傳統的springmvc整合swagger2
1、maven依賴
<!--springfox依賴-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
2、spring-mvc.xml 中添加映射靜態的配置(其實我項目中把這個去掉也可以,不知道什么情況):
<!-- swagger靜態文件路徑 -->
<mvc:resources location="classpath:/META-INF/resources/" mapping="swagger-ui.html"/>
<mvc:resources location="classpath:/META-INF/resources/webjars/" mapping="/webjars/**"/>
注意:基本的springmvc配置我就不貼了,需要注意的是,如果你看到swagger-ui.html 界面出來,但卻一片空白,請檢查下你web.xml中攔截器的配置,一定要springmvc先攔截到,然后界面才會顯示的。
3、然后是swagger2的配置類:
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("net.laoyeyey.yyblog"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("yyblog項目 RESTful APIs")
.description("yyblog項目api接口文檔")
.version("1.0")
.build();
}
}
注意:paths如果在生產情況下可以調整為PathSelectors.none(),即不顯示所有接口信息;
4、接口信息配置
即在SpringMvc的Controller中配置相關的接口信息
@Controller
@RequestMapping(value = "aitou")
@Api(description = "測試服務-賬戶信息查詢")
public class DailyOperationDataController {
Logger logger = Logger.getLogger(DailyOperationDataController.class);
@Autowired
private DailyOperationDataService DailyOperationDataService;
/*
* @ApiOperation(value = "接口說明", httpMethod ="接口請求方式", response ="接口返回參數類型", notes ="接口發布說明"
* @ApiParam(required = "是否必須參數", name ="參數名稱", value ="參數具體描述"
*/
@ApiOperation(value = "賬戶信息查詢接口")
@RequestMapping(method ={RequestMethod.POST,RequestMethod.GET}, value="/query/dailydata/{dataDate}")
@ResponseBody
public DailyOperationDataDto getDailyReportByDataDate(@PathVariable("dataDate") String dataDate) {
try {
return DailyOperationDataService.getDailyReportByDataDate(dataDate);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
}
注:通常情況下swagger2會將掃描包下所有的接口展示出來,這里我是對外的接口是單獨一個包,避免展示過多的接口,當然接口方法也可以讓它不展示。可以在下面看到相關的注解中有寫。
常用的一些注解
@Api:用在類上,說明該類的作用
@ApiOperation:用在方法上,說明方法的作用
@ApiImplicitParams:用在方法上包含一組參數說明
@ApiImplicitParam:用在 @ApiImplicitParams 注解中,指定一個請求參數的各個方面
paramType:參數放在哪個地方
· header --> 請求參數的獲取:@RequestHeader
· query -->請求參數的獲取:@RequestParam
· path(用於restful接口)--> 請求參數的獲取:@PathVariable
· body(不常用)
· form(不常用)
name:參數名
dataType:參數類型
required:參數是否必須傳
value:參數的意思
defaultValue:參數的默認值
@ApiResponses:用於表示一組響應
@ApiResponse:用在@ApiResponses中,一般用於表達一個錯誤的響應信息
code:數字,例如400
message:信息,例如"請求參數沒填好"
response:拋出異常的類
@ApiParam:單個參數描述
@ApiModel:描述一個Model的信息,用對象來接收參數(這種一般用在post創建的時候,使用@RequestBody這樣的場景,請求參數無法使用@ApiImplicitParam注解進行描述的時候)
@ApiModelProperty:描述一個model的屬性
@ApiProperty:用對象接收參數時,描述對象的一個字段
@ApiIgnore:使用該注解忽略這個API
基本上就是上面這些了,是不是很easy,下面看下效果圖


二、使用springboot整合swagger2
上面說了使用傳統的springmvc整合swagger2,在說說最近比較流行的springboot的方式,其實原理都是一樣的。
1、maven依賴
<!--springfox依賴 -->
<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>
這個是我最近用springboot寫的個人項目中的內用,版本用的2.7.0
2、添加靜態資源配置
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {/**
* 配置靜態資源路徑以及上傳文件的路徑
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
registry.addResourceHandler("/upload/**").addResourceLocations(environment.getProperty("spring.resources.static-locations"));
/*swagger-ui*/
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
其實就是最后兩句,如果你不配置這個的話,訪問swagger-ui.html會出現500,還是404的錯誤來着,記不清了,應該是404.
3、swagger2的配置類
和上面一樣,基本上沒區別
@Configuration
@EnableSwagger2
@EnableWebMvc
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("net.laoyeye.yyblog.web.frontend"))
.paths(PathSelectors.none())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("yyblog項目 RESTful APIs")
.description("yyblog項目api接口文檔")
.version("1.0")
.build();
}
}
注意,我上面有說path的問題哦,直接拷貝不顯示api的,(#^.^#)
4、接口的配置
/**
* 前台文章Controller
* @author 小賣鋪的老爺爺
* @date 2018年5月5日
* @website www.laoyeye.net
*/
@Api(description="文章查詢")
@Controller
@RequestMapping("/article")
public class ArticleController {
@Autowired
private ArticleService articleService;
@Autowired
private SettingService settingService;
@Autowired
private CateService cateService;
@Autowired
private TagReferService tagReferService;
@Autowired
private UserService userService;
@Autowired
private ArticleMapper articleMapper;
@Autowired
private CommentService commentService;
@ApiOperation(value="文章查詢接口")
@ApiImplicitParam(name = "id", value = "文章ID", required = true, dataType = "Long")
@GetMapping("/{id}")
public String index(Model model, @PathVariable("id") Long id) {
try {
articleService.updateViewsById(id);
} catch (Exception ignore) {
}
List<Setting> settings = settingService.listAll();
Map<String,Object> map = new HashMap<String,Object>();
for (Setting setting : settings) {
map.put(setting.getCode(), setting.getValue());
}
Article article = articleService.getArticleById(id);
model.addAttribute("settings", map);
model.addAttribute("cateList", cateService.listAllCate());
model.addAttribute("article", article);
model.addAttribute("tags", tagReferService.listNameByArticleId(article.getId()));
model.addAttribute("author", userService.getNicknameById(article.getAuthorId()));
//回頭改
model.addAttribute("articles", articleMapper.listArticleByTitle(null));
model.addAttribute("similars", articleMapper.listArticleByTitle(null));
CommentQuery query = new CommentQuery();
query.setLimit(10);
query.setPage(1);
query.setArticleId(id);
model.addAttribute("comments", commentService.listCommentByArticleId(query));
return "frontend/article";
}
@ApiOperation(value="文章評論查詢接口")
@PostMapping("/comments")
@ResponseBody
public DataGridResult comments(CommentQuery query) {
//設置默認10
query.setLimit(10);
return commentService.listCommentByArticleId(query);
}
@ApiOperation(value="文章點贊接口")
@ApiImplicitParam(name = "articleId", value = "文章ID", required = true, dataType = "Long")
@PostMapping("/approve")
@ResponseBody
public YYBlogResult approve(@RequestParam Long articleId) {
return articleService.updateApproveCntById(articleId);
}
}
最后同樣來個效果圖,和上面一樣。
PathSelectors.none()的時候
PathSelectors.any()的時候
看到效果圖是不是接口內容一目了然,很簡潔明了了。
最后,好像忘記說swagger文檔的路徑了
如果你的項目在根目錄:http://localhost:8080/swagger-ui.html
如果不是根目錄那就是:http://localhost:8080/你的項目名/swagger-ui.html
實例地址:http://www.laoyeye.net/management/index 賬號/密碼:test/123456 菜單:系統設置/接口文檔

