Introducción a Swagger
Swagger es de hecho algo bueno. Puede generar automáticamente documentos de interfaz API basados en el código de negocio, especialmente para proyectos con estilo RESTful. Los desarrolladores difícilmente pueden tener que mantener específicamente la API de reestima. Este marco puede generar automáticamente API de estilo RESTFUT para su código de negocio, y también proporciona una interfaz de prueba correspondiente para mostrar automáticamente la respuesta en el formato JSON. Facilita enormemente los costos de comunicación y coordinación entre los desarrolladores de back-end y el front-end.
Introducción a Springfox-Swagger
Con las poderosas funciones de Swagger, el gran marco de primavera de la industria de código abierto de Java se mantuvo rápidamente. Utilizó completamente sus propias ventajas, integró Swagger en su propio proyecto e integró una pava de primavera, que luego evolucionó hacia Springfox. SpringFox solo usa sus propias características de AOP e integra Swagger en el enchufe. Su propia generación de API comerciales aún depende de la arrogancia para lograrlo.
Hay relativamente poca información sobre este marco, y la mayoría de ellos son un uso simple de nivel de entrada. Encontré muchas dificultades en el proceso de integración de este marco en mi proyecto. Para resolver estas dificultades, tuve que desenterrar su código fuente para ver qué era. Este artículo describe mi comprensión de SpringFox y a lo que debe prestarse atención durante el uso de SpringFox.
El principio general de Springfox
El principio general de SpringFOX es que en el proceso de inicio del proyecto, durante el proceso de inicialización del contexto de Spring, el marco carga automáticamente algunos frijoles relacionados con Swagger en el contexto actual de acuerdo con la configuración, y escanea automáticamente las clases que pueden necesitar generar documentos API en el sistema, y genera cache de información correspondiente. Si la capa de control MVC del proyecto usa SpringMVC, escaneará automáticamente todas las clases de controlador para generar los documentos API correspondientes de acuerdo con los métodos en estas clases de controlador.
Dado que mi proyecto es SpringMVC, este artículo utiliza SRPing MVC Integration Springfox como ejemplo para discutir el uso y los principios de SpringFox.
Pasos para integrar SpringMVC en SpringFox
Primero, el proyecto debe agregar las siguientes tres dependencias:
< <artifactId>springfox-swagger2</artifactId> <version>2.6.1</version> </dependency> <!-- swagger-ui provides API display and testing interface for projects --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.6.1</version> </dependency>
Las tres dependencias anteriores son las dependencias más básicas para la integración de proyectos SpringMVC y SpringFox, y se omiten otras dependencias aquí. El primero es la dependencia básica de SpringMVC, la segunda es la dependencia de arrogancia, y el tercero es la dependencia relacionada con la interfaz. Esto no es necesario. Si no desea utilizar la interfaz API que viene con SpringFox, tampoco puede usar esto y escribir un conjunto de interfaces que se adapten a su proyecto. Después de agregar estas dependencias, el sistema agregará automáticamente algunos paquetes JAR relacionados con SpringFox y Swagger. Eché una breve mirada y descubrí que hay principalmente lo siguiente:
Springfox-Swagger2-2.6.1.Jar
Annotaciones Swagger-1.5.10.Jar
Swagger-Models-1.5.10.Jar
Springfox-SPI-2.6.1.Jar
Springfox-core-2.6.1.Jar
springfox-schema-2.6.1.Jar
Springfox-Swagger-Common-2.6.1.Jar
Springfox-Spring-Web-2.6.1.Jar
Guava-17.0.Jar
Spring-Plugin-Core-1.2.0.Release.Jar
Spring-plug-Metadata-1.2.0.Release.Jar
Spring-Swagger-Ui-2.6.1.Jar
Jackson-Databind-2.2.3.Jar
Jackson-Annotations-2.2.3.Jar
Lo anterior son los frascos que visualmente creo que Springfox puede necesitar, y no ilustrar completamente todos los frascos que SpringFox necesita. En el frasco anterior, podemos ver que, además de confiar en Swagger, Pringfox también requiere Guava, Spring-Plug, Jackson y otras dependencias (tenga en cuenta que Jackson es un paquete JAR necesario para generar JSON. Si esta dependencia no se agrega al proyecto en sí, para integrar Swagger, se debe agregar esta dependencia).
Uso simple de Springfox
Si solo usa la configuración predeterminada de SpringFox, integrarse con SpringMVC es muy simple. Simplemente escriba una clase similar al siguiente código y póngala en su proyecto. El código es el siguiente:
@Configuration@enablewebmvc@habilswagger2publicclass apiconfig {}Tenga en cuenta que arriba es un archivo de clase Java vacío, el nombre de la clase se puede especificar a voluntad, pero las tres anotaciones marcadas @Configuration, @enableWebMvc y @habilitanwagger2 en la clase anterior se deben agregar. Esto completa la integración básica de SpringMVC y SpringFox. Con tres anotaciones, después de que comience el proyecto, puede usar directamente una dirección similar a la siguiente para ver la lista de API: http://127.0.0.1:8080/jaddemo/swagger-ui.html
De hecho, este es un efecto muy mágico. Con tres anotaciones simples, el sistema mostrará automáticamente todas las API de todas las clases de controlador en el proyecto. Ahora, comencemos con esta clase de configuración y simplemente analicemos sus principios. No hay código en esta clase, y es obvio que las tres anotaciones juegan un papel crucial. Entre ellos, la anotación @configuration ya está disponible en el marco de primavera. Es una anotación identificada por la meta anotación @Component. Por lo tanto, con esta anotación, Spring instanciará automáticamente la clase en un frijol y la registrará en el contexto de primavera. La segunda anotación @EnableWebMVC, por lo tanto, significa que SRPingMVC está habilitado. Haga clic en esta anotación en Eclipse para ver breve. Es rellenar un frijol de tipo delegación de tubmvcconfiguration en el contexto de primavera a través de la meta anotación @import (delegandowebmvcconfiguration.class). Creo que el propósito de esta clase debería ser proporcionar a Swagger con una configuración de SpringMVC. La tercera anotación: @habilswagger2. Puedes pensar en el nombre. Se utiliza para integrar Swagger 2. A través de la meta anotación: @import ({swagger2DocumentationConfiguration.class}), introdujo una frijol de tipo Swagger2DocumationConfiguration, y esta es la configuración central de Swagger. El código dentro es el siguiente:
@Configuración@import ({springfoxwebmvcconfiguration.class, swaggercommonconfiguration.class})@componentscan (basepackages = {"springfox.documentation.swagger2.readers.parameter", "springfox.documentation.swagger2.web",,,, "Springfox.documentation.swagger2.mappers"}) publicClassSwagger2DocumentationConfiguration {@Bean public JacksonModuleregistrar Swagger2Module () {returnNeWSWagger2JacksonModule (); }}Este encabezado de clase utiliza algunas anotaciones, y luego presenta la clase SpringFoxWebMVCConfiguration y la clase SwaggerComMonfiguration, y escanea automáticamente los frijoles relacionados con Springfox .Swagger2 en el contexto de primavera a través de la anotación de componentes. Aquí, lo que más me interesa es la clase SpringFoxWebMVCConfiguration. Supongo que esta clase debería ser la configuración más central de SpringFox Integrated MVC. Haga clic y vea el siguiente código:
@Configuration@import ({ModelsConfiguration.class})@ComponentScan (basepackages = { "Springfox.documentation.spring.web.scanners", "springfox.documentation.spring.web.eaders.operation", "springfox.documentation.spring.web.eaders.operation", "Springfox.documentation.spring.parameter", "springfox.documentation.spring.web.plugins", "springfox.documentation.spring.web.paths"})@enseablepluginregistries ({{ Documentationplugin.class, apilistingbuilderplugin.class, operationBuilderplugin.class, parameterBuilderPlugin.class, expandedParameterBuilderPlugin.class, recurseGroupingingSygy.class, OperationModelsProviderPlugin.class, defaultsProvider.Class, PathDecorator.Class}) publicClassSpringFoxWebMvCConfiguration {}El siguiente código en esta clase no es más que agregar algunos frijoles nuevos a través de la anotación @Bean. No estoy muy interesado en ello. Lo que más me interesa son las cosas agregadas a la cabeza a través de @enablePlugInRegistries. SpringFox se basa en el mecanismo de plug-spring para integrar la arrogancia. ¿Cómo se implementa Spring-Plug? Todavía no tengo tiempo para estudiar el principio de la plug de primavera. Pero a continuación, mencionaré que escribo un complemento de enchufe para extender la funcionalidad de Swagger. El enchufe agregado arriba a través de @enablePlugInRegistries aún no está disponible. Los códigos que he visto incluyen principalmente apilistingbuilderplugin.class, operationBuilderplugin.class, parameterBuilderplugin.class, ExpandandedParameterBuilderplugin.class, expandedParameterBuilderplugin.class,
El primer ApilistingBuilderplugin, que tiene dos clases de implementación, a saber, ApilistingReader y SwaggerilistingReader. Entre ellos, el ApilistingReader generará automáticamente una lista de API de acuerdo con el tipo de controlador, y el SwaggerApilistingReader generará una lista API de acuerdo con la clase identificada por la anotación @API. El complemento OperationBuilderplugin se utiliza para generar documentos API específicos. Este tipo de complemento tiene muchas clases de implementación. Cada uno divide su trabajo y hacen sus propias cosas. No miré los detalles cuidadosamente, sino que solo me centré en una de las clases de implementación: OperationParameterReader. Esta clase es un complemento utilizado para leer los parámetros de API. Se basa en la clase de herramienta ModelAtTributeParameterRexpander, que puede analizar automáticamente los objetos de comando del tipo no simple en los parámetros del método de interfaz en el controlador para obtener una lista de parámetros que contiene todos los atributos (aquí hay un pozo que puede causar una recursión infinita, que se introduce a continuación). El complemento ExpandennedParameterBuilderplugin se usa principalmente para extender algunas funciones de los parámetros de la interfaz, como determinar el tipo de datos de este parámetro y si es un parámetro necesario para esta interfaz, etc. En general, la camiseta SpringFox en realidad es realmente transportada por esta serie de enchufes. Cuando se inicia el sistema, están sintonizados, algunos se usan para escanear la lista de interfaz, algunos se usan para leer los parámetros de la interfaz, etc. Su propósito común es escanear todas las interfaces API en el sistema y almacenarlos en caché para que los usuarios los vean. Entonces, ¿cómo se ajustan esta serie de enchufes de mesa y dónde están sus entradas de ejecución?
Ponemos nuestro punto de atención en el contenido de anotación de componentes en el encabezado de código de la clase SpringFoxWebMVCConfiguration anterior. En esta anotación, se escanea un paquete llamado SpringFox.Documentation.Spring.Web.Plugins. Este paquete se puede encontrar en Springfox-Spring-Web-2.6.1.Jar. En este paquete, descubrimos que hay dos clases muy centrales, a saber, DocumationPluginsManager y DocumationPlugInsBootstraPper. Para el primer documento PluginSmanager, es un frijol que no implementa ninguna interfaz, pero tiene muchas propiedades del tipo de registro de pluginegistry, y todos ellos se inyectan en el valor de la propiedad a través de la anotación @aUtowired. Combinando su nombre de clase, es fácil pensar que este es un gerente que administra todos los enchufes. Es fácil de entender, debido a la configuración de la anotación de componentes, todas las instancias de enchufe se instanciarán en un frijol por primavera, y luego se inyectarán en esta instancia de documentaciónpluginsManager y se administrarán de manera uniforme. Otra clase importante en este paquete DocumentationPlugInsBootstraPper, puede adivinar al mirar el nombre, puede ser la clase de inicio del enchufe. Cuando hace clic y observa los detalles, encontrará que es un componente identificado por @Component, y su método de construcción inyecta la instancia de DocumationPlugInsManager que acaba de describir, y lo más crítico es que también implementa la interfaz SmartLifecycle. Cualquiera que conozca el ciclo de vida de los frijoles de primavera sabe que cuando este componente se instancia en un frijol y se gestiona en el contexto SRPing, su método Start () se llamará automáticamente. Cuando haga clic en Start () para mirar el código, encontrará que tiene una línea de escandocumentación de código (buildContext (cada una)); que se utiliza para escanear documentos API. Al seguir el seguimiento del código de este método, puede encontrar que este método eventualmente usará su propiedad DocumationPlugInsManager para ajustar todos los enchufes para escanear todo el sistema y generar documentos API. Los resultados del escaneo se almacenan en caché en una propiedad de mapa de la clase DocumationCache.
Lo anterior es el principio general de SRPingMVC integrando SpringFox. Inyecta principalmente una serie de frijoles en el contexto SRPing a través de la anotación de habilitaciones de Aablewagger2, y escanea automáticamente la clase de controlador del sistema cuando el sistema comienza, genera la información de API correspondiente y la almacena en caché. Además, inyecta algunas clases de controlador identificadas por @Controller Annotation como la entrada para que el módulo UI acceda a la lista API. Por ejemplo, la clase Swagger2Controller en el paquete SpringFox-Swagger2-2.6.1.JAR. Este controlador es la dirección de interfaz utilizada en el módulo UI para acceder a la lista API. Cuando visite la dirección http://127.0.0.1:8080/jaddemo/swagger-ui.html Para ver la lista de API, puede ver a través del navegador que está obteniendo asincrónicamente la información de la API (formato JSON) a través de una dirección similar a una dirección similar a http://127.0.0.1:8080/jaddemo/v2/api-docs?group=sysgroup y mostrándolo en la interfaz. La entrada del controlador correspondiente al fondo de esta dirección es la clase Swagger2Controller anterior. Después de recibir la solicitud, esta clase obtiene directamente la información de la API del caché que se inicializó por adelantado para generar una devolución de cadena JSON.
Después de comprender los principios de Springfox, echemos un vistazo a las dificultades que encontré durante el uso de Springfox.
El primer gran pozo de Springfox: el frijol generado por la clase de configuración debe compartir el mismo contexto que Spring MVC.
Como se describió anteriormente, en el proyecto SpringMVC, la integración de SpringFox es solo escribir una clase de configuración simple de la siguiente manera sin ningún código de negocio en el proyecto.
@Configuration@enablewebmvc@habilswagger2publicclass apiconfig {}Debido a la anotación de @Configuration, Spring lo instanciará automáticamente en un frijol y lo inyectará en el contexto. Pero una trampa para tener en cuenta es que el contexto en el que este frijol debe estar en el mismo contexto que Spring MVC. ¿Cómo entender? Debido a que en los proyectos de MVC de primavera reales, generalmente hay dos contextos, uno es el siguiente contexto y el otro es Spring MVC (es un subcontexto que sigue el contexto). El contexto es el org.springframework.web.context.request.requestContextListener Oyer relacionado con la primavera en el archivo web.xml. El contexto cargado generalmente se escribe como un archivo de configuración llamado Spring-Contet.xml. Los frijoles aquí eventualmente se inicializarán en el contexto. Incluye principalmente el servicio, DAO y otros frijoles en el sistema, así como fuentes de datos, cosas, etc. Otro contexto es Spring MVC, que se carga a través del org.springframework.web.servlet.dispatcherservlet relacionado con Spring MVC en Web.xml. Por lo general, tiene un archivo de configuración llamado Spring-MVC.XML. Al escribir la clase APICONFIG, si decidimos cargarla con la anotación @Configuration, debemos asegurarnos de que la ruta de esta clase esté dentro del alcance del paquete base de la configuración de componente-scan en SpringMVC. Porque cuando APICONFIG se carga por Spring, se inyectará una serie de frijoles. En estos frijoles, para escanear automáticamente todas las clases de controlador, algunos frijoles deben confiar en algunos frijoles en SpringMVC. Si el proyecto separa el contexto de SRPingMVC del contexto como un subcontexto del contexto. Si accidentalmente deja que este tipo de bean de apiconfig se cargue con el texto anterior, porque no hay clases de configuración en el contexto de Spring MVC en el contexto raíz.
De hecho, no estoy de acuerdo con la configuración de Swagger a través de la anotación @Configuration, porque creo que la funcionalidad API de Swagger es opcional para los proyectos de producción. Nuestra arrogancia a menudo se usa para probar entornos para el desarrollo del equipo frontal del proyecto o para otros sistemas para integrar interfaces. Una vez que el sistema está en línea, es probable que estas listas de API estén ocultas en el sistema de producción. Pero si la configuración se escribe en el código Java a través de la anotación @Configuration, entonces cuando desee eliminar esta función cuando se conecta, será vergonzoso y debe modificar el código Java para recompilar. Según esto, recomiendo un método para configurar el archivo XML más tradicional para Spring. El método específico es eliminar la anotación de @configuration, y luego escribe una configuración de frijoles similar a <bean/> en el archivo de configuración de Spring XML. En un proyecto donde el contexto raíz se separa del contexto MVC, se configura directamente en Spring-MVC.XML, que asegura que debe estar en el mismo contexto que el contexto SpringMVC.
El segundo pozo más grande de Springfox: los parámetros de la clase del controlador, preste atención para prevenir la recursión infinita.
Spring MVC tiene un potente mecanismo de enlace de parámetros, que puede unir automáticamente los parámetros de solicitud en un objeto de comando personalizado. Por lo tanto, para ser perezosos, muchos desarrolladores usan directamente un objeto de entidad como parámetro del método del controlador al escribir un controlador. Por ejemplo, el siguiente código de ejemplo:
@RequestMapping (valor = "actualización") Public String Update (Menuvomenuvo, modelo modelo) {}Este es el código que a la mayoría de los programadores les gusta escribir en el controlador para modificar una entidad. Al integrarse con Swagger, hay un gran pozo aquí. Si todas las propiedades en Menuvo son tipos básicos, entonces está bien, nada sale mal. Pero si hay algunos otros atributos de tipo personalizado en esta clase, y este atributo existe directa o indirectamente atributos de su propio tipo, entonces habrá problemas. Por ejemplo: si la clase Menuvo es una clase de menú, también contiene un padre de propiedad del tipo Menuvo que representa su menú principal. De esta manera, el módulo Swagger informará directamente un error cuando el sistema comience porque no puede cargar la API. La razón del error es que al cargar este método, se analizarán los parámetros del método de actualización. Cuando el parámetro Menuvo no es un tipo simple, todos sus atributos de clase se interpretarán automáticamente de manera recursiva. Esto facilita caer en un bucle muerto de recursión infinita.
Para resolver este problema, acabo de escribir una clase de implementación del complemento OperationParameterReader y la clase de herramienta ModelAtTributeParameterRexpander en la que depende. Reemplaza las dos clases originales de SrpingFox a través de la configuración, reemplaza la lógica de análisis del análisis de parámetros como una columna y evita la recursión infinita. Por supuesto, esto es equivalente a una forma de modificar el nivel del código fuente. Todavía no he encontrado una solución más perfecta para este problema, por lo que solo puedo recomendar que intente evitar esta recursión infinita cuando use Spring-Fox Swagger. Después de todo, esto no cumple con las especificaciones de los objetos de comando SpringMVC. Los objetos de comando con el parámetro SpringMVC son preferiblemente solo atributos de tipo básico simples.
El tercer pozo principal de Springfox: las instancias de agrupación de API relacionadas, el expediente no se puede cargar de forma latente
SpringFox dividirá todas las API en un grupo por defecto. Cuando se accede a través de una dirección similar a http://127.0.0.1:8080/jaddemo/swagger-ui.html, todas las listas de API se cargarán en la misma página. De esta manera, si el sistema es un poco más grande y la API es un poco más, la página será falsificada hasta la muerte, por lo que es muy necesario agrupar la API. La agrupación de API se define mediante la anotación @Bean en el archivo de configuración APICONF. Las configuraciones comunes en Internet son las siguientes:
@Enablewebmvc@habilswagger2publicClass apiconfig {@bean public docket CustomDocket () {return newDocket (documentationType.swagger_2) .apiinfo (apiinfo ()); }}En el código anterior, se inyecta un expediente a través de @Bean. Esta configuración no es necesaria. Si esta configuración no está disponible, el marco generará una instancia de expediente predeterminada por sí misma. El propósito de esta instancia de expediente es especificar la información pública de todas las API que puede administrar, como información básica como la versión API, el autor, etc., y especificar qué API se enumeran solo (filtradas por direcciones o anotaciones de API).
Puede haber múltiples instancias de expediente, como el siguiente código:
@EnableWebmvc@habilswagger2PublicClass apiConfig {@Bean public docket CustomDocket1 () {return newDocket (documentationType.swagger_2) .GroupName ("apiGroup1"). APIInfo (apiInfo ()). Select (). Pathselectors.ant ("/sys/**")); } @Bean public Docket CustomDocket2 () {return newDocket (documentationType.swagger_2) .GroupName ("apigroup2"). Apiinfo (apiinfo ()). Select (). Paths (pathSelectores.ant ("/shop/**"); }}Cuando se configuran múltiples instancias de expediente en el proyecto, la API se puede agrupar, por ejemplo, el código anterior divide la API en dos grupos. En este caso, a cada grupo se le debe asignar un nombre diferente, como "Apigroup1" y "Apigroup2" en el código anterior. Cada grupo puede usar rutas para especificar qué grupo administrar qué API a través de la expresión de dirección de estilo Ant. Por ejemplo, en la configuración anterior, el primer grupo de direcciones de administración son API con el comienzo de /sys /. El segundo grupo de API de gestión con el comienzo de /shop /. Por supuesto, existen muchos otros métodos de filtrado, como anotación de clase, anotación de métodos, expresiones regulares de dirección, etc. Después de agrupar, puede seleccionar diferentes grupos de API en la opción desplegable en la esquina superior derecha de la interfaz de la lista API. Esto dispersará la lista API del proyecto a diferentes páginas. Esto facilitará la gerencia sin pretender estar muerto porque la página necesita cargar demasiadas API.
Sin embargo, como usar @Configuration, no estoy de acuerdo con usar @Bean para configurar las instancias de expediente para agrupar las API. Debido a esto, el código también se escribirá hasta la muerte. Por lo tanto, recomiendo configurar su propia instancia de expediente en el archivo XML para implementar estas funciones similares. Por supuesto, teniendo en cuenta los muchos atributos en el expediente, es más problemático configurar los frijoles directamente. Puede escribir una fábrica para el expediente tú mismo y luego configurar FactoryBean en el archivo XML. Sin embargo, al configurar Docket en XML. Encontrarás otro gran pozo, es decir, el método de carga de Spring on Beans está cargado de forma predeterminada. Después de configurar directamente estos frijoles de instancia de expediente en XML. Encontrará que no hay efecto, y no hay un elemento de agrupación en la lista desplegable en la esquina superior izquierda de la página.
Este problema me ha preocupado durante varias horas. Más tarde, en base a la experiencia, se especuló que podría deberse a que el frijol de resorte es una carga perezosa de forma predeterminada, y esta instancia de expediente no se ha cargado en el contexto de resorte. Resulta que mi suposición es correcta. No sé si este es un error en SpringFox, o si no debería haber movido la configuración del expediente del código Java original al archivo de configuración XML.
Otras trampas en Springfox: hay algunas otras dificultades en Springfox. Por ejemplo, en la anotación @Apioperation, si el atributo httpmethod no se especifica como un cierto método Get o Post, todos los métodos como Get, Post, Delete, PUT se enumerarán en la lista de API, de modo que la lista de API se duplique demasiado, lo cual es muy feo. Además, durante las pruebas, encontré problemas de permiso de inicio de sesión, etc. Estos pozos de pequeños pozos que son más fáciles de resolver, debido al espacio limitado, no diré mucho. También está el uso de anotaciones como @api, @apioperation y @apiparam. No repetiré muchos documentos en esto en línea.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.