Bootstrap

Spring Boot(十)swagger-生产环境展示部分接口,测试环境展示所有

前段时间讲述了如何配置swagger以及如何禁用swagger。主要还是为了安全起见。但是总会出现事与愿违或者某种突发状况。
所以就会出现一种新的场景,测试环境需要展示全部接口,线上由于某种原因需要展示一小部分,这种情况该如何配置展示呢???
主要的思路则是:swagge2多包扫描实现。

API接口类是可以放在不同的包名下的,我们可以将线上展示的部分接口独立到一个包下边,通过读取环境来判定展示几个包名。

具体实现方式:

	/**
	 * swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等
	 * @author huohuo
	 */
	@Bean()
	public Docket createRestApi() {

		// 增加全局参数设置
		ParameterBuilder parameterBuilder = new ParameterBuilder();
		List<Parameter> parameters = new ArrayList<>();
		parameterBuilder.name("Authorization")
				.description("token")
				.modelRef(new ModelRef("string"))
				.parameterType(SwaggerParamType.HEADER)
				.defaultValue("1")
				.required(true);
		parameters.add(parameterBuilder.build());

		parameterBuilder.name("x-matrix-from")
				.description("x-matrix-from")
				.modelRef(new ModelRef("string"))
				.parameterType(SwaggerParamType.HEADER)
				.defaultValue("OUTER")
				.required(false);
		parameters.add(parameterBuilder.build());

		//profiles可以读取环境是什么,是test还是prod。
		//PROFILES_VALUE值我定义了一个静态变量,默认为test.
		//由于我只是配置了两个包,所以test通过SEPARATE_MARK=“;”连接符来连接两个包名,当非test环境,也就是prod环境,只展示我们需要的包名即可。
		//需要对basePackage进行改造,代码如下,原理见下篇博客。
		String[] profiles = applicationContext.getEnvironment().getActiveProfiles();
		String basePackage;
		if (profiles[0].equals(PROFILES_VALUE)) {
			basePackage = "cn.hysn.api.controller" + SEPARATE_MARK + "cn.hysn.api.home.controller";
		} else {
			basePackage = "cn.hysn.api.home.controller";
		}

		return new Docket(DocumentationType.SWAGGER_2)
				.apiInfo(apiInfo())
				.groupName("app接口")
				.genericModelSubstitutes(Result.class)
				.globalOperationParameters(parameters)
				.useDefaultResponseMessages(false)
				.pathMapping("/")
				.select()
				// 为当前包路径
				.apis(basePackage(basePackage))
				.paths(PathSelectors.any())
				.build();
	}
	/**
	 * @param basePackage 所有包路径
	 * @return Predicate<RequestHandler>
	 * @author huohuo
	 * @description 重写basePackage方法,使能够实现多包访问
	 */
	public static Predicate<RequestHandler> basePackage(final String basePackage) {
		return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);
	}

	/**
	 * @param basePackage 所有包路径
	 * @return Function<Class < ?>, Boolean>
	 * @author huohuo
	 * @description 重写basePackage方法,使能够实现多包访问
	 */
	private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
		return input -> {
			// 循环判断匹配
			for (String strPackage : basePackage.split(SEPARATE_MARK)) {
				assert input != null;
				boolean isMatch = input.getPackage().getName().startsWith(strPackage);
				if (isMatch) {
					return true;
				}
			}
			return false;
		};
	}

	/**
	 * @param input
	 * @return Optional<? extends Class < ?>>
	 * @author huohuo
	 * @description 重写basePackage方法,使能够实现多包访问
	 */
	private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
		return Optional.fromNullable(input.declaringClass());
	}
;