Spring Boot 集成Swagger
來自: http://blog.csdn.net/catoop/article/details/50668896
Swagger 是一個規范和完整的框架,用于生成、描述、調用和可視化 RESTful 風格的 Web 服務。總體目標是使客戶端和文件系統作為服務器以同樣的速度來更新。文件的方法,參數和模型緊密集成到服務器端的代碼,允許API來始終保持同步。Swagger 讓部署管理和使用功能強大的API從未如此簡單。
更多關于Swagger的作用,相信大家百度一下能了解的更全面,本文以SpringBoot中集成Swagger為例做介紹說明。
一、修改pom.xml,添加maven依賴
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency> 二、添加Swagger配置類
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() {
ApiInfo apiInfo = new ApiInfo("Electronic Health Record(EHR) Platform API",//大標題
"EHR Platform's REST API, all the applications could access the Object model data via JSON.",//小標題
"0.1",//版本
"NO terms of service",
"365384722@qq.com",//作者
"The Apache License, Version 2.0",//鏈接顯示文字
"http://www.apache.org/licenses/LICENSE-2.0.html"http://網站鏈接
);
return apiInfo;
}
private ApiInfo demoApiInfo() {
ApiInfo apiInfo = new ApiInfo("Electronic Health Record(EHR) Platform API",//大標題
"EHR Platform's REST API, for system administrator",//小標題
"1.0",//版本
"NO terms of service",
"365384722@qq.com",//作者
"The Apache License, Version 2.0",//鏈接顯示文字
"http://www.apache.org/licenses/LICENSE-2.0.html"http://網站鏈接
);
return apiInfo;
}
} 經過這2步配置后,我們啟動服務后,訪問: http://localhost:8080/swagger-ui.html 就完成了集成。
下面創建2個Controller來測試:1、TestController.java
@Controller
@RequestMapping("/api/test")
public class TestController {
@ResponseBody
@RequestMapping(value = "/show", method=RequestMethod.POST)// 這里指定RequestMethod,如果不指定Swagger會把所有RequestMethod都輸出,在實際應用中,具體指定請求類型也使接口更為嚴謹。
@ApiOperation(value="測試接口", notes="測試接口詳細描述")
public String show(
@ApiParam(required=true, name="name", value="姓名")
@RequestParam(name = "name") String stuName){
return "success";
}
} 2、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 的后期版本應該會支持更全面的應用需求的。