Введение в чванство
Swagger действительно хорошая вещь. Он может автоматически генерировать интерфейсные документы API на основе бизнес -кода, особенно для проектов в стиле RESTFUL. Разработчики вряд ли могут поддерживать API RESTAP конкретно. Эта структура может автоматически генерировать API в стиле RestFut для вашего бизнес-кода, а также предоставляет соответствующий тестовый интерфейс для автоматического отображения ответа в формате JSON. Это значительно облегчает общение и затраты на координацию между застройщиками и фронт-концом.
Введение в Springfox-Swagger
С мощными функциями Swagger, Java Big Spring Framework с открытым исходным исходным кодом быстро поддержала. Он полностью использовал свои собственные преимущества, интегрировал Swagger в свой собственный проект и интегрировал пружинный вывод, который впоследствии превратился в Springfox. Сам Springfox использует только свои собственные характеристики AOP и интегрирует Swagger в пробку. Его собственное поколение деловых API по -прежнему полагается на Swagger для достижения его.
Относительно мало информации об этой структуре, и большинство из них являются простым использованием начального уровня. Я столкнулся с множеством ловушек в процессе интеграции этой структуры в свой проект. Чтобы решить эти ловушки, мне пришлось выкопать его исходный код, чтобы увидеть, что это было. В этой статье описывается мое понимание Springfox и о том, на что нужно обратить внимание во время использования Springfox.
Общий принцип Springfox
Общий принцип Springfox заключается в том, что в процессе запуска проекта, во время процесса инициализации контекста пружины, структура автоматически загружает некоторые бобы, связанные с чванством, в текущий контекст в соответствии с конфигурацией и автоматически сканирует классы, которые могут потребоваться генерировать документы API в системе, и генерирует соответствующий информационный кэш. Если уровень управления MVC в проекте использует SpringMVC, он автоматически сканирует все классы контроллера, чтобы генерировать соответствующие документы API в соответствии с методами в этих классах контроллера.
Поскольку мой проект - SpringMVC, в этой статье используется Srping MVC Integration Springfox в качестве примера для обсуждения использования и принципов Springfox.
Шаги по интеграции Springmvc в Springfox
Во -первых, проект должен добавить следующие три зависимости:
<!-Sring MVC Deperiance-> <dependency> <groupid> org.springframework </groupid> <artifactid> spring-webmvc </artifactid> <sersive> 4.2.8.Release </version> </dependence> <!-Swagger2 Core-зависимость-> <Dependency> <groupId> io.springfox> <! <ratifactid> Springfox-swagger2 </artifactid> <sersive> 2.6.1 </version> </deperency> <!-Swagger-ui Предоставляет интерфейс дисплея и тестирование API для проектов-> <Dependency> <groupid> io.springfox </GroupD> <artifactid> springfox-sguger-uii </artifactid> 2.6.
Вышеуказанные три зависимости являются наиболее основными зависимостями для интеграции проекта Springmvc и Springfox, а другие зависимости здесь опущены. Первым является основная зависимость SpringMVC, вторая-это зависимость Swagger, а третье-зависимость, связанная с интерфейсом. Это не обязательно. Если вы не хотите использовать интерфейс API, который поставляется с Springfox, вы также не можете использовать его и написать набор интерфейсов, которые соответствуют вашему проекту. После добавления этих зависимостей система автоматически добавит несколько пакетов JAR, связанных с Springfox и Swagger. Я кратко взглянул и обнаружил, что в основном есть следующие:
Springfox-Swagger2-2.6.1.jar
Swagger-annotations-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-22.6.1.jar
Джексон-Датабинд-2.2.3.Jar
Джексон-Анотации-2.2.3.Jar
Вышесказанное - банки, которые я визуально думаю, что Springfox может понадобиться, и может не полностью проиллюстрировать все банки, которые нуждаются в Springfox. Из приведенной выше JAR мы видим, что в дополнение к полаганию на чванство, Pringfox также требует гуавы, пружины, Джексона и других зависимостей (обратите внимание, что Джексон является необходимым пакетом JAR для генерации JSON. Если эта зависимость не добавляется к самому проекту, чтобы интегрировать Swagger, эта зависимость должна быть добавлена).
Простое использование Springfox
Если вы используете только конфигурацию Springfox по умолчанию, интеграция с SpringMVC очень проста. Просто напишите класс, похожий на следующий код, и поместите его в свой проект. Код заключается в следующем:
@Configuration@enablewebmvc@enatorswagger2publicclass apiconfig {}Обратите внимание, что выше - пустой файл класса Java, имя класса может быть указано по желанию, но должны быть добавлены три аннотации, отмеченные @configuration, @enablewebmvc и @enabswagger2. Это завершает базовую интеграцию SpringMVC и Springfox. С тремя аннотациями, после начала проекта вы можете напрямую использовать адрес, аналогичный следующему, для просмотра списка API: http://127.0.0.1:8080/jaddemo/swagger-ui.html
Это действительно очень волшебный эффект. С тремя простыми аннотациями система автоматически отображает все API всех классов контроллера в проекте. Теперь давайте начнем с этого класса конфигурации и просто проанализируем его принципы. В этом классе нет кода, и очевидно, что три аннотации играют решающую роль. Среди них аннотация @configuration уже доступна в рамках весенней. Это аннотация, идентифицированная @Component MetaNation. Следовательно, с помощью этой аннотации Spring автоматически создаст класс в фасоль и зарегистрирует его в контексте Spring. Следовательно, вторая аннотация @enablewebmvc означает, что SrpingMVC включен. Нажмите на эту аннотацию в Eclipse для краткого взгляда. Это для того, чтобы внести бон типа DelegatingWebmvcconfiguration в пружинный контекст через мета -аннотацию @Import (DelegatingWebmvcconfiguration.class). Я думаю, что цель этого класса должна заключаться в том, чтобы обеспечить чванство некоторую конфигурацию SpringMVC. Третья аннотация: @eNableswger2. Вы можете придумать имя. Он используется для интеграции Swagger 2. Через метада -аннотацию: @import ({swagger2documentationConfiguration.class}) он представил конфигурацию типа Swagger2documentationConfiguration, и это основная конфигурация Swammer. Код внутри него следующим образом:
@Configuration@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 (); }}Этот заголовок класса использует некоторые аннотации, а затем вводит класс SpringfoxWebMvcConfiguration и класс SwaggerCommonConfiguration и автоматически сканирует бобы, связанные с Springfox. Swagger2 в контексте Spring через аннотацию ComponentsCan. Здесь меня больше всего интересует, так это класс Springfoxwebmvcconfiguration. Я предполагаю, что этот класс должен быть более основной конфигурацией интегрированного MVC Springfox. Нажмите и посмотрите на следующий код:
@Configuration@import ({modelsconfiguration.class})@componentscan (basepackages = { "Springfox.documentation.spring.web.scanners", "Springfox.documentation.spring.web.readers.operation", "Springfox.documentation.spring.web.readers.operation", "Springfox.documentation.spring.parameter", "springfox.documentation.spring.web.plugins", "Springfox.documentation.spring.web.paths"})@enablepluginregistries ({{{{{{{{{{{{{{{{{{{{{{{{{{{{{ DocumentCationPlugin.Class, ApilistingBuilderPlugin.Class, OperationBuilderPlugin.Class, ParameterBuilderPlugin.Class, ExpatedParameterBuilderPlugin.class, DresourceGroupingStrategy.Class, OperationModelsProviderPlugin.class, depaulsproviderprategy.class. Pathdecorator.class}) publicclassspringfoxwebmvcconfiguration {}Следующий код в этом классе - не что иное, как добавление новых бобов через аннотацию @Bean. Меня это не очень интересует. Что меня больше всего интересует, так это то, что добавляют в голову через @enablepluginregistries. Springfox основан на механизме пружины для интеграции Swagger. Как реализовать Spring-Plug? У меня еще нет времени, чтобы изучить принцип пружины. Но ниже я упомяну, что я пишу плагин плагина, чтобы расширить функциональность Swagger. Подсказка, добавленная выше через @enablepluginregistries, еще не доступна. Коды, которые я видел в основном, включают в себя ApilistingBuilderPlugin.class, OperationBuilderPlugin.class, ParameterBuilderPlugin.class, ExpatedParameterBuilderPlugin.class, ExpatedParameterBuilderPlugin.class,
Первый ApilistingBuilderPlugin, который имеет два класса реализации, а именно ApilistingReader и SwaggerApilistingReader. Среди них ApilistingReader автоматически генерирует список API в соответствии с типом контроллера, а SwaggerapilistingReader будет генерировать список API в соответствии с классом, идентифицированным аннотацией @API. Плагин OperationBuilderPlugin используется для создания конкретных документов API. Этот тип плагина имеет много классов реализации. Каждый из них делят свой труд и делает свои вещи. Я не смотрел детали внимательно, но сосредоточился только на одном из классов реализации: OperationParameterReader. Этот класс представляет собой плагин, используемый для чтения параметров API. Он опирается на класс инструмента ModelattributeParameterExpander, который может автоматически анализировать объекты команды не простой тип в параметрах метода интерфейса в контроллере, чтобы получить список параметров, содержащий все атрибуты (здесь есть яма, которая может вызвать бесконечную рекурсию, который введен ниже). Плагин expedypedParameterBuilderPlugin в основном используется для расширения некоторых функций параметров интерфейса, таких как определение типа данных этого параметра и является ли он необходимым параметром для этого интерфейса и т. Д. В целом, весь Springfox-Swager фактически транспортируется этой серией платьев. Когда система запускается, они настроены, некоторые используются для сканирования списка интерфейсов, некоторые используются для чтения параметров интерфейса и т. Д. Их общая цель - сканировать все интерфейсы API в системе и кэшировать их для просмотра пользователей. Итак, как настраивается эта серия заглушек таблицы и где их входы в исполнение?
Мы уделяем внимание контенту аннотации ComponentsCan в заголовке кода класса SpringfoxWebMvcConfiguration выше. В этой аннотации, пакет под названием Springfox.documentation.spring.web.plugins, сканируется. Этот пакет можно найти в Springfox-Spring-Web-2.6.1.jar. В рамках этого пакета мы обнаружили, что есть два очень основных класса, а именно DocumentationPluginsmanager и DocucationPluginsbootStrapper. Для первой документации Ppluginsmanager это комбинезон, который не реализует никакого интерфейса, но он обладает множеством свойств типа плагина, и все они вводят в значение свойства через аннотацию @autowired. Объединяя название своего класса, легко думать, что это менеджер, который управляет всеми вилками. Это легко понять из -за конфигурации аннотации ComponentsCan, все экземпляры плавон будут созданы в боба к весне, а затем вводят в этот экземпляр документации Pluginsmanager и управляется равномерно. Еще один важный класс в этом пакете документации PluginsbootStrapper, вы можете догадаться, посмотрев на имя, это может быть класс запуска. Когда вы нажимаете и посмотрите на специфику, вы обнаружите, что это действительно компонент, идентифицированный @Component, и его метод строительства вводит только что описанный экземпляр документации Pluginsmanager, и самое важное, что он также реализует интерфейс SmartLifecycle. Любой, кто знает жизненный цикл весенних бобов, знает, что когда этот компонент создается в бобах и управляется в контексте SRPING, его метод start () будет автоматически вызван. Когда вы нажимаете на start (), чтобы посмотреть на код, вы обнаружите, что он имеет строку скандации кода (BuildContext (каждый)); который используется для сканирования документов API. Благодаря дальнейшему отслеживанию кода этого метода вы можете обнаружить, что этот метод в конечном итоге будет использовать свое свойство документации Pluginsmanager, чтобы настроить все заглушки вместе для сканирования всей системы и генерации документов API. Результаты сканирования кэшируются в свойстве карты класса документации.
Вышеуказанное является общим принципом SrpingMVC, интегрирующей Springfox. В основном он вводит серию бобов в контекст Srping через аннотацию outswagger2 и автоматически сканирует класс контроллера системы при запуске системы, генерирует соответствующую информацию API и кэширует ее. Кроме того, он вводит некоторые классы контроллера, идентифицированные аннотацией @Controller в качестве записи для модуля пользовательского интерфейса для доступа к списку API. Например, класс Swagger2controller в пакете Springfox-Swagger2-2.6.1.jar. Этот контроллер является интерфейсным адресом, используемым в модуле пользовательского интерфейса для доступа к списку API. Когда вы посещаете адрес http://127.0.0.1:8080/jaddemo/swagger-ui.html для просмотра списка API, вы можете увидеть через браузер, что это асинхронно получение информации API (формат JSON) через адрес сходного адреса. http://127.0.0.1:8080/jaddemo/v2/api-docs?group=sysgroup и отображение на интерфейсе. Запись контроллера, соответствующая фону этого адреса, является классом Swagger2controller выше. После получения запроса этот класс напрямую получает информацию API из кэша, который был инициализирован заранее для генерации возврата строки JSON.
Понимая принципы Springfox, давайте посмотрим, какие ловушки я столкнулся во время использования Springfox.
Первая большая яма Springfox: бобы, сгенерированные классом конфигурации, должны использовать тот же контекст, что и Spring MVC.
Как описано выше, в проекте SpringMVC интеграция SpringFox - это просто написать простой класс конфигурации следующим образом без какого -либо бизнес -кода в проекте.
@Configuration@enablewebmvc@enatorswagger2publicclass apiconfig {}Из -за аннотации @Configuration Spring автоматически создаст его в фасоль и вводит в контекст. Но одна ловушка, которую следует отметить, состоит в том, что контекст, в котором этот боб должен быть в том же контексте, что и Spring MVC. Как понять? Поскольку в фактических весенних проектах MVC обычно существует два контекста, один следит за контекстом, а другой - Spring MVC (это субконтекст, который следует за контекстом). Контекст - это org.springframework.web.context.request.requestcontextlister Sulder, связанный с Spring в файле web.xml. Загруженный контекст обычно записывается как файл конфигурации с именем Spring-contet.xml. Бобы здесь в конечном итоге будут инициализированы в контексте. В основном он включает в себя сервис, DAO и другие бобы в системе, а также источники данных, вещи и т. Д. Другой контекст - Spring MVC, который загружается через org.springframework.web.servlet.dispatcherservlet, связанный с Spring Mvc в web.xml. Обычно он имеет файл конфигурации под названием Spring-Mvc.xml. При написании класса Apiconfig, если мы решим загрузить его с помощью аннотации @configuration, мы должны убедиться, что путь этого класса находится в рамках базовой пакетирования конфигурации компонента Scan в SpringMVC. Потому что, когда Apiconfig загружена пружиной, будет введена серия бобов. В этих бобах, чтобы автоматически сканировать все классы контроллеров, некоторые бобы должны полагаться на некоторые бобы в SpringMVC. Если проект отделяет контекст SrpingMVC от контекста как субконтекст контекста. Если вы случайно позволите загружать этот тип Apiconfig Bean с предыдущим текстом, потому что в контексте Spring MVC нет классов конфигурации в корневом контексте.
На самом деле, я не согласен с настройкой Swagger через аннотацию @Configuration, потому что я думаю, что функциональность API Swagger не является обязательной для производственных проектов. Наш Swagger часто используется для тестирования среда для разработки команды фронтальных проектов или для других систем для интеграции интерфейсов. Как только система будет в Интернете, вполне вероятно, что эти списки API будут скрыты в производственной системе. Но если конфигурация записана в коде Java через аннотацию @Configuration, то, когда вы хотите удалить эту функцию, когда вы выйдете в интернет, она будет смущает, и вам нужно изменить код Java для перекомпилирования. Основываясь на этом, я рекомендую метод настройки наиболее традиционного файла XML к весне. Конкретный метод состоит в том, чтобы удалить аннотацию @Configuration, а затем записывает конфигурацию бобов, аналогичную <Bean/> в файл конфигурации Spring XML. В проекте, где корневой контекст отделен от контекста MVC, он напрямую настроен на Spring-Mvc.xml, что гарантирует, что он должен находиться в том же контексте, что и контекст SpringMVC.
Вторая по величине яма Springfox: параметры класса контроллера, обратите внимание на предотвращение бесконечной рекурсии.
Spring MVC имеет мощный механизм привязки параметров, который может автоматически связывать параметры запроса с пользовательским объектом команды. Поэтому, чтобы быть ленивыми, многие разработчики напрямую используют объект объекта в качестве параметра метода контроллера при написании контроллера. Например, следующий пример кода:
@Requestmapping (value = "update") открытая строка
Это код, который большинство программистов любит писать в контроллере для изменения объекта. При интеграции с Swagger здесь есть большая яма. Если все свойства в Menuvo являются основными типами, то все в порядке, ничто не идет неправильно. Но если в этом классе есть некоторые другие атрибуты пользовательского типа, и этот атрибут прямо или косвенно существует атрибуты своего собственного типа, будут проблемы. Например: если класс Menuvo является классом меню, он также содержит родитель свойства типа Menuvo, который представляет его родительское меню. Таким образом, модуль Swagger будет напрямую сообщать об ошибке, когда система запускается, потому что она не может загрузить API. Причина ошибки заключается в том, что при загрузке этого метода параметры метода обновления будут анализироваться. Когда параметр Menuvo не является простым типом, все его атрибуты класса будут автоматически интерпретироваться рекурсивно. Это позволяет легко попасть в мертвую петлю бесконечной рекурсии.
Чтобы решить эту проблему, я только что записал класс реализации плагина PrayParameterRearder и класс инструмента ModelatTributEparameterExpander, от которого он зависит. Он заменяет исходные два класса SrpingFox через конфигурацию, заменяет логику анализа параметров как столбец и избегает бесконечной рекурсии. Конечно, это эквивалентно способу изменения уровня исходного кода. Я еще не нашел более совершенного решения этой проблемы, поэтому я могу только порекомендовать вам попытаться избежать этой бесконечной рекурсии при использовании Spring-Fox Swagger. В конце концов, это не соответствует спецификациям объектов команды SpringMVC. Объекты команды с параметром SpringMVC предпочтительно являются только простыми атрибутами основного типа.
Третья основная яма Springfox: группы API, связанные с группировкой, экземпляры спиртных напитков не могут быть загружены лаконичными
Springfox разделит все API на группу по умолчанию. При обращении к адресу, аналогичному http://127.0.0.1:8080/jaddemo/swagger-ui.html, все списки API будут загружены на одной странице. Таким образом, если система немного больше, а API немного больше, страница будет подделана до смерти, поэтому очень необходимо группировать API. Группировка API определяется аннотацией @Bean в файле конфигурации APICONF. Общие конфигурации в Интернете следующие:
@Enablewebmvc@enatorswagger2publicclass apiconfig {@bean public docket CustomDocket () {return newDocket (documentType.swagger_2) .apiinfo (apiinfo ()); }}В приведенном выше коде ввод вводится через @Bean. Эта конфигурация не нужна. Если эта конфигурация недоступна, Framework само по себе будет генерировать экземпляр Docket Docket по умолчанию. Цель этого экземпляра Docket - указать публичную информацию обо всех API, которые она может управлять, такую как основная информация, такая как версия API, автор и т. Д., И указать, какие API перечислены только (отфильтрованы адресами API или аннотациями).
Может быть несколько экземпляров списка, например, следующий код:
@Enablewebmvc@enatorswagger2publicclass apiconfig {@bean public docket CustomDocket1 () {return newDocket (documentType.swager_2) .groupName ("apigroup1"). Apiinfo (apiinfo ()). Select (). Pathss (pathselectors.ant ("/sys/**; } @Bean public docket CustomDocket2 () {return newDocket (documentType.swagger_2) .groupName ("apigroup2"). Apiinfo (apiinfo ()). Select (). }}Когда в проекте настроены несколько экземпляров списков, API можно сгруппировать, например, приведенный выше код делит API на две группы. В этом случае каждой группе должно быть назначено другое имя, такое как «Apigroup1» и «Apigroup2» в приведенном выше коде. Каждая группа может использовать пути, чтобы указать, какую группу управлять какой API с помощью выражения адреса в стиле муравья. Например, в приведенной выше конфигурации первой группой адресов управления являются API с началом /sys /. Вторая группа управленческих API с началом /Shop /. Конечно, существует много других методов фильтрации, таких как классовая аннотация, аннотация метода, обращение в регулярные выражения и т. Д. После группировки вы можете выбрать различные группы API в раскрывающемся параметре в верхнем правом углу интерфейса списка API. Это рассеяет список API проекта на разные страницы. Это облегчит управление, не притворяясь мертвым, потому что страница должна загружать слишком много API.
Однако, как и использование @Configuration, я не согласен с использованием @Bean для настройки экземпляров Docket на групповые API. Из -за этого код также будет записан до смерти. Итак, я рекомендую настроить свой собственный экземпляр Docket в файле XML для реализации этих аналогичных функций. Конечно, учитывая множество атрибутов в списке, более трудно напрямую настраивать бобы. Вы можете написать фабрику для списка самостоятельно, а затем настроить Factorybean в файле XML. Однако при настройке докета в XML. Вы столкнетесь с другой большой ямой, то есть методом загрузки пружины на бобы лениво загружен по умолчанию. После непосредственной настройки этих бобов экземпляра Docket в XML. Вы обнаружите, что нет никакого эффекта, и в раскрывающемся списке нет элемента группировки в верхнем левом углу страницы.
Эта проблема беспокоила меня в течение нескольких часов. Позже, основываясь на опыте, предполагалось, что это может быть связано с тем, что пружинный фасоль ленивый загружается по умолчанию, и этот экземпляр Docket не был загружен в контекст пружины. Как выясняется, я предполагаю, что верно. Я не знаю, является ли это ошибкой в Springfox, или я не должен был перемещать конфигурацию Docket из исходного кода Java в файл конфигурации XML.
Другие ловушки в Springfox: в Springfox есть другие подводные камни. Например, в аннотации @Apioperation, если атрибут httpmethod не указан в качестве определенного метода Get или post, все методы, такие как Get, post, delete, PUT, будут перечислены в списке API, так что список API слишком много дублируется, что очень уродливо. Кроме того, во время тестирования я столкнулся с проблемами разрешения входа в систему и т. Д. Есть также использование аннотаций, таких как @API, @Apioperation и @apiparam. Я не буду повторять много документов в этом онлайн.
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.