javascript
学习Spring Boot:(六) 集成Swagger2
前言
Swagger是用來(lái)描述和文檔化RESTful API的一個(gè)項(xiàng)目。Swagger Spec是一套規(guī)范,定義了該如何去描述一個(gè)RESTful API。類似的項(xiàng)目還有RAML、API Blueprint。 根據(jù)Swagger Spec來(lái)描述RESTful API的文件稱之為Swagger specification file,它使用JSON來(lái)表述,也支持作為JSON支持的YAML。
Swagger specification file可以用來(lái)給swagger-ui生成一個(gè)Web的可交互的文檔頁(yè)面,以可以用swagger2markup生成靜態(tài)文檔,也可用使用swagger-codegen生成客戶端代碼。總之有了有個(gè)描述API的JSON文檔之后,可以做各種擴(kuò)展。
Swagger specification file可以手動(dòng)編寫,swagger-editor為了手動(dòng)編寫的工具提供了預(yù)覽的功能。但是實(shí)際寫起來(lái)也是非常麻煩的,同時(shí)還得保持代碼和文檔的兩邊同步。于是針對(duì)各種語(yǔ)言的各種框架都有一些開(kāi)源的實(shí)現(xiàn)來(lái)輔助自動(dòng)生成這個(gè)`Swagger specification file。
swagger-core是一個(gè)Java的實(shí)現(xiàn),現(xiàn)在支持JAX-RS。swagger-annotation定義了一套注解給用戶用來(lái)描述API。
spring-fox也是一個(gè)Java的實(shí)現(xiàn),它支持Spring MVC, 它也支持swagger-annotation定義的部分注解。
使用
添加依賴
在pom文件添加:
<swagger.version>2.7.0</swagger.version><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>${swagger.version}</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${swagger.version}</version></dependency>配置docket
@Configuration @EnableSwagger2 public class SwaggerConfig {/*** SpringBoot默認(rèn)已經(jīng)將classpath:/META-INF/resources/和classpath:/META-INF/resources/webjars/映射* 所以該方法不需要重寫,如果在SpringMVC中,可能需要重寫定義(我沒(méi)有嘗試)* 重寫該方法需要 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/"); // }@Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.wuwii")).paths(PathSelectors.any()).build();}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("Spring Boot中使用Swagger2構(gòu)建RESTful APIs").description("rest api 文檔構(gòu)建利器").termsOfServiceUrl("https://blog.wuwii.com/").contact("KronChan").version("1.0").build();} }builder說(shuō)明
根據(jù)網(wǎng)上一位前輩的文章:
@Beanpublic Docket petApi() {return new Docket(DocumentationType.SWAGGER_2).select() //1.apis(RequestHandlerSelectors.any()).paths(PathSelectors.any()).build().pathMapping("/") //2.directModelSubstitute(LocalDate.class, //3String.class).genericModelSubstitutes(ResponseEntity.class) //4.alternateTypeRules( //5newRule(typeResolver.resolve(DeferredResult.class,typeResolver.resolve(ResponseEntity.class, WildcardType.class)),typeResolver.resolve(WildcardType.class))).useDefaultResponseMessages(false) //6.globalResponseMessage(RequestMethod.GET, //7newArrayList(new ResponseMessageBuilder().code(500).message("500 message").responseModel(new ModelRef("Error")).build())).securitySchemes(newArrayList(apiKey())) //8.securityContexts(newArrayList(securityContext())) //9;}方法說(shuō)明:
接口上添加文檔
@RestController @Api(description = "這是一個(gè)控制器的描述 ") public class PetController {/*** logger*/private static final Logger LOGGER = LoggerFactory.getLogger(PetController.class);private String no;private String kind;private String name;@ApiOperation(value="測(cè)試接口", notes="測(cè)試接口描述")@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "用戶ID", required = true, dataType = "Long", paramType = "path"),@ApiImplicitParam(name = "pet", value = "寵物", required = true, dataType = "PetController")})@ApiResponses({@ApiResponse(code = 200, message = "請(qǐng)求完成"),@ApiResponse(code = 400, message = "請(qǐng)求參數(shù)錯(cuò)誤")})@RequestMapping(path = "/index/{id}", method = RequestMethod.PUT)public PetController index1(@PathVariable("id") String id, @RequestBody PetController pet) {return pet;}//…… get / set常用的注解說(shuō)明
查看API文檔
啟動(dòng)Spring Boot程序,訪問(wèn):http://host:port/swagger-ui.html
。就能看到RESTful API的頁(yè)面。打開(kāi)我們的測(cè)試接口的API ,可以查看這個(gè)接口的描述,以及參數(shù)等信息:
點(diǎn)擊上圖中右側(cè)的Model Schema(黃色區(qū)域:它指明了這個(gè)requestBody的數(shù)據(jù)結(jié)構(gòu)),此時(shí)pet中就有了pet對(duì)象的模板,修改上測(cè)試數(shù)據(jù),點(diǎn)擊下方Try it out!按鈕,即可完成了一次請(qǐng)求調(diào)用!
調(diào)用完后,我們可以查看接口的返回信息:
參考文章
- Spring Boot中使用Swagger2構(gòu)建強(qiáng)大的RESTful API文檔檔
- spring-boot-swagger2 使用手冊(cè)
- 使用springfox生成springmvc項(xiàng)目的swagger的文檔
例外補(bǔ)充點(diǎn)
驗(yàn)證碼
我使用的是 com.github.axet.kaptcha 的驗(yàn)證碼
雖然按照別人的方法使用 HttpServletResponse 輸出流,這種是暴露 Servlet 的接口。但是發(fā)現(xiàn)了一個(gè)問(wèn)題了,在 swagger 的獲取驗(yàn)證碼接上測(cè)試的時(shí)候不能得到驗(yàn)證碼圖片,但是在 img 標(biāo)簽中是沒(méi)問(wèn)題,發(fā)現(xiàn) swagger 還是把我的返回結(jié)果作為 json 處理。所以我還是想到使用下載中二進(jìn)制流的方法,將 BufferedImage 轉(zhuǎn)換成二進(jìn)制流數(shù)組,總算是解決。
上最后解決的辦法:
/*** 獲取驗(yàn)證碼*/@GetMapping(value = "/captcha.jpg", produces = MediaType.IMAGE_JPEG_VALUE)public ResponseEntity<byte[]> captcha()throws IOException {//生成文字驗(yàn)證碼String text = producer.createText();//生成圖片驗(yàn)證碼BufferedImage image = producer.createImage(text);ByteArrayOutputStream out = new ByteArrayOutputStream();ImageIO.write(image, "jpg", out);// 文字驗(yàn)證碼保存到 shiro sessionShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);HttpHeaders headers = new HttpHeaders();headers.setCacheControl("no-store, no-cache");return ResponseEntity.status(HttpStatus.OK).headers(headers).body(out.toByteArray());我是采用 ImageIO 工具類的將 BufferedImage 轉(zhuǎn)換成 輸出流,從輸出流中獲取二進(jìn)制流數(shù)組。
ImageIO.write(BufferedImage image,String format,OutputStream out)再補(bǔ)充一個(gè) 將二進(jìn)制流數(shù)組 byte[] 轉(zhuǎn)換成 BufferedImage
// 將二進(jìn)制流數(shù)組轉(zhuǎn)換成輸入流 ByteArrayInputStream in = new ByteArrayInputStream(byte[] byets); // 讀取輸入流 BufferedImage image = ImageIO.read(InputStream in);在 swagger 上是這樣的了:
配置不同環(huán)境中是否啟動(dòng)
在不同環(huán)境種配置是否啟用規(guī)則:
swagger:enable: true # or false在 swagger 配置類中加入
/*** 啟用*/@Value("${swagger.enable}")private boolean enable;…… set / get配置 Docket 中
@Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())// 加入 enable.enable(enable).select().apis(RequestHandlerSelectors.basePackage("com.wuwii")).paths(PathSelectors.any()).build();}SpringMVC 中配置 Swagger2
Swagger 的配置文件:
@Configuration @EnableSwagger2 @EnableWebMvc @ComponentScan("com.devframe.controller") public class SwaggerConfig extends WebMvcConfigurerAdapter {/*** 靜態(tài)文件過(guò)濾* @param registry*/@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}@Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.devframe")).paths(PathSelectors.any()).build();}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("RESTful APIs").description("rest api 文檔構(gòu)建利器").termsOfServiceUrl("https://blog.wuwii.com/").version("1.0").build();}}額外需要在 web.xml 配置:
<!-- Springmvc前端控制器掃描路徑增加“/v2/api-docs”,用于掃描Swagger的 /v2/api-docs,否則 /v2/api-docs無(wú)法生效。--><servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/v2/api-docs</url-pattern></servlet-mapping>單元測(cè)試中會(huì)出現(xiàn)的錯(cuò)誤
發(fā)現(xiàn)加入 Swagger 后,以前的單元測(cè)試再運(yùn)行的時(shí)候,會(huì)拋出一個(gè)異常,參考 How to run integration tests with spring and springfox?
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'documentationPluginsBootstrapper' defined in URL [jar:file:/C:/Users/test/.m2/repository/io/springfox/springfox-spring-web/2.0.0-SNAPSHOT/springfox-spring-web-2.0.0- SNAPSHOT.jar!/springfox/documentation/spring/web/plugins/DocumentationPluginsBootstrapper.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [java.util.List]: : No qualifying bean of type [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}1解決,單元測(cè)試上加入 @EnableWebMvc
總結(jié)
以上是生活随笔為你收集整理的学习Spring Boot:(六) 集成Swagger2的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Golang基础知识入门详解
- 下一篇: 使用navicat for mysql