Swagger 是一個規範和完整的框架,用於生成、描述、調用和可視化 RESTful 風格的 Web 服務。整體目標是使客戶端和文件系統做爲服務器以一樣的速度來更新。文件的方法,參數和模型緊密集成到服務器端的代碼,容許API來始終保持同步。Swagger 讓部署管理和使用功能強大的API從未如此簡單。html
更多關於Swagger的做用,相信你們百度一下能瞭解的更全面,本文以SpringBoot中集成Swagger爲例作介紹說明。java
1、修改pom.xml,添加maven依賴web
<!-- Swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.6.1</version> </dependency>
2、添加Swagger配置類spring
package com.example.swaggerdemo; import static com.google.common.base.Predicates.or; import static springfox.documentation.builders.PathSelectors.regex; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.async.DeferredResult; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /** * SwaggerConfig */ @Configuration @EnableSwagger2 public class SwaggerConfig { /** * SpringBoot默認已經將classpath:/META-INF/resources/和classpath:/META-INF/resources/webjars/映射 * 因此該方法不須要重寫,若是在SpringMVC中,可能須要重寫定義(我沒有嘗試) * 重寫該方法須要 extends WebMvcConfigurerAdapter * */ // @Override // public void addResourceHandlers(ResourceHandlerRegistry registry) { // registry.addResourceHandler("swagger-ui.html") // .addResourceLocations("classpath:/META-INF/resources/"); // // registry.addResourceHandler("/webjars/**") // .addResourceLocations("classpath:/META-INF/resources/webjars/"); // } /** * 能夠定義多個組,好比本類中定義把test和demo區分開了 * (訪問頁面就能夠看到效果了) * */ @Bean public Docket testApi() { return new Docket(DocumentationType.SWAGGER_2) .groupName("test") .genericModelSubstitutes(DeferredResult.class) // .genericModelSubstitutes(ResponseEntity.class) .useDefaultResponseMessages(false) .forCodeGeneration(true) .pathMapping("/")// base,最終調用接口後會和paths拼接在一塊兒 .select() .paths(or(regex("/api/.*")))//過濾的接口 .build() .apiInfo(testApiInfo()); } @Bean public Docket demoApi() { return new Docket(DocumentationType.SWAGGER_2) .groupName("demo") .genericModelSubstitutes(DeferredResult.class) // .genericModelSubstitutes(ResponseEntity.class) .useDefaultResponseMessages(false) .forCodeGeneration(false) .pathMapping("/") .select() .paths(or(regex("/demo/.*")))//過濾的接口 .build() .apiInfo(demoApiInfo()); } private ApiInfo testApiInfo() { return new ApiInfoBuilder() .title("Electronic Health Record(EHR) Platform API")//大標題 .description("EHR Platform's REST API, all the applications could access the Object model data via JSON.")//詳細描述 .version("1.0")//版本 .termsOfServiceUrl("NO terms of service") .contact(new Contact("小單", "http://blog.csdn.net/catoop", "365384722@qq.com"))//做者 .license("The Apache License, Version 2.0") .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") .build(); } private ApiInfo demoApiInfo() { return new ApiInfoBuilder() .title("Electronic Health Record(EHR) Platform API")//大標題 .description("EHR Platform's REST API, all the applications could access the Object model data via JSON.")//詳細描述 .version("1.0")//版本 .termsOfServiceUrl("NO terms of service") .contact(new Contact("小單", "http://blog.csdn.net/catoop", "365384722@qq.com"))//做者 .license("The Apache License, Version 2.0") .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") .build(); return apiInfo; } }
通過這2步配置後,咱們啓動服務後,訪問:http://localhost:8080/swagger-ui.html 就完成了集成。apache
Swagger會默認把全部Controller中的RequestMapping方法都生成API出來,實際上咱們通常只須要標準接口的(像返回頁面的那種Controller方法咱們並不須要),全部你能夠按下面的方法來設定要生成API的方法的要求。
以下我針對RestController註解的類和ResponseBody註解的方法才生成Swaager的API,而且排除了特定的類,代碼以下:json
@Configuration @EnableSwagger2 // 啓用 Swagger public class SwaggerConfig { @Bean public Docket createRestApi() { Predicate<RequestHandler> predicate = new Predicate<RequestHandler>() { @Override public boolean apply(RequestHandler input) { Class<?> declaringClass = input.declaringClass(); if (declaringClass == BasicErrorController.class)// 排除 return false; if(declaringClass.isAnnotationPresent(RestController.class)) // 被註解的類 return true; if(input.isAnnotatedWith(ResponseBody.class)) // 被註解的方法 return true; return false; } }; return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .useDefaultResponseMessages(false) .select() .apis(predicate) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("包含媒體、諮詢、搜索引擎關鍵字、廣告等類型接口的服務")//大標題 .version("1.0")//版本 .build(); }
3、常見swagger註解一覽與使用api
最經常使用的5個註解ruby
@Api:修飾整個類,描述Controller的做用 @ApiOperation:描述一個類的一個方法,或者說一個接口 @ApiParam:單個參數描述 @ApiModel:用對象來接收參數 @ApiProperty:用對象接收參數時,描述對象的一個字段
其它若干服務器
@ApiResponse:HTTP響應其中1個描述 @ApiResponses:HTTP響應總體描述 @ApiIgnore:使用該註解忽略這個API @ApiClass @ApiError @ApiErrors @ApiParamImplicit @ApiParamsImplicit
下面建立2個Controller來測試:
一、TestController.javasession
@Controller @RequestMapping("/api/test") public class TestController { @ResponseBody @RequestMapping(value = "/show", method=RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)// 這裏指定RequestMethod,若是不指定Swagger會把全部RequestMethod都輸出,在實際應用中,具體指定請求類型也使接口更爲嚴謹。 @ApiOperation(value="測試接口", notes="測試接口詳細描述") public String show( @ApiParam(required=true, name="name", value="姓名") @RequestParam(name = "name", required=true) String stuName){ return "success"; } }
二、DemoController.java
/** * DemoController * */ @Controller @RequestMapping(value = "/demo") public class DemoController { private Logger logger = LoggerFactory.getLogger(DemoController.class); /** * 能夠直接使用@ResponseBody響應JSON * * @param request * @param response * @return */ @ResponseBody @RequestMapping(value = "/getcount", method = RequestMethod.POST) @ApiOperation(value="測試-getCount", notes="getCount更多說明") public ModelMap getCount(HttpServletRequest request, HttpServletResponse response) { logger.info(">>>>>>>> begin getCount >>>>>>>>"); ModelMap map = new ModelMap(); map.addAttribute("count", 158); // 後臺獲取的國際化信息 map.addAttribute("xstest", "測試"); return map; } /** * 能夠直接使用@ResponseBody響應JSON * * @param request * @param response * @return */ @ApiIgnore//使用該註解忽略這個API @ResponseBody @RequestMapping(value = "/jsonTest1", method = RequestMethod.POST) public ModelMap jsonTest(HttpServletRequest request, HttpServletResponse response) { ModelMap map = new ModelMap(); map.addAttribute("hello", "你好"); map.addAttribute("veryGood", "很好"); return map; } /** * 能夠直接使用@ResponseBody響應JSON * * @param request * @param response * @return */ @ResponseBody @RequestMapping(value = "/jsonTest3", method = RequestMethod.POST) public List<String> jsonTest3(HttpServletRequest request, HttpServletResponse response) { List<String> list = new ArrayList<String>(); list.add("hello"); list.add("你好"); return list; } /** * JSON請求一個對象<br/> * (Ajax Post Data:{"name":"名稱","content":"內容"}) * * @param version * @return */ @ResponseBody @RequestMapping(value = "/jsonTest2", method = RequestMethod.POST) public ModelMap jsonTest2(@RequestBody Demo demo) { logger.info("demoName:" + demo.getName()); logger.info("demoContent:" + demo.getContent()); ModelMap map = new ModelMap(); map.addAttribute("result", "ok"); return map; } /** * 直接讀取URL參數值<br/> * /demo/jsonTest6.do?name=Hello&content=World * * @param demoName * @param content * @return */ @ResponseBody @RequestMapping(value = "/jsonTest6", method = RequestMethod.POST) public ModelMap jsonTest6(@RequestParam("name") String demoName, @RequestParam String content) { logger.info("demoName:" + demoName); ModelMap map = new ModelMap(); map.addAttribute("name",demoName + "AAA"); map.addAttribute("content",content + "BBB"); map.addAttribute("date",new java.util.Date()); return map; } /** * JSON請求一個對象,將RequestBody自動轉換爲JSONObject對象<br/> * (Ajax Post Data:{"name":"名稱","content":"內容"}) * * 使用JSONObject請添加依賴 * <dependency> * <groupId>net.sf.json-lib</groupId> * <artifactId>json-lib</artifactId> * <version>2.4</version> * <!--指定jdk版本 --> * <classifier>jdk15</classifier> * </dependency> * * @param version * @return */ @ResponseBody @RequestMapping(value = "/jsonTest5", method = RequestMethod.POST) public ModelMap jsonTest5(@RequestBody JSONObject jsonObject) { String name = jsonObject.getString("name"); logger.info("demoName:" + name); ModelMap map = new ModelMap(); map.addAttribute("demoName",name); return map; } /** * 輸入 和輸出爲JSON格式的數據的方式 HttpEntity<?> ResponseEntity<?> * * @param u * @return */ @ResponseBody @RequestMapping(value = "/jsonTest4", method = RequestMethod.POST) public ResponseEntity<String> jsonTest4(HttpEntity<Demo> demo, HttpServletRequest request, HttpSession session) { //獲取Headers方法 HttpHeaders headers = demo.getHeaders(); // 獲取內容 String demoContent = demo.getBody().getContent(); // 這裏直接new一個對象(HttpHeaders headers = new HttpHeaders();) HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.add("MyHeaderName", "SHANHY"); ResponseEntity<String> responseResult = new ResponseEntity<String>( demoContent, responseHeaders, HttpStatus.OK); return responseResult; } }
Swagger2默認將全部的Controller中的RequestMapping方法都會暴露,然而在實際開發中,咱們並不必定須要把全部API都提如今文檔中查看,這種狀況下,使用註解@ApiIgnore來解決,若是應用在Controller範圍上,則當前Controller中的全部方法都會被忽略,若是應用在方法上,則對應用的方法忽略暴露API。
註解@ApiOperation和@ApiParam能夠理解爲API說明,多動手嘗試就很容易理解了。
若是咱們不使用這樣註解進行說明,Swagger2也是有默認值的,沒什麼可說的試試就知道了。
在 http://localhost:8080/swagger-ui.html 顯示頁面的右上角有api_key ,springfox-swagger 2.2.2 版本並無進行處理,咱們能夠本身添加攔截器攔截 /v2/api-docs 來處理咱們API文檔的訪問權限,若是要更嚴格更靈活的控制,可能須要修改源碼來實現了。相信 springfox-swagger 的後期版本應該會支持更全面的應用需求的。
引自 http://blog.csdn.net/catoop/article/details/50668896