Recuerde la encapsulación de Swagger-UI y el análisis y procesamiento de los datos JSON del documento

Recuerde la encapsulación de Swagger-UI y el análisis y procesamiento de los datos JSON del documento

origen

Los proyectos de Spring a menudo tienen que formar un documento para que lo usen otras personas, especialmente la interfaz desarrollada. Hay muchos tipos de documentos de clase en Java, como javadoc, genDoc, SwaggerUI, etc. De acuerdo con los requisitos, primero debemos agrupar diferentes paquetes de controladores. Cada paquete de controladores representa un tipo de interfaz. En segundo lugar, la interfaz de pantalla SwagerUI original puede no ser lo que queremos, por lo que debemos transformarla.

Tenga en cuenta que la versión de SwaggerUI utilizada en mi código es 2.7.0, y la diferencia entre cada versión de SwaggerUI es relativamente grande.

Agrupe las interfaces de acuerdo con el paquete de controlador de código

Necesitamos configurar SwaggerUI globalmente para que admita la generación dinámica de DocketBean de acuerdo con el paquete.
En primer lugar, necesitamos definir una clase utilizada para ilustrar la descripción del documento para la configuración 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 clase corresponde al archivo de configuración:

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

Luego usamos el archivo de configuración global para implementar la inyección dinámica de beans, de la siguiente manera:

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

Después de hacer esto, puede ver cuando visite http: // your ip: port / api / swagger-ui.html que swaggerUI se ha agrupado de acuerdo con su significado, y el trabajo de agrupación ha terminado.

Procesamiento personalizado de documento JSON

La organización de SwaggerUI es:

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

Entonces necesitamos obtener los grupos en el primer paso:

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

Después de obtener todos los grupos, podemos obtener la arrogancia dentro de los grupos uno por uno:

Swagger swagger = getSwagger(groupName, httpServletRequest);

Para obtener Swagger necesitamos inyectar dos objetos, el método es el siguiente:

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

De esta forma se ha obtenido el objeto Swagger. El resto puede procesarse usted mismo en el objeto Swagger.

Supongo que te gusta

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