1. Введение в чванство
В предыдущей статье мы представили поддержку Spring Boot для Restful. В этой статье мы продолжаем обсуждать эту тему. Тем не менее, мы больше не будем обсуждать, как реализован Retfful API, а скорее обсуждаем поддержание документации API RESTFUL.
В ежедневной работе нам часто необходимо предоставлять интерфейсы на передний конец (Web End, iOS, Android) или третьи стороны. В настоящее время мы должны предоставить им подробную документацию API. Но поддержание подробного документа - нелегкая задача. Прежде всего, написание подробного документа является трудоемкой и трудоемкой задачей. С другой стороны, поскольку код и документ разделены, легко вызвать несоответствия между документом и кодом. В этой статье мы поделимся способом поддержания документов API, то есть автоматически генерировать ресторанные документы API через Swagger.
Так что же такое чванство? Мы можем напрямую прочитать официальное описание:
Самая популярная в мире API ToolingsWagger является крупнейшей в мире структурой инструментов разработчика API для спецификации OpenAPI (OAS), обеспечивающей разработку на протяжении всего жизненного цикла API, от проектирования и документации, для тестирования и развертывания.
Этот отрывок сначала говорит вам, что Swagger является самым популярным инструментом API в мире, и целью Swagger является поддержка разработки всего жизненного цикла API, включая дизайн, документацию, тестирование и развертывание. В этой статье мы будем использовать функции управления документами Swagger и тестирования.
Получив базовое понимание роли Swagger, давайте посмотрим, как его использовать.
2. Интеграция Swagger и Spring Boot
Шаг 1: Представьте соответствующий пакет JAR:
<depervice> <groupid> io.springfox </groupid> <artifactid> springfox-swager2 </artifactid> <sersive> 2.6.0 </version> </dependency> <dependency> <groupid> io.springfox </GroupD> <artifactid> springfox-swager-uii </artifactid> </GroupD> <artifactid> springfox-swager-ui </artifactid>.
Шаг 2: Конфигурация базовой информации:
@Configuration @entableswager2public class swagger2config {@bean public docket createrestapi () {return new docket (documationtype.swagger_2) .apiinfo (apiinfo ()). Selectect () .apis (requestHandLerseLectors.BasePackage ("com.pandy.blog.rest.) .paths (pathselectors.regex ("/rest /.*)) .build (); } private apiinfo apiinfo () {return new apiinfobuilder () .title ("System System Restful API") .description ("System System Restful API") .termsofServiceurl ("http://127.0.0.1:8080/"). .строить(); }}Основная конфигурация - это описание всего документа API и некоторых глобальных конфигураций, которые работают для всех интерфейсов. Здесь есть две аннотации:
@Configuration означает, что это класс конфигурации, аннотация, предоставленная JDK, и была объяснена в предыдущей статье.
@Enabswager2 функция заключается в включении функций, связанных с Swagger2.
В этом классе конфигурации я создал создание объекта Docket, который в основном включает в себя три аспекта информации:
(1) Описание информации всего API, то есть информации, включенной в объект Apiinfo, эта часть информации будет отображаться на странице.
(2) Укажите имя пакета для генерации документа API.
(3) Укажите путь для генерации API. API на основе пути может поддерживать четыре режима, которые можно использовать для обозначения его исходного кода:
открытый класс PathSelectors {private PathSelectors () {бросить новый UnsupportedOperationException (); } public static Predicat <string> any () {return Predicates.alwayStrue (); } public static Predicate <string> non () {return Predicates.alwaysfalse (); } public Static Predicate <string> regex (final String pathregex) {return new Predicate <string> () {public boolean Apply (String input) {return input.matches (pathregex); }}; } public static Predicate <string> ant (final String antpattern) {return new Predicate <string> () {public boolean Apply (String input) {antPathMatcher Matcher = new AntPathMatcher (); return Matcher.match (antpattern, input); }}; }}Как видно из исходного кода, Swagger поддерживает четыре способа: генерация любого пути, не генерируя любого пути, а также регулярное сопоставление и сопоставление паттернов муравья. Вы можете быть более знакомы с первыми тремя типами, последним из согласия муравья. Если вы не знакомы с муравей, просто игнорируйте его. Первых трех типов должны быть достаточно, чтобы каждый мог бы использовать в ежедневной работе.
С приведенной выше конфигурацией мы можем увидеть эффект. У меня есть класс articlerestcontroller в пакете com.pandy.blog.rest. Исходный код заключается в следующем:
Start Spring Boot, а затем посетите: http://127.0.0.1:8080/swagger-ui.html, чтобы увидеть следующие результаты:
На этой странице вы можете увидеть, что за исключением последнего интерфейса /test /{id}, другие интерфейсы генерируют соответствующие документы. Поскольку последний интерфейс не соответствует пути, который мы настроили - "/rest/.*", документ не сгенерирован.
Мы также можем щелкнуть, чтобы увидеть каждый конкретный интерфейс. Давайте возьмем интерфейс «post /rest /artice» в качестве примера:
Как вы можете видеть, Swagger генерирует примеры результатов возврата и запроса параметров для каждого интерфейса и может напрямую получить доступ к интерфейсу через «Try Out» ниже. С точки зрения интерфейса, каждый тестирует интерфейс. В целом, Swagger по -прежнему очень мощный, а конфигурация относительно проста.
@Restcontrollerpublic class articlerestcontroller {@autowired private articleservice articleservice; @Requestmapping (value = "/rest/article", method = post, products = "application/json") public webresponse <map <string, object >> savearticle (@requestbody article article) {article.setUserid (1L); articleservice.savearticle (статья); Map <string, object> ret = new Hashmap <> (); ret.put ("id", article.getid ()); Webresponse <map <string, object >> response = webresponse.getSuccessResponse (ret); ответный ответ; } @Requestmapping (value = "/rest/article/{id}", method = delete, provectes = "application/json") public webresponse <?> Deletearticle (@pathvarible long id) {article article = articleservice.getbyid (id); article.setStatus (-1); iklicservice.updatearticle (статья); Webresponse <object> response = webresponse.getSuccessResponse (null); ответный ответ; } @RequestMapping (value = "/rest/article/{id}", method = put, производители = "application/json") public webresponse <object> updatearticle (@pathvarible long id, @requestbody article article) {article.setid (id); iklicservice.updatearticle (статья); Webresponse <object> response = webresponse.getSuccessResponse (null); ответный ответ; } @RequestMapping (value = "/rest/article/{id}", method = get, производители = "application/json") public webResponse <статья> getarticle (@pathvarible long id) {article article = articleservice.getbyid (id); Webresponse <compate> response = webresponse.getSuccessResponse (статья); ответный ответ; } @RequestMapping (value = "/test/{id}", method = get, производить = "application/json") public webResponse <?> GetNoapi () {webResponse <?> Response = webResponse.getSuccessResponse (null); ответный ответ; }}3. Подробная конфигурация API Swagger API
Но у вас обязательно будет несколько вопросов, когда вы увидите это:
Первый вопрос: нет буквального описания результата возврата и параметров запроса. Можно ли это настроить?
Второй вопрос: этот параметр запроса должен быть непосредственно отражен на основе объекта, но не требуется каждая свойство объекта, и значение параметра может не соответствовать нашим потребностям. Можно ли это настроить?
Ответ, безусловно, в порядке. Теперь давайте решим эти две проблемы и посмотрим напрямую на код конфигурации:
пакет com.pandy.blog.rest; import com.pandy.blog.dto.webresponse; import com.pandy.blog.po.article; импорт com.pandy.blog.service.articleservice; import io.swager.annotations.apiimplicitparam; import.swager.annotation.apiimplications.apiimplicitparam; import.swager.annotation.apiimplationparams. io.swagger.annotations.apioperation; импорт io.swagger.annotations.apresponse; импорт io.swagger.annotations.Apiresponse; импорт io.swager.annotations.Apiresponse; импорт io.swager.annotations.Apiresponse; импорт org.spramework.beans.factory.Annotation org.springframework.context.annotation.profile; import org.springframework.web.bind.nantation.pathviable; импорт org.springframework.web.bindtation.Requestbody; import.springframework.web.bindtation.Requestmappy; org.springframework.web.bind.annotation.restcontroller; import java.util.hashmap; import java.util.list; import java.util.map; импорт static org.springframework.web.bind.annotation.requestmethod.delete; импорт stati org.springframework.web.bind.annotation.requestmethod.get; import static org.springframework.web.bind.annotation.requestmethod.post; импорт статический org.springframework.web.bindtation.requestmethod.put; Articlerestcontroller {@autowired private articleservice articleservice; @RequestMapping(value = "/article", method = POST, produces = "application/json") @ApiOperation(value = "Add article", notes = "Add new article", tags = "Article",httpMethod = "POST") @ApiImplicitParams({ @ApiImplicitParam(name = "title", value = "Article title", required = true, dataType = "String"), @Apiimplicitparam (name = "summary", value = "summary", required = true, datatype = "string"), @apiimplicitparam (name = "value =" publish status ", обязательно = true, dataType =" Integer ")}) @Apiresses ({@Apresponse (code = 200, messceps = webrespresses webrespresse webrespress webrespresse webressonse webressonse webressess public webresponse <map <string, object >> savearticle (статья @requestbody статья) {articleservice.savearticle (статья); Map <string, object> ret = new Hashmap <> (); ret.put ("id", article.getid ()); Webresponse <map <string, object >> response = webresponse.getSuccessResponse (ret); ответный ответ; } @ApiOperation(value = "Delete article", notes = "Delete article by ID", tags = "Article",httpMethod = "DELETE") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "Article ID", required = true, dataType = "Long") }) @RequestMapping(value = "/{id}",method = DELETE, PREALCES = "Application/JSON") Public weBResponse <?> DeleteArticle (@Pathvariable Long Id) {статья = статья = articleservice.getbyid (id); article.setStatus (-1); articleservice.savearticle (статья); вернуть webResponse.getSuccessResponse (новый HashMap <> ()); } @Apioperation (value = "Получить список статьи", notes = "Полный запрос в соответствии с заголовком", tags = "article", httpmethod = "get") @apiimplicitarparams ({@apiimplicitparam (name = "title", value = "start atember watress = false = string") @ApiImplize (value valize vallize ", vallize", "value", vallize ", vallize", valize ", valueSize", value ", valize", value ", value vallize" = value vallize "= value". Статьи на страницу «, обязательно = false, dataType =" Integer "), @apiimplicitparam (name =" pagenum ", value =" № PagePage ", обязательный = false, datatype =" integer ")}) @Requestmapping (value ="/article/list ", method = get, производит =" Приложение/Json ") public weBresponse <? PageSize, Integer Pagenum) {if (pagesize == null) {pageSize = 10; } if (pagenum == null) {pagenum = 1; } int offset = (pagenum - 1) * pageSize; Список <статья> artiks = articleservice.getarticlics (заголовок, 1L, смещение, страницы размером); вернуть webResponse.getSuccessResponse (статьи); } @Apioperation (value = "Обновление статьи", notes = "Обновление содержимого статьи", tags = "article", httpmethod = "put") @apiimplicitalparams ({@apiimplicitparam (name = "id", value = "article id", обязательный = true, dataType = "long"), @ApiimplictAltial datatype = "string"), @apiimplicitarparam (name = "summary", value = "summary", required = false, datatype = "string"), @apiimplicitarparam (name = ", value =" publish status ", обязательный = false, datatype =" integer ")} @requestmapping (value ="/й идентификатор ", IDESEES", IDESEES ", IDESEES", IDES «Приложение/JSON») Public webResponse <?> UpdateArticle (@pathvarible long id,@article article article) {article.setid (id); iklicservice.updatearticle (статья); вернуть webResponse.getSuccessResponse (новый HashMap <> ()); }}Давайте объясним конкретные функции нескольких аннотаций и связанных с ними атрибутов в коде:
@Apioperation, вся конфигурация атрибута интерфейса:
Значение: Описание интерфейса, отображаемое в списке интерфейса.
Примечания: Подробное описание интерфейса, отображаемое на странице сведений о интерфейсе.
Теги: тег интерфейса. Интерфейс с тем же тегом будет отображаться под страницей вкладки.
httpmethod: поддерживаемый метод HTTP.
@ApiimplicitParams, контейнер для @apiimplicitparam, может содержать несколько аннотаций @ApiimplIticalParam
@Apiimplicitparam, запрос параметров конфигурации атрибута:
Имя: имя параметра
Значение: Описание параметра
Требуется: это необходимо
DataType: тип данных
@Apiresponses, @Apiresponse Container, может содержать несколько аннотаций @Apiresponse
@Apiresponse, верните конфигурацию атрибута результата:
Код: возвращает кодирование результата.
Сообщение: возвращает описание результата.
Ответ: возвращает соответствующий класс результата.
После завершения вышеуказанной конфигурации давайте посмотрим на эффект страницы:
СПИСОК СТРАНИЦА:
Как видите, интерфейсы теперь расположены под тегом статьи, а также есть инструкции для нашей конфигурации за интерфейсом. Давайте посмотрим на страницу сведений интерфейса «post /rest /article»:
Картинка слишком велика, и только отображение атрибута заголовка перехватывается, а другие параметры похожи. На странице мы видим, что есть инструкции для параметров запроса, но это не тот эффект, который мы ожидали. Если наши параметры являются просто простыми типами, этот метод должен быть в порядке, но проблема в том, что наши параметры запроса являются объектом, так как их настроить? Это включает в себя две другие аннотации: @apimodel и @apimodelproperty. Сначала посмотрим на код, а затем объясним его, что легче понять:
@Apimodel (value = "ocyation", description = "Добавить и обновить статью Описание") Общественный класс статья {@id @GeneratedValue @ApimodelProperty (name = "id", value = "ID статьи", обязательный = false, пример = "1") private Long Id; @Apimodelproperty (name = "title", value = "start witn", required = true, arvess = "test article") заголовок частной строки; @ApimodelProperty (name = "summary", value = "Сводка статьи", обязательный = true, пример = "Сводка тестовой статьи") Приватная строка; @Apimodelproperty (hidden = true) частная дата Create -Time; @Apimodelproperty (hidden = true) частная дата Publictime; @Apimodelproperty (hidden = true) частная дата обновления; @Apimodelproperty (hidden = true) private long userid; @Apimodelproperty (name = "status", value = "Статус выпуска статьи", обязательный = true, arvess = "1") частное целочисленное статус; @Apimodelproperty (name = "type", value = "article Category", обязательный = true, anvess = "1") private Integer Type;}@Apimodel - это конфигурация свойств всего класса:
Значение: описание класса
Описание: подробное описание
@Apimodelproperty - это конфигурация свойств каждого поля подробно:
Имя: имя поля
Значение: Описание поля
Требуется: это необходимо
Пример: пример значения
скрытый: отображать ли
После завершения вышеуказанной конфигурации давайте посмотрим на эффект:
Теперь мы видим, что описание поля было показано, и значение поля в примере также стало соответствующим значением свойства примера, которое мы настроили. Таким образом, создается полный документ API, и документ тесно связан с кодом, а не двумя изолированными частями. Кроме того, мы также можем легко проверить его через этот документ. Нам просто нужно щелкнуть на желтое поле «Значение», и содержимое внутри будет автоматически скопировано в соответствующее поле значения статьи, а затем нажмите «Попробуйте его», чтобы инициировать HTTP -запрос.
После нажатия попробуйте это, мы видим возвращенный результат:
Операция все еще очень удобна. По сравнению с Junit и Postman тестирование через Swagger более удобно. Конечно, тестирование Swagger не может заменить модульные тестирование, но оно все еще оказывает очень важное влияние на совместную отладку.
4. Резюме
В целом, конфигурация Swagger относительно проста, а способность Swagger автоматически генерировать документы действительно сэкономила нам много работы и оказала большую помощь для последующего обслуживания. Кроме того, Swagger может автоматически генерировать тестовые данные для нас в соответствии с конфигурацией и предоставить соответствующие методы HTTP, что также помогает для нашей работы самопроверка и совместной отладки. Поэтому я все еще рекомендую вам использовать Swagger в ежедневном развитии, что должно помочь вам в определенной степени повысить эффективность работы вашей работы. Наконец, позвольте мне оставить вопрос для вас, чтобы подумать, то есть документ можно получить непосредственно через страницу, поэтому мы не можем подвергать интерфейс непосредственно в производственную среду, особенно системы, которые необходимо предоставлять внешние услуги. Итак, как мы можем отключить эту функцию в производственном процессе? Есть много методов, вы можете попробовать сами.
Выше приведено фактическое борьбу с программным проектом Spring Boot Integrated Swagger2, представленный вам редактором. Я надеюсь, что это будет полезно для вас. Если у вас есть какие -либо вопросы, пожалуйста, оставьте мне сообщение, и редактор ответит вам вовремя. Большое спасибо за вашу поддержку сайту wulin.com!