最近开发项目需要和前端人员提供接口文档,文档十分繁琐,索性使用了最近看的这个swagger2,感觉还是不错的,虽然有一定的侵入性,但无伤大雅,如果只是单纯的使用,看此篇和第三篇就可以了,第二篇是为了多模块使用。
swagger2有很多版本,本人踩坑了访问ui404 doc404、登录密码不可使用等诸多问题,最终使用的2.9.2这个版本,还是非常好的体验的
pom文件引入依赖:
<!-- swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- 引入swagger-bootstrap-ui包 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.3</version>
</dependency>
<!-- 1.5.21版本解决 实体类使用@ApiModelProperty时,example属性没有赋值导致 java.lang.NumberFormatException-->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
application.yml:
swagger:
production: false #是否屏蔽所有资源,生产环境可配置
basic:
enable: true #开启加密
username: admin #用户名
password: admin #密码
配置文件
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
public class Swagger2 {
// http://localhost:8088/swagger-ui.html 原路径(swagger自带的ui)
// http://localhost:8088/doc.html 原路径
// 配置swagger2核心配置 docket
@Bean
public Docket createRestApi(){
return new Docket(DocumentationType.SWAGGER_2)//制定api类型为swagger2类型
.apiInfo(apiInfo()) //定义api文档汇总信息
.select().apis(RequestHandlerSelectors.basePackage("com.mantis.micor.cpsidebar.controller"))//扫描哪个包下面 //RequestHandlerSelectors.withClassAnnotation(Api.class)存在注解的都都会拿取到
.paths(PathSelectors.any())//所有接口
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("企业侧边栏接口平台Api") //标题
.contact(new Contact("renyitian","https//www.mantis.com","mantis@qq.com"))//联系方式
.description("企业侧边栏接口文档")//描述
.version("0.0.1")//版本
.termsOfServiceUrl("https//www.mantis.com")//网址
.build();
}
}
扫描包的方法在这个类里面:RequestHandlerSelectors,可以根据业务或者需求自行编写扫描包的方法,也可以根据需求自己定义下一篇就是根据需求定制扫描哪些包
扫描多个包的方法有很多种,如果是单个模块,使用RequestHandlerSelectors.withClassAnnotation(Api.class)就能扫描多个包了,只要Controller类加上@Api注解即可
RequestHandlerSelectors:
public class RequestHandlerSelectors {
private RequestHandlerSelectors() {
throw new UnsupportedOperationException();
}
/**
* Any RequestHandler satisfies this condition
*
* @return predicate that is always true
*/
public static Predicate<RequestHandler> any() {
return Predicates.alwaysTrue();
}
/**
* No RequestHandler satisfies this condition
*
* @return predicate that is always false
*/
public static Predicate<RequestHandler> none() {
return Predicates.alwaysFalse();
}
/**
* Predicate that matches RequestHandler with handlers methods annotated with given annotation
*
* @param annotation - annotation to check
* @return this
*/
public static Predicate<RequestHandler> withMethodAnnotation(final Class<? extends Annotation> annotation) {
return new Predicate<RequestHandler>() {
@Override
public boolean apply(RequestHandler input) {
return input.isAnnotatedWith(annotation);
}
};
}
/**
* Predicate that matches RequestHandler with given annotation on the declaring class of the handler method
*
* @param annotation - annotation to check
* @return this
*/
public static Predicate<RequestHandler> withClassAnnotation(final Class<? extends Annotation> annotation) {
return new Predicate<RequestHandler>() {
@Override
public boolean apply(RequestHandler input) {
return declaringClass(input).transform(annotationPresent(annotation)).or(false);
}
};
}
private static Function<Class<?>, Boolean> annotationPresent(final Class<? extends Annotation> annotation) {
return new Function<Class<?>, Boolean>() {
@Override
public Boolean apply(Class<?> input) {
return input.isAnnotationPresent(annotation);
}
};
}
private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
return new Function<Class<?>, Boolean>() {
@Override
public Boolean apply(Class<?> input) {
return ClassUtils.getPackageName(input).startsWith(basePackage);
}
};
}
/**
* Predicate that matches RequestHandler with given base package name for the class of the handler method.
* This predicate includes all request handlers matching the provided basePackage
*
* @param basePackage - base package of the classes
* @return this
*/
public static Predicate<RequestHandler> basePackage(final String basePackage) {
return new Predicate<RequestHandler>() {
@Override
public boolean apply(RequestHandler input) {
return declaringClass(input).transform(handlerPackage(basePackage)).or(true);
}
};
}
private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
return Optional.fromNullable(input.declaringClass());
}
}