1.引入swagger的pom
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
2.配置资源拦截器放行swagger资源链接
@Configuration public class MvcConfigurer implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ List<String> profileList = SpringContextUtil.getActiveProfile(); //****** 访问控制,需和“SwaggerConfig”上“@Profile”保持一致 if (profileList.contains("test") || profileList.contains("dev") || profileList.contains("local") || profileList.contains("default")) { registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars") .addResourceLocations("classpath:/META-INF/resources/webjars/"); } } }/** * Spring Context 工具类 * * @author MrBird * */ @Component public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtil.applicationContext = applicationContext; } public static Object getBean(String name) { return applicationContext.getBean(name); } public static <T> T getBean(Class<T> clazz){ return applicationContext.getBean(clazz); } public static <T> T getBean(String name, Class<T> requiredType) { return applicationContext.getBean(name, requiredType); } public static boolean containsBean(String name) { return applicationContext.containsBean(name); } public static boolean isSingleton(String name) { return applicationContext.isSingleton(name); } public static Class<?> getType(String name) { return applicationContext.getType(name); } // 国际化使用 public static String getMessage(String key) { return applicationContext.getMessage(key, null, Locale.getDefault()); } /// 获取当前环境 public static List<String> getActiveProfile() { return Arrays.asList(applicationContext.getEnvironment().getActiveProfiles()); } }
3.springboot配置声明当前开发环境(不同环境项目配置不同,maven打包时指定环境,程序读取指定环境配置)
spring.profiles.active:dev
4.由于我这里接口主要服务于移动端,所以每个请求都需要在head中指定参数,以及相关说明配置。
import cc.mrbird.febs.common.controller.SwaggerController; import cc.mrbird.febs.common.domain.AppInfo; import com.google.common.base.Predicate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import springfox.documentation.RequestHandler; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ParameterBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.schema.ModelRef; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; 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; //****** 访问控制,需和“WebMvcConfig.addResourceHandlers”保持一致 @Profile({"test", "dev", "local", "default"}) @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket swaggerSpringMvcPlugin() { ParameterBuilder ticketPar = new ParameterBuilder(); List<Parameter> pars = new ArrayList<Parameter>(); Parameter code = ticketPar.name(AppInfo.CODE).description("应用代号").defaultValue("OYGH01").modelRef(new ModelRef("string")).parameterType("header") .required(true).build(); Parameter version = ticketPar.name(AppInfo.VERSION).description("应用版本").defaultValue("8.0.9").modelRef(new ModelRef("string")).parameterType("header") .required(true).build(); Parameter timestamp = ticketPar.name(AppInfo.TIMESTAMP).description("请求时间戳").defaultValue("1234567890").modelRef(new ModelRef("string")).parameterType("header") .required(true).build(); Parameter channel = ticketPar.name(AppInfo.CHANNEL).description("对接渠道").defaultValue("ios").modelRef(new ModelRef("string")).parameterType("header") .required(true).build(); Parameter deviceModel = ticketPar.name(AppInfo.DEVICE_MODEL).description("设备型号").defaultValue("iPhone 6@10.3").modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); Parameter rpnStrategy = ticketPar.name(AppInfo.RPN_STRATEGY).description("返回属性命名策略(空和underline)").defaultValue("").modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); Parameter rpnKeepnull = ticketPar.name(AppInfo.RPN_KEEPNULL).description("是否返回null值属性(1或true)").defaultValue("").modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); Parameter signType = ticketPar.name(AppInfo.SIGN_TYPE).description("加签类型").defaultValue("").modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); Parameter sign = ticketPar.name(AppInfo.SIGN).description("签名").defaultValue("").modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); Parameter token = ticketPar.name(AppInfo.TOKEN).description("用户令牌").defaultValue("").modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); Parameter authentication = ticketPar.name(AppInfo.AUTHENTICATION).description("用户令牌").defaultValue("").modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); pars.add(code); pars.add(version); pars.add(timestamp); pars.add(channel); pars.add(deviceModel); pars.add(rpnStrategy); pars.add(rpnKeepnull); pars.add(signType); pars.add(sign); pars.add(token); pars.add(authentication); Predicate<RequestHandler> apisPredicate = new Predicate<RequestHandler>() { @Override public boolean apply(RequestHandler requestHandler) { Class<?> superClass = requestHandler.declaringClass().getSuperclass(); if (superClass != null && SwaggerController.class.equals(superClass)) {//必须是继承了SwaggerController才会显示 return true; } return false; } }; return new Docket(DocumentationType.SWAGGER_2) .select() .apis(apisPredicate) .paths(PathSelectors.any()) .build() .globalOperationParameters(pars) .apiInfo(apiInfo()); } protected ApiInfo apiInfo() { return new ApiInfoBuilder() .title("欧冶小程序后端管理API接口文档") .description("接口中心答题模块 - 小程序前端人员调用server端接口的测试文档与平台") .license("") .licenseUrl("") .termsOfServiceUrl("") .version("1.0") .contact(new Contact("", "", "")) .build(); } }
5.在上面4的swagger的配置类中,可以看到只有当继承了指定SwaggerControoler才能才会生效(这样避免了不需要的在swagger中显示的接口也暴露出来)
/** * 需要在swagger显示api需要继承此controoler */ public class SwaggerController { }
6.如果权限配置使用shiro则还需要给swagger资源放行,不然会被拦截
/项目名/swagger-ui.html,/项目名/swagger-resources/**,/项目名/v2/**,/项目名/webjars/**
7.访问:http://ip:port/项目名称/swagger.html
8.swagger相关注解
在方法的返回值上增加指定返回泛型,即可在swagger上查看返回值。且该泛型必须增加swagger注解