SpringBoot集成swagger2
一.Swagger概述
在当今前后端框架流行的时代,一个完整并且规范的接口文档是必不可少的。Swagger是一款Restful接口风格文档在线自动生成、接口功能测试的集成插件,用于生成、描述和可视化Restful风格的Web服务。软件可以实现接口文档同API始终保持同步。同过去的离线接口文档相比起来,整体提高了项目的开发效率,减少了前后端成员之间的非必要沟通。
官网地址:https://swagger.io/
二.集成步骤
2.1 引入依赖(maven为例)
<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>
2.2 添加配置
第一种方式:
@EnableSwagger2 添加此注解项目的启动类上。例如
@SpringBootApplication
@EnableSwagger2
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class, args);
System.out.println("Springboot集成Swagger2示例项目启动成功");
}
}
第二种方式(推荐):
自定义一个Swagger的配置类,@EnableSwagger2 添加此注解至配置类上。可以在自定义的配置类上设置Docket属性,例如设置项目名称,添加token验证。配置类案例如下:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
/**
* @author:zjpQ
* @date 2023/4/20 14:09
* @Description
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
.apis(RequestHandlerSelectors.basePackage("填入controller所在包位置"))
.paths(PathSelectors.any())
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("Springboot集成Swagger2示例项目")
.description("Springboot集成Swagger2示例项目接口api").termsOfServiceUrl("")
.version("1.0").build();
}
private List<ApiKey> securitySchemes() {
List<ApiKey> securitySchemes = new ArrayList<>();
securitySchemes.add(new ApiKey("Authorization", "Authorization", "header"));
return securitySchemes;
}
private List<SecurityContext> securityContexts() {
List<SecurityContext> securityContexts=new ArrayList<>();
securityContexts.add(
SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!auth).*$"))
.build());
return securityContexts;
}
List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences=new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
}
2.3 实体对象类添加注解
主要使用 @ApiModel注解和 @ApiModelProperty 注解。定义实体的名称和字段的名称,文档展示的时候与接口字段代表的含义一一对应。
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* @author:zjpQ
* @date 2023/4/20 15:31
* @Description
*/
@ApiModel("示例参数")
public class SwaggerExample {
@ApiModelProperty("id")
private Integer id;
@ApiModelProperty(value="昵称", required=false)
private String name;
}
2.4 Controller添加注解
@Api注解:标注接口组名
@ApiOperation注解:接口的名称
@ApiImplicitParam注解: 描述方法的参数
@ApiParam注解:用于方法,参数,字段说明
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/example")
@Api(value = "示例接口", tags = {"示例接口"})
public class ExampleController {
/**
* 获取验证码
*
* @param response 网络请求
* @return
*/
@GetMapping("/example")
@ApiOperation("示例说明")
@ApiImplicitParam(name = "id",value = "接口传参id",dataType = "int ")
public void example(int id) {
System.out.println("这是一个示例说明的接口")
}
}
2.5 启动项目
按照正常流程启动项目,浏览器输入ip:port/swagger-ui.html。跳转即可访问,成功!!!
提醒:若项目配置了server.servelet.context-path参数,例如配置此参数为api,那么访问地址需变更为ip:port/api/swagger-ui.html
三.问题解析
3.1 swagger访问401
项目中有鉴权验证,需要放开对Swagger的限制。以shiro举例,需要在配置类中添加如下代码
// 过滤器链定义映射
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//swagger接口权限 开放
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
filterChainDefinitionMap.put("/swagger/**", "anon");
filterChainDefinitionMap.put("/webjars/**", "anon");
filterChainDefinitionMap.put("/swagger-resources/**", "anon");
filterChainDefinitionMap.put("/v2/**", "anon");
filterChainDefinitionMap.put("/doc.html", "anon");
3.2 swagger访问404
添加如下配置类
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
*
* @param registry
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
//
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
// swagger 404问题
registry.addResourceHandler("/swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
/**
* 跨域问题解决
*
* @param registry
*/
@Override
protected void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods(ORIGINS)
.maxAge(3600);
}
/**
* 跨域配置
*
* @return
*/
private CorsConfiguration corsConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setMaxAge(3600L);
return corsConfiguration;
}
/**
* 跨域过滤器
*
* @return
*/
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig());
return new CorsFilter(source);
}
}