Swagger-UI의 캡슐화와 문서 JSON 데이터의 구문 분석 및 처리를 기억하십시오.

Swagger-UI의 캡슐화와 문서 JSON 데이터의 구문 분석 및 처리를 기억하십시오.

유래

Spring 프로젝트는 종종 다른 사람들이 사용할 수있는 문서, 특히 개발 된 인터페이스를 구성해야합니다. Java에는 javadoc, genDoc, SwaggerUI 등과 같은 많은 종류의 클래스 문서가 있습니다. 요구 사항에 따라 먼저 서로 다른 컨트롤러 패키지를 그룹화해야합니다. 각 컨트롤러 패키지는 인터페이스 유형을 나타냅니다. 둘째, 원래 SwagerUI 디스플레이 인터페이스가 우리가 원하는 것이 아닐 수 있으므로 변환해야합니다.

내 코드에 사용 된 SwaggerUI의 버전은 2.7.0이고 SwaggerUI의 각 버전 간의 차이는 상대적으로 큽니다.

코드 컨트롤러 패키지에 따라 인터페이스 그룹화

패키지에 따라 DocketBean을 동적으로 생성 할 수 있도록 SwaggerUI를 전역 적으로 구성해야합니다.
우선, 자동화 된 구성을위한 문서 설명을 설명하는 데 사용되는 클래스를 정의해야합니다.

private class SwaggerConfigProperties {
    
    
        private String version;
        private Boolean enable;
        private String groupName;
        private String title;
        private String description;
        private String basePackage;

        public SwaggerConfigProperties(Environment env, String groupName) {
    
    
            this.groupName = env.getProperty("swagger2." + groupName + ".groupName", "groupName");
            this.title = env.getProperty("swagger2." + groupName + ".title", "title");
            this.description = env.getProperty("swagger2." + groupName + ".description", "description");
            this.version = env.getProperty("swagger2." + groupName + ".version", "version");
            this.basePackage = env.getProperty("swagger2." + groupName + ".basePackage", "basePackage");
            this.enable = Boolean.parseBoolean(env.getProperty("swagger2.enable", "false"));
        }
       
        ///getter
        ///setter
    }

이 클래스는 구성 파일에 해당합니다.

#启用/禁用swagger
swagger2.enable=true
# rest API 标题
#服务器启动后可以通过访问http://your ip:8090/api/swagger-ui.html查看发布的REST接口
swagger2.title=BFSAPP相关Restfull API接口

# group1
swagger2.group1.groupName=文档分组1
swagger2.group1.title=文档分组1文档
swagger2.group1.description=文档分组1
swagger2.group1.version=1.0
swagger2.group1.basePackage=com.xxx.group1 # 这里是第一个controller组对应的包名
# group2
swagger2.group2.groupName=文档分组2
swagger2.group2.title=文档分组1文档
swagger2.group2.description=文档分组2
swagger2.group2.version=1.0
swagger2.group2.basePackage=com.xxx.group2 # 这里是第二个controller组对应的包名
# groups
swagger2.groups=group1,group2

그런 다음 전역 구성 파일을 사용하여 다음과 같이 동적 빈 주입을 구현합니다.

@Configuration
@PropertySources({
    
    @PropertySource(value = "classpath:swagger2.properties", ignoreResourceNotFound = true, encoding = "UTF-8")})
@EnableSwagger2
@RestController
public class Swagger2UIConfig implements ApplicationContextAware {
    
    
    private ConfigurableApplicationContext configurableApplicationContext;

    @Autowired
    private Environment env;

    @Value("#{'${swagger2.groups}'.split(',')}")
    private List<String> groups;

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    
    
        this.configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
    }
	
	/**
     * 按照group的个数,自动生成一系列的Docket bean对象。
     *
     * @return
     */
    @Bean
    public String createDocket() {
    
    
        groups.forEach(group -> {
    
    
            SwaggerConfigProperties properties = new SwaggerConfigProperties(env, group);

            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Docket.class);
            beanDefinitionBuilder.addConstructorArgValue(DocumentationType.SWAGGER_2);

            BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
            BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) configurableApplicationContext.getBeanFactory();
            beanFactory.registerBeanDefinition(group, beanDefinition);

            Docket docket = configurableApplicationContext.getBean(group, Docket.class);
            docket.groupName(properties.getGroupName())
                    .enable(properties.getEnable())
                    .apiInfo(apiInfo(properties.getTitle(), properties.getTitle(), properties.getVersion()))
                    .select()
                    .apis(basePackage(properties.getBasePackage()))
                    .paths(PathSelectors.any())
                    .build();
        });
        return "createDocket";
    }

    
    public static Predicate<RequestHandler> basePackage(final String basePackage) {
    
    
        return input -> Optional.fromNullable(input.declaringClass()).transform(
                (Function<Class<?>, Boolean>) input1 -> {
    
    
                    for (String strPackage : basePackage.split(",")) {
    
    
                        boolean isMatch = input1.getPackage().getName().startsWith(strPackage);
                        if (isMatch) {
    
    
                            return true;
                        }
                    }
                    return false;
                }
        ).or(true);
    }
    
    public ApiInfo apiInfo(String title, String description, String version) {
    
    
        return new ApiInfoBuilder()
                .title(title)
                .version(version)
                .description(description)
                .termsOfServiceUrl("https://springfox.github.io/springfox/docs/current/")
                .version(version)
                .build();
    }
}

이렇게하면 http : // your ip : port / api / swagger-ui.html을 방문하면 swaggerUI가 의미에 따라 그룹화되어 그룹화 작업이 끝났음을 알 수 있습니다.

문서 JSON의 사용자 지정 처리

SwaggerUI의 구성은 다음과 같습니다.

包括
包括
包括
包括
包括
包括
包括
包括
group
swagger
info
host
basePath
tags
schemes
consumes
...

따라서 첫 번째 단계에서 그룹을 가져와야합니다.

RestTemplate restTemplate = new RestTemplate();
List groupEntities = restTemplate.getForObject("http://ip:port/contextPath/swagger-resources", ArrayList.class);

모든 그룹을 얻은 후에는 그룹 내부에서 하나씩 스웨거를 얻을 수 있습니다.

Swagger swagger = getSwagger(groupName, httpServletRequest);

Swagger를 얻으려면 두 개의 개체를 주입해야합니다. 방법은 다음과 같습니다.

@Autowired
    private DocumentationCache documentationCache;

    @Autowired
    private ServiceModelToSwagger2Mapper mapper;

    private String hostNameOverride = "DEFAULT";

    private String hostName(UriComponents uriComponents) {
    
    
        if ("DEFAULT".equals(this.hostNameOverride)) {
    
    
            String host = uriComponents.getHost();
            int port = uriComponents.getPort();
            return port > -1 ? String.format("%s:%d", host, port) : host;
        } else {
    
    
            return this.hostNameOverride;
        }
    }

    private Swagger getSwagger(String groupName, HttpServletRequest request) {
    
    
        Documentation documentation = this.documentationCache.documentationByGroup(groupName);
        if (documentation != null) {
    
    
            Swagger swagger = this.mapper.mapDocumentation(documentation);
            UriComponents uriComponents = HostNameProvider.componentsFrom(request, swagger.getBasePath());
            swagger.basePath(Strings.isNullOrEmpty(uriComponents.getPath()) ? "/" : uriComponents.getPath());
            if (Strings.isNullOrEmpty(swagger.getHost())) {
    
    
                swagger.host(this.hostName(uriComponents));
            }
            return swagger;
        }
        return null;
    }

HostNameProvider 클래스를 사용합니다.

public class HostNameProvider {
    
    
    public HostNameProvider() {
    
    
        throw new UnsupportedOperationException();
    }

    public static UriComponents componentsFrom(HttpServletRequest request, String basePath) {
    
    
        ServletUriComponentsBuilder builder = fromServletMapping(request, basePath);
        UriComponents components = UriComponentsBuilder.fromHttpRequest(new ServletServerHttpRequest(request)).build();
        String host = components.getHost();
        if (!StringUtils.hasText(host)) {
    
    
            return builder.build();
        } else {
    
    
            builder.host(host);
            builder.port(components.getPort());
            return builder.build();
        }
    }

    private static ServletUriComponentsBuilder fromServletMapping(HttpServletRequest request, String basePath) {
    
    
        ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromContextPath(request);
        builder.replacePath(prependForwardedPrefix(request, basePath));
        if (StringUtils.hasText((new UrlPathHelper()).getPathWithinServletMapping(request))) {
    
    
            builder.path(request.getServletPath());
        }

        return builder;
    }

    private static String prependForwardedPrefix(HttpServletRequest request, String path) {
    
    
        String prefix = request.getHeader("X-Forwarded-Prefix");
        return prefix != null ? prefix + path : path;
    }
}

이러한 방식으로 Swagger 오브젝트를 획득했습니다. 나머지는 Swagger 개체에서 직접 처리 할 수 ​​있습니다.

추천

출처blog.csdn.net/polixiaohai/article/details/107082976