Lembre-se do encapsulamento do Swagger-UI e da análise e processamento dos dados JSON do documento

Lembre-se do encapsulamento do Swagger-UI e da análise e processamento dos dados JSON do documento

origem

Projetos Spring freqüentemente precisam formar um documento para outras pessoas usarem, especialmente a interface desenvolvida. Existem muitos tipos de documentos de classe em Java, como javadoc, genDoc, SwaggerUI, etc. De acordo com os requisitos, primeiro precisamos agrupar diferentes pacotes de controladores. Cada pacote de controladores representa um tipo de interface. Em segundo lugar, a interface de exibição SwagerUI original pode não ser o que queremos, então precisamos transformá-la.

Observe que a versão do SwaggerUI usada em meu código é 2.7.0, e a diferença entre cada versão do SwaggerUI é relativamente grande.

Agrupe as interfaces de acordo com o pacote do controlador de código

Precisamos configurar o SwaggerUI globalmente para que ele suporte a geração dinâmica de DocketBean de acordo com o pacote.
Em primeiro lugar, precisamos definir uma classe usada para ilustrar a descrição do documento, que é usada para configuração automatizada.

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
    }

Esta classe corresponde ao arquivo de configuração:

#启用/禁用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

Em seguida, usamos o arquivo de configuração global para implementar a injeção dinâmica de bean, como segue:

@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();
    }
}

Depois de fazer isso, você pode ver quando visitar http: // your ip: port / api / swagger-ui.html que swaggerUI foi agrupado de acordo com o seu significado e o trabalho de agrupamento acabou.

Processamento personalizado de documento JSON

A organização do SwaggerUI é:

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

Portanto, precisamos colocar os grupos na primeira etapa:

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

Depois de obter todos os grupos, podemos obter a arrogância dentro dos grupos, um por um:

Swagger swagger = getSwagger(groupName, httpServletRequest);

Para obter o Swagger, precisamos injetar dois objetos, o método é o seguinte:

@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;
    }

Que usa uma classe 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;
    }
}

Desta forma, o objeto Swagger foi obtido. O resto pode ser processado no objeto Swagger.

Acho que você gosta

Origin blog.csdn.net/polixiaohai/article/details/107082976
Recomendado
Clasificación