swagger ialah alat penjanaan dokumen antara muka masa nyata yang popular. Dokumen antara muka adalah alat yang sangat diperlukan dalam projek pemisahan bahagian hadapan dan bahagian belakang Sebelum pembangunan bahagian hadapan dan bahagian hadapan, bahagian belakang mesti menghasilkan dokumen antara muka terlebih dahulu dokumen. Selepas pembangunan kedua-dua pihak selesai, penyahpepijatan dan ujian bersama akan dijalankan.
Jadi dokumen antara muka sebenarnya adalah perjanjian antara kedua-dua pihak sebelum pembangunan. Biasanya dokumen antara muka dibahagikan kepada luar talian dan masa nyata. Alat dokumen antara muka luar talian termasuk: perkataan (bersamaan dengan Wu berkata), YAPI, Xiaoyaoji, dsb. Dokumen jenis ini perlu ditulis oleh pengaturcara, dan secara amnya mempunyai fungsi ujian antara muka. Biasanya, pembangun mula-mula menulis maklumat pada dokumen antara muka luar talian, dan kemudian menyerahkannya kepada kakitangan bahagian hadapan untuk pembangunan rujukan. Kelemahan terbesar ialah apabila program antara muka kami berubah, kami perlu kembali dan mengekalkan kandungan di atas, yang sangat menyusahkan, sangat menyusahkan.
Dokumen antara muka masa nyata secara automatik boleh menjana dokumen antara muka yang sepadan berdasarkan kod kami. Kelebihannya ialah apabila kod kami berubah, dokumen antara muka yang dihasilkan akan dikemas kini secara automatik pengubahsuaian, dan ia perlu dikeluarkan tepat pada masanya. Walau bagaimanapun, oleh kerana ia dijana secara automatik berdasarkan kod, kelemahan terbesar ialah kod itu sangat mengganggu dan memerlukan kami untuk menyepadukan kod yang berkaitan untuk menjana dokumen antara muka dalam kod projek. Terdapat banyak penyelesaian untuk dokumentasi antara muka masa nyata, tetapi kesombongan masih merupakan salah satu penyelesaian yang lebih berpengaruh.
Alamat tapak web rasmi: swagger.io Sudah tentu, laman web rasmi semuanya dalam bahasa Inggeris, yang nampaknya agak menyusahkan. Saya cadangkan anda ikut sahaja langkah saya, ia sangat mudah.
Pada masa yang sama, izinkan saya mengatakan sesuatu: swagger terbahagi kepada dua versi yang biasa digunakan: swagger2 dan swagger3. Perbezaan antara kedua-duanya tidak begitu besar Ia terutamanya mengoptimumkan kebergantungan dan anotasi. Swagger2 perlu memperkenalkan dua pakej balang, dan swagger3 hanya memerlukan satu. Berikut mengambil swagger2 sebagai contoh.
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>
Mula-mula anda perlu menambah anotasi: @EnableSwagger2. Kita boleh menambah anotasi ini pada kelas permulaan SpringBoot, atau kita boleh menyesuaikan kelas konfigurasi dan meletakkannya di atasnya. Selepas menambah anotasi ini, ini bermakna kami telah mendayakan fungsi Swagger dalam projek.
Kami menggunakan kaedah kedua untuk menentukan sendiri kelas konfigurasi dan kami juga boleh menambah konfigurasi Doket. Konfigurasi Docket yang dipanggil ialah konfigurasi set dokumen antara muka (projek atau versi), seperti menetapkan nama, kenalan, dsb.
Kami menambah kelas SwaggerConfig di bawah folder konfigurasi.
@Configuration @EnableSwagger2 public class SwaggerConfig { /** * 设置多个: * * @Bean * public Docket appApi() { * * List<Parameter> pars = new ArrayList<>(); * ParameterBuilder token = new ParameterBuilder(); * token.name("token").description("用户令牌").modelRef(new ModelRef("string")).parameterType("header").required(false) * .build(); * pars.add(token.build()); * * return new Docket(DocumentationType.SWAGGER_2).select().paths(regex("/app/.*")).build() * .globalOperationParameters(pars).apiInfo(pdaApiInfo()).useDefaultResponseMessages(false) * .enable(enableSwagger) * .groupName("appApi"); * * } * * @Bean * public Docket adminApi() { * * List<Parameter> pars = new ArrayList<>(); * ParameterBuilder token = new ParameterBuilder(); * token.name("token").description("用户令牌").modelRef(new ModelRef("string")).parameterType("header").required(false) * .build(); * pars.add(token.build()); * return new Docket(DocumentationType.SWAGGER_2).select().paths(regex("/admin/.*")).build() * .globalOperationParameters(pars).apiInfo(pdaApiInfo()).useDefaultResponseMessages(false) * .enable(enableSwagger) * .groupName("adminApi"); * * } * * * @return */ @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() .apis(RequestHandlerSelectors.basePackage("com.lsqingfeng.action.swagger.controller")).paths(PathSelectors.any()) .build().globalOperationParameters(setHeaderToken()); } private ApiInfo apiInfo() { return new ApiInfoBuilder().title("action-swagger").description("swagger实战").termsOfServiceUrl("") .version("1.0").build(); } /** * @Description: 设置swagger文档中全局参数 * @param * @Date: 2020/9/11 10:15 * @return: java.util.List<springfox.documentation.service.Parameter> */ private List<Parameter> setHeaderToken() { List<Parameter> pars = new ArrayList<>(); ParameterBuilder userId = new ParameterBuilder(); userId.name("token").description("用户TOKEN").modelRef(new ModelRef("string")).parameterType("header") .required(true).build(); pars.add(userId.build()); return pars; } }
Di atas ialah contoh konfigurasi dan kaedah setToken juga ditetapkan, yang bermaksud bahawa semua antara muka yang menjana dokumen mesti mengandungi parameter token jenis pengepala.
Penerangan langsung dokumen antara muka kami terutamanya pada peringkat Pengawal, seperti fungsi antara muka ini, nama parameter, nama nilai pulangan, dsb. Untuk nilai ini, kami perlu menambah anotasi yang sepadan dengan kaedah, meminta parameter dan mengembalikan parameter pada Pengawal, supaya kesombongan boleh membantu kami menjana dokumen antara muka yang sepadan. Ini adalah pencerobohan ke dalam kod sedia ada yang saya nyatakan sebelum ini.
Mari kita tulis kes.
Mula-mula buat pakej vo, tulis permintaan kami dan parameter yang sepadan di dalamnya, dan gunakan JavaBean untuk mentakrifkan struktur data permintaan dan respons. Ambil perhatian bahawa anotasi yang sepadan perlu ditambahkan di sini:
Kelas permintaan:
package com.lsqingfeng.springboot.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @className: SwaggerReqVO * @description: * @author: sh.Liu * @date: 2022-03-22 19:19 */ @Data @ApiModel("创建Swagger请求参数") public class SwaggerReqVO { @ApiModelProperty("id") private Integer id; @ApiModelProperty("姓名") private String name; @ApiModelProperty("性别") private Integer gender; }
Kelas respons:
package com.lsqingfeng.springboot.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @className: SwaggerResVO * @description: * @author: sh.Liu * @date: 2022-03-22 19:20 */ @Data @ApiModel("创建Swagger响应结果") public class SwaggerResVO { @ApiModelProperty("id") private Integer id; @ApiModelProperty("姓名") private String name; @ApiModelProperty("性别") private Integer gender; @ApiModelProperty("啥啥") private String what; }
Anotasi @ApiModel dan @@ApiModelProperty anotasi digunakan di sini untuk tentukan entiti Nama dan nama medan adalah mudah untuk dipaparkan semasa menjana dokumen antara muka.
Lihat Pengawal sekali lagi:
package com.lsqingfeng.springboot.controller; import com.lsqingfeng.springboot.vo.SwaggerReqVO; import com.lsqingfeng.springboot.vo.SwaggerResVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; /** * @className: SwaggerController * @description: swagger 接口测试 * @author: sh.Liu * @date: 2022-03-22 19:18 */ @RestController @RequestMapping("/swagger") @Api(value = "用户接口", tags = {"用户接口"}) public class SwaggerController { @ApiOperation("新增用户") @PostMapping("save") public String save(@RequestBody SwaggerReqVO req) { return "success"; } @GetMapping("getById") @ApiOperation("根据条件查询用户") public SwaggerResVO getById(@RequestBody SwaggerResVO req) { return new SwaggerResVO(); } }
Anotasi @Api dan @ApiOperation digunakan untuk menandakan nama kumpulan antara muka dan nama antara muka masing-masing. Sekarang kita mulakan projek.
Saya mendapati ralat ini dilaporkan.
Mencari sebab dalam talian, dikatakan bahawa versi SpringBoot2.6 tidak serasi dengan Swagger2.9.2. Ada juga yang mengatakan ia berpunca daripada versi pakej jambu batu yang terlalu rendah.
Saya mencuba kesemuanya secara berasingan, dan masalah menggantikan kebergantungan versi yang lebih tinggi bagi jambu batu masih wujud.
Sebab utama masalah ini sememangnya versi SpringBoot terlalu tinggi. Jika anda menggunakan SpringBoot2.5.x dan versi terdahulu, tiada masalah.
Spring Boot 2.6.X menggunakan PathPatternMatcher untuk memadankan laluan. Padanan laluan yang digunakan oleh Springfox yang dirujuk oleh Swagger adalah berdasarkan AntPathMatcher.
Jadi untuk menyelesaikannya, tambah konfigurasi dan ubah suai mod pemadanan kekuatan jalan springBoot MVC.
Tambah konfigurasi dalam fail konfigurasi springBoot:
spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER
Jika ia adalah fail konfigurasi dalam format yml:
Mulakan semula untuk menyelesaikan masalah.
Alamat akses: ip:port number/swagger-ui.html
正常情况就可以看到我们的界面了。一会再说非正常情况。由于我们只给用户接口添加了注解,所有用户接口是可以直接观察中文文档的。而剩下的两个接口,由于没添加注解,所以都是以默认的形式展示的。
点开接口,我们可以看到接口中的想详细信息
点击model,可以看到字段的中文描述。点击 Try it out,就可以直接调试接口。同时注意接口中都让填一个token,这就是我们之前的设置成效了。
截止到目前其实swagger的集成就已经完毕了,主要就是根据我们的注解生成文档,并且可以在线调用调试。开发的时候,我们只需要把Controller这一层的请求和响应,以及方法描述等内容先开发完毕,就可以提供给前端让他们参照开发了。
正常情况我们按照上面的步骤就可以出现页面,但是有些时候可能是由于springBoot的版本过高导致的,我们输入之前的地址,出现404的情况,这个主要是由于项目中无法读取到swagger依赖包下的页面导致的。如果出现了这个问题,我们可以添加一个配置类,让他实现WebMvcConfigurer 接口,在添加一个方法:
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); }
完整代码如下:
package com.lsqingfeng.springboot.config; import com.lsqingfeng.springboot.interceptor.TokenInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @className: WebMvcConfig * @description:webMvc配置 * @author: sh.Liu * @date: 2022-01-13 09:51 */ @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); } }
这个时候在启动就可以了!
上面的整个过程已经完成了,但是生成的接口文档的页面,其实很多人不太喜欢,觉得不太符合国人的使用习惯,所有又有一些大神,提供了其他的UI测试页面。这个页面的使用还是比较广泛的。
修改方式:只需引入一个依赖包:
<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>swagger-bootstrap-ui</artifactId> <version>1.9.6</version> </dependency>
然后把刚才实现的那个的那个方法再添加一条:
registry.addResourceHandler("doc.html") .addResourceLocations("classpath:/META-INF/resources/");
完成代码:
package com.lsqingfeng.springboot.config; import com.lsqingfeng.springboot.interceptor.TokenInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @className: WebMvcConfig * @description:webMvc配置 * @author: sh.Liu * @date: 2022-01-13 09:51 */ @Configuration public class WebMvcConfig implements WebMvcConfigurer { // @Override // public void addInterceptors(InterceptorRegistry registry) { // //拦截 // registry.addInterceptor(new TokenInterceptor()) // .addPathPatterns("/**") // .excludePathPatterns("/login"); // } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); registry.addResourceHandler("doc.html") .addResourceLocations("classpath:/META-INF/resources/"); } }
重新启动项目: 访问路径发生了变化:** ip:端口号/doc.html**
页面出现了。我们在看看我们的用户接口:
这个风格确实更加的直观,同时也是可以直接进行调试的。大部分的swagger都用的这个风格的文档。
上面已经很详细的讲解了swagger2的集成方式,而swagger3的集成方式更加的简洁一些。
首先引入依赖:
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version> </dependency>
然后是替换注解: swagger2使用的开启注解是: @EnableSwagger2
而在swagger3中,这个注解要换成: @EnableOpenApi
配置类:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.oas.annotations.EnableOpenApi; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; @Configuration public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.OAS_30) // v2 不同 .select() .apis(RequestHandlerSelectors.basePackage("com.example.swaggerv3.controller")) // 设置扫描路径 .build(); } }
要注意,里边的版本类型换成了 OAS_30, 就是swagger3的意思。
OAS 是 OpenAPI Specification 的简称,翻译成中文就是 OpenAPI 说明书。
同时访问地址:原始地址,也就是没换UI的地址: localhost:8080/swagger-ui/index.html这个要和swagger2区分开。
swagger3的原始UI风格也发生了一些变化:
同时swagger3也是可以更换UI的。方法和swagger2一样。
如果我们的项目中有关于跨域的处理,同时还有拦截器,然后还要使用swagger,这种情况大家要注意了,有可能我们的拦截器会将swagger中的页面路径拦截掉导致swagger页面出不来,当我们在拦截器中把swagger的页面排除掉的时候,也有可能会导致跨域配置的失效。
具体解决方案简单提一下:
拦截器:
/** * 拦截器配置 * * @author liuShuai */ @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Bean public TokenInterceptor tokenInterceptor() { return new TokenInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { registry .addInterceptor(tokenInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/user/login") .excludePathPatterns("/user/downloadExcel") .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"); } @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/"); } }
跨域配置:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; /** * @className: CorsConfig * @description: * @author: sh.Liu * @date: 2020-12-02 10:16 */ @Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("*"); config.setAllowCredentials(true); config.addAllowedMethod("*"); config.addAllowedHeader("*"); UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); configSource.registerCorsConfiguration("/**", config); return new CorsFilter(configSource); } }
用这两种方式去配置,就可以让他们和平共处了。
另: 配套项目代码已托管中gitCode: gitcode.net/lsqingfeng/…
分支: feautre/MybatisPlus
Atas ialah kandungan terperinci Analisis contoh kesombongan bersepadu SpringBoot. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!