Серия Springboot (16) Вы действительно понимаете документацию Swagger?

Spring Boot

Привет, мир :) Поиск WeChat " Программист Аранг" Подписаться.подобноПосмотрите еще раз, сила безгранична.

эта статьяGitHub.com/Ниу Мух/Java…а такжеБлог программиста АрангаБыл включен, есть много точек знаний и серии статей.

предисловие

В настоящее время в области использования JavaSpringbootСоздание микросервисов относительно популярно, и при создании микросервисов большинство из нас предпочитает раскрывать один из них.REST APIдля вызова. Или компания принимает модель разработки, которая разделяет фронтенд и бэкенд, так что фронтенд и бэкэнд разрабатываются совершенно разными инженерами. Будь то микросервисы или такого рода разработка с разделением интерфейса и сервера, поддерживайте полное и своевременное обновление.REST APIДокументация значительно повысит эффективность нашей работы. Однако традиционный метод обновления документа (такой как ручное написание) трудно обеспечить своевременность документа, и он часто приходит в негодность и теряет свой надлежащий смысл. Следовательно, необходимо выбрать новый способ ведения документации по API, о чем и пойдет речь в этой статье.

1. Введение в спецификацию OpenAPI

OpenAPI SpecificationСокращенно OAS, также известная на китайском языке.OpenAPIспецификация описания, использованиеOpenAPIДокумент может описывать весь API, который определяет набор подходящих универсальных, не зависящих от языкаREST APIСпецификация описания, такая как спецификация пути API, спецификация метода запроса, спецификация параметров запроса, спецификация формата возврата и другая связанная информация, чтобы люди и компьютеры могли понимать и использовать функции службы без доступа к исходному коду.

НижеOpenAPIСпецификация дизайна API, предложенная в спецификации, спецификация дизайна основного пути.

https://api.example.com/v1/users?role=admin&status=active
\________________________/\____/ \______________________/
         server URL       endpoint    query parameters
                            path

Также существуют спецификации по оформлению параметров, которые могут быть следующими:

OpenAPIНорма намного больше, чем это, в настоящее времяOpenAPIПоследняя версия спецификации — 3.0.2, если вы хотите узнать большеOpenAPIТехнические характеристики доступны по ссылке ниже.OpenAPI Specification (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md)

2. Введение в Swagger

Многие люди думаютSwaggerЭто просто фреймворк для генерации интерфейсных документов, но это не так. Сваггер - этоOpenAPI Specification(OAS, также известная как спецификация OpenAPI на китайском языке) — это набор инструментов с открытым исходным кодом. Это может помочь вам предоставить соответствующие решения для всего цикла разработки API, от проектирования API до вывода документа API, тестирования API, окончательного развертывания API и т. д. Это огромный проект. Swagger не только бесплатен, но и имеет открытый исходный код.Являетесь ли вы корпоративным пользователем или индивидуальным игроком, вы можете использовать решения, предоставляемые Swagger, для создания потрясающихREST API.

У Swagger есть несколько основных продуктов.

  • Swagger Editor– Браузерный редактор для спецификации Open API.
  • Swagger UI– Инструмент для представления спецификаций OpenAPI в виде интерактивных онлайн-документов.
  • Swagger Codegen– Инструмент для генерации кода вызова из OpenAPI.

Если вы хотите узнать больше информации, вы можете посетить официальный сайт Swagger.swagger.io.

3. Введение в Springfox

Из-за популярности фреймворка Spring в Java иностранцу по имени Маррти Питту пришла в голову идея добавить описания интерфейса в SpringMVC, поэтому он создал проект, соответствующий спецификации OpenAPI (OAS), названныйswagger-springmvc, этот проект позволяет проектам Spring автоматически генерировать документы OpenAPI в формате JSON. Этот фреймворк также имитирует привычки разработки проектов Spring, используя аннотации для настройки информации.

Позже проект перерос вSpringfox, а позже распространился наspringfox-swagger2, чтобы документ API в формате JSON был лучше представлен, снова появилсяspringfox-swagger-uiИспользуется для демонстрации и тестирования сгенерированного OpenAPI. Springfox-swagger-ui здесь на самом деле является Swagger-ui, описанным выше, но он упакован в пакет jar с помощью webjar и представлен maven.

Как упоминалось выше, Springfox-swagger2 также настраивает информацию через аннотации, так как же это используется? Ниже перечислены некоторые часто используемые аннотации, которые будут использоваться в Swagger интеграции Springboot ниже.

аннотация Пример описывать
@ApiModel @ApiModel (значение = «Объект пользователя») описать объект сущности
@ApiModelProperty @ApiModelProperty (значение = «Идентификатор пользователя», обязательное = true, пример = «1000») Опишите атрибутивную информацию, выполните описание, если оно требуется, и приведите пример
@Api @Api(value = "API операций пользователя (v1)", tags = "Интерфейс операций пользователя") Используется в классах интерфейса для добавления описаний в классы интерфейса.
@ApiOperation @ApiOperation (значение = «Добавить пользователя») Описать метод или интерфейс класса
@ApiParam @ApiParam (значение = «имя пользователя», обязательно = истина) описать один параметр

Чтобы узнать больше о Springfox, посетите официальный сайт Springfox.

Springfox Reference Documentation (http://springfox.github.io)

4. Springboot интегрирует Swagger

В настоящее время платформа Springboot является очень популярной платформой микросервисов, в рамках которой мы часто напрямую предоставляемREST APIиз. Если документации по REST API нет, у пользователя будет головная боль. Но не волнуйтесь, как упоминалось выше, иностранец по имени Маррти Питт создал проект, который превратился в Springfox, который может легко предоставить спецификацию OpenAPI и поддержку документов в формате JSON. И он расширяет springfox-swagger-ui для отображения страницы.

Следует отметить, что так называемый Swagger, используемый здесь, на самом деле не то же самое, что настоящий Swagger, здесь используется реализация Swagger, предоставленная Springfox. Все они представляют собой сборки API, основанные на спецификации OpenAPI. Следовательно, Swagger-ui также можно использовать для рендеринга страниц API.

4.1 Создание проекта

Как создать проект Springboot здесь не упоминается, вы можете прямо изОфициальный источник SpringbootЗагрузите стандартный проект, вы также можете использовать идею, чтобы быстро создать проект Springboot, или вы можете скопировать проект Springboot, чтобы протестировать его, Короче говоря, есть много способов на выбор.

Ниже показано, как использовать swagger2 в проекте Springboot.

4.2. Введение зависимостей

В основном это введение springfox-swagger2, который может генерировать документы интерфейса OpenAPI в формате JSON с помощью аннотаций, а затем, поскольку Springfox должен полагаться на jackson, он представлен. springfox-swagger-ui может отображать сгенерированную документацию по интерфейсу OpenAPI в виде страницы. Внедрение Lombok позволяет генерировать методы get/set для классов сущностей с помощью аннотаций.

<dependencies> 
	<!-- Spring Boot web 开发整合 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <artifactId>spring-boot-starter-json</artifactId>
                <groupId>org.springframework.boot</groupId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- 引入swagger2的依赖-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>
    
    <!-- jackson相关依赖 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.5.4</version>
    </dependency>

    <!-- Lombok 工具 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

4.3 Настройка Springfox-swagger

Конфигурация Springfox-swagger заключена в Docket, а метод apiInfo в Docket может передавать в описании информацию об интерфейсе в целом. Метод apis может указать конкретный путь к сканируемому пакету. Добавьте @Configuration в класс, чтобы объявить, что это класс конфигурации, и, наконец, используйте @EnableSwagger2, чтобы включить Springfox-swagger2.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * <p>
 * Springfox-swagger2 配置
 *
 * @Author niujinpeng
 * @Date 2019/11/19 23:17
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("net.codingme.boot.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("未读代码 API")
                .description("公众号:未读代码(weidudaima) springboot-swagger2 在线借口文档")
                .termsOfServiceUrl("https://www.codingme.net")
                .contact("达西呀")
                .version("1.0")
                .build();
    }
}

4.4 Написание кода

В статье не будет перечисляться весь код по порядку, в этом нет особого смысла, поэтому будет размещен только основной код, полный код будет загружен на Github, а ссылка на Github будет прикреплена внизу статья.

класс сущности параметраUser.java,использовать@ApiModelа также @ApiModelPropertyЧтобы описать объект параметра, используйте @NotNullДля проверки данных используйте@DataАвтоматически создавать методы получения/установки для классов сущностей параметров.

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * <p>
 * 用户实体类
 *
 * @Author niujinpeng
 * @Date 2018/12/19 17:13
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "用户对象")
public class User {

    /**
     * 用户ID
     *
     * @Id 主键
     * @GeneratedValue 自增主键
     */
    @NotNull(message = "用户 ID 不能为空")
    @ApiModelProperty(value = "用户ID", required = true, example = "1000")
    private Integer id;

    /**
     * 用户名
     */
    @NotNull(message = "用户名不能为空")
    @ApiModelProperty(value = "用户名", required = true)
    private String username;
    /**
     * 密码
     */
    @NotNull(message = "密码不能为空")
    @ApiModelProperty(value = "用户密码", required = true)
    private String password;
    /**
     * 年龄
     */
    @ApiModelProperty(value = "用户年龄", example = "18")
    private Integer age;
    /**
     * 生日
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
    @ApiModelProperty(value = "用户生日")
    private Date birthday;
    /**
     * 技能
     */
    @ApiModelProperty(value = "用户技能")
    private String skills;
}

Напишите слой контроллера, используйте@ApiЧтобы описать класс интерфейса, используйте@ApiOperationДля описания интерфейса используйте@ApiParamОписывает параметры интерфейса. В коде добавлены оба интерфейса для запроса информации о пользователе tags = "用户查询"tag, чтобы эти два метода были разделены на общую группу тегов при создании документа интерфейса Swagger.

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import net.codingme.boot.domain.Response;
import net.codingme.boot.domain.User;
import net.codingme.boot.enums.ResponseEnum;
import net.codingme.boot.utils.ResponseUtill;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 用户操作
 *
 * @Author niujinpeng
 * @Date 2019/11/19 23:17
 */

@Slf4j
@RestController(value = "/v1")
@Api(value = "用户操作 API(v1)", tags = "用户操作接口")
public class UserController {

    @ApiOperation(value = "新增用户")
    @PostMapping(value = "/user")
    public Response create(@Valid User user, BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            String message = bindingResult.getFieldError().getDefaultMessage();
            log.info(message);
            return ResponseUtill.error(ResponseEnum.ERROR.getCode(), message);
        } else {
            // 新增用户信息 do something
            return ResponseUtill.success("用户[" + user.getUsername() + "]信息已新增");
        }
    }

    @ApiOperation(value = "删除用户")
    @DeleteMapping(value = "/user/{username}")
    public Response delete(@PathVariable("username")
                           @ApiParam(value = "用户名", required = true) String name) throws Exception {
        // 删除用户信息 do something
        return ResponseUtill.success("用户[" + name + "]信息已删除");
    }

    @ApiOperation(value = "修改用户")
    @PutMapping(value = "/user")
    public Response update(@Valid User user, BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            String message = bindingResult.getFieldError().getDefaultMessage();
            log.info(message);
            return ResponseUtill.error(ResponseEnum.ERROR.getCode(), message);
        } else {
            String username = user.getUsername();
            return ResponseUtill.success("用户[" + username + "]信息已修改");
        }
    }

    @ApiOperation(value = "获取单个用户信息", tags = "用户查询")
    @GetMapping(value = "/user/{username}")
    public Response get(@PathVariable("username")
                        @NotNull(message = "用户名称不能为空")
                        @ApiParam(value = "用户名", required = true) String username) throws Exception {
        // 查询用户信息 do something
        User user = new User();
        user.setId(10000);
        user.setUsername(username);
        user.setAge(99);
        user.setSkills("cnp");
        return ResponseUtill.success(user);
    }

    @ApiOperation(value = "获取用户列表", tags = "用户查询")
    @GetMapping(value = "/user")
    public Response selectAll() throws Exception {
        // 查询用户信息列表 do something
        User user = new User();
        user.setId(10000);
        user.setUsername("未读代码");
        user.setAge(99);
        user.setSkills("cnp");
        List<User> userList = new ArrayList<>();
        userList.add(user);
        return ResponseUtill.success(userList);
    }
}

Наконец, чтобы сделать код более совместимым и удобным для использования, используйте унифицированный класс для ответа интерфейса.

@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "响应信息")
public class Response {
    /**
     * 响应码
     */
    @ApiModelProperty(value = "响应码")
    private String code;
    /**
     * 响应信息
     */
    @ApiModelProperty(value = "响应信息")
    private String message;

    /**
     * 响应数据
     */
    @ApiModelProperty(value = "响应数据")
    private Collection content;
}

4.5. Выполнить доступ

Запустите проект Springboog напрямую, и вы увидите пути доступа к каждому интерфейсу, отсканированные выводом консоли, включая/2/api-docs.

Это также путь доступа к описанию JSON сгенерированной спецификации OpenAPI, вы можете увидеть доступ.

Поскольку мы также представили пакет springfox-swagger-ui, когда представили зависимости выше, мы также можем получить доступ к документации на странице API. Путь доступа — /swagger-ui.html, и результат посещения можно увидеть на следующем рисунке.

Вы также можете видеть, что два метода пользовательского запроса будут сгруппированы вместе, потому что аннотации этих двух методов используют один и тот же атрибут тега.

4.7. Вызов теста

springfox-swagger-ui не только генерирует документацию по API, но и предоставляет функцию вызова и тестирования. Ниже приведен процесс тестирования получения информации об одном пользователе на странице.

  1. Нажмите на интерфейс [/user/{username}], чтобы получить информацию об отдельных пользователях.
  2. нажмите**Try it out** Перейдите на страницу тестового переноса.
  3. Введите параметры и нажмитеExecuteСиняя кнопка выполняет вызов.
  4. Посмотреть информацию о возврате.

Ниже приведен скриншот ответа во время тестирования.

5. Распространенные ошибки

Если при запуске программы вы часто сталкиваетесь с ошибками, подобными приведенным ниже.

java.lang.NumberFormatException: For input string: ""
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[na:1.8.0_111]
	at java.lang.Long.parseLong(Long.java:601) ~[na:1.8.0_111]
	at java.lang.Long.valueOf(Long.java:803) ~[na:1.8.0_111]
	at io.swagger.models.parameters.AbstractSerializableParameter.getExample(AbstractSerializableParameter.java:412) ~[swagger-models-1.5.20.jar:1.5.20]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_111]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_111]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:536) [jackson-databind-2.5.4.jar:2.5.4]
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666) [jackson-databind-2.5.4.jar:2.5.4]
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156) [jackson-databind-2.5.4.jar:2.5.4]
	at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:113) [jackson-databind-2.5.4.jar:2.5.4]

то вам нужно проверить с помощью@ApiModelPropertyВ атрибуте, который аннотирован, и тип поля является числовым типом,@ApiModelPropertyУстановлено ли в аннотации значение примера, если нет, его необходимо установить, как показано ниже.

@NotNull(message = "用户 ID 不能为空")
@ApiModelProperty(value = "用户ID", required = true, example = "1000")
private Integer id;

Код в тексте загружен на https://github.com/niumoo/springboot

Справочная документация

Привет, мир :) Я Аланг, передовой специалист по техническим инструментам, серьезно пишу статьи.

Нравятся комментариивсе ониталант, не только выглядит красивым и симпатичным, но и красиво говорит.

Статья постоянно обновляется, вы можете искать в WeChat " Программист Аранг"или посетите"Блог программиста Аранга"Читал в первый раз.

Ответить【материал】 Я подготовил различные серии знаний и обязательных к просмотру книг.

эта статьяGitHub.com/Ниу Мух/Java…Он был включен, есть много знаний и серии статей, добро пожаловать в Star.