Swagger 之 Spring REST示例

现在,天REST微服务已经得到了很多的势头。同时,实际的REST规范并未建议任何标准方法来记录我们将要公开的REST API(例如WSDL for SOAP)。结果,每个人都以自己的方式记录自己的API,从而导致通用结构中的空白,所有这些都可以轻松地遵循,理解和使用。我们需要一个通用的模式和工具。

Swagger(得到了Baidu,IBM,Microsoft等公司的支持)在填补通用文档样式方面做了同样的工作。在本教程中,我们将学习使用Swagger通过swagger 2注解生成REST API文档

目录

Swagger 
项目结构和技术堆栈
是什么创建REST API 
Swagger2配置
Swagger2注解
演示

昂首阔步

Swagger(现为“ Open API Initiative”)是一种规范和框架,用于使用所有人都可以理解的通用语言来描述REST API。还有其他一些 popular 的框架,例如RAML,Summation等。但是考虑到它的功能和在开发者社区中的接受程度,Swagger在这个时候是最受欢迎的。

它提供了人类可读和机器可读的文档格式。它同时提供JSON和UI支持。JSON可以用作机器可读格式,Swagger-UI并且用于可视化显示,人类只需浏览api文档即可轻松理解。

项目结构与技术栈

项目的文件夹结构为:

Swagger2项目结构
Swagger2项目结构

在本演示中,我们将使用以下技术。

  1. Eclipse作为IDE
  2. Maven作为构建工具
  3. Spring Boot作为应用程序框架
  4. Spring Rest作为REST API框架
  5. Swagger2作为REST文档框架
  6. Java 1.8

创建REST API

我们将首先创建一些REST API,这些API将用于展示Swagger文档功能。我们将使用Spring引导样式公开剩余的API,以缩短开发时间。

  1. 创建一个Spring Boot 项目初始化Spring Boot门户网站WebRest RepositoriesActuator依赖性。给出其他Maven GAV坐标并下载项目。该屏幕如下所示:
    Spring Boot REST项目生成

    将项目解压缩并将其作为现有的maven项目导入Eclipse。在此步骤中,将从maven存储库下载所有必需的依赖项。mvn clean install在此步骤中执行全新操作,以便正确下载所有与Spring Boot相关的工件。

  2. 打开application.properties并添加以下属性。这将在/swagger2-demo上下文路径中启动应用程序 。
    server.contextPath=/swagger2-demo
  3. 添加一个REST控制器Swagger2DemoRestController,它将在Student实体上提供基于REST的基本功能。Swagger2DemoRestController.java
    package com.example.springbootswagger2.controller;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import com.example.springbootswagger2.model.Student;
    @RestController
    public class Swagger2DemoRestController {
        List<Student> students = new ArrayList<Student>();
        {
            students.add(new Student("Sajal", "IV", "India"));
            students.add(new Student("Lokesh", "V", "India"));
            students.add(new Student("Kajal", "III", "USA"));
            students.add(new Student("Sukesh", "VI", "USA"));
        }
        @RequestMapping(value = "/getStudents")
        public List<Student> getStudents() {
            return students;
        }
        @RequestMapping(value = "/getStudent/{name}")
        public Student getStudent(@PathVariable(value = "name") String name) {
            return students.stream().filter(x -> x.getName().equalsIgnoreCase(name)).collect(Collectors.toList()).get(0);
        }
        @RequestMapping(value = "/getStudentByCountry/{country}")
        public List<Student> getStudentByCountry(@PathVariable(value = "country") String country) {
            System.out.println("Searching Student in country : " + country);
            List<Student> studentsByCountry = students.stream().filter(x -> x.getCountry().equalsIgnoreCase(country))
                    .collect(Collectors.toList());
            System.out.println(studentsByCountry);
            return studentsByCountry;
        }
        @RequestMapping(value = "/getStudentByClass/{cls}")
        public List<Student> getStudentByClass(@PathVariable(value = "cls") String cls) {
            return students.stream().filter(x -> x.getCls().equalsIgnoreCase(cls)).collect(Collectors.toList());
        }
    }

    Student.java

    package com.example.springbootswagger2.model;
    public class Student {
        
        private String name;
        private String cls;
        private String country;
        public Student(String name, String cls, String country) {
            super();
            this.name = name;
            this.cls = cls;
            this.country = country;
        }
        public String getName() {
            return name;
        }
        public String getCls() {
            return cls;
        }
        public String getCountry() {
            return country;
        }
        @Override
        public String toString() {
            return "Student [name=" + name + ", cls=" + cls + ", country=" + country + "]";
        }
    }
  4. 作为Spring Boot 应用程序启动该应用程序。测试几个REST端点,以检查它们是否工作正常:
    • http:// localhost:8080 / swagger2-demo / getStudents
    • http:// localhost:8080 / swagger2-demo / getStudent / sajal
    • http:// localhost:8080 / swagger2-demo / getStudentByCountry / india
    • http:// localhost:8080 / swagger2-demo / getStudentByClass / v

Swagger2配置

我们的REST API已准备就绪。现在将swagger 2支持添加到project.ff

添加Swagger2 Maven依赖项

打开spring-boot-swagger2项目的pom.xml文件,并在下面添加两个与swagger相关的依赖项,即springfox-swagger2springfox-swagger-ui

<dependency>
       <groupId>io.springfox</groupId>
       <artifactId>springfox-swagger2</artifactId>
       <version>2.6.1</version>
   </dependency>
   <dependency>
       <groupId>io.springfox</groupId>
       <artifactId>springfox-swagger-ui</artifactId>
       <version>2.6.1</version>
   </dependency>
实际上,swaggerAPI有几个变种,并且维护在不同的工件中。今天,我们将使用,springfox因为该版本可以很好地适应任何基于spring的配置。我们也可以轻松尝试其他配置,并且应该提供相同的功能-无需更改/只需进行少许更改。

添加Swagger2配置

在代码库中添加以下配置。为了帮助您理解配置,我添加了嵌入式注解。

package com.example.springbootswagger2.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.google.common.base.Predicates;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class Swagger2UiConfiguration extends WebMvcConfigurerAdapter
{
    @Bean
    public Docket api() {
        // @formatter:off
        //Register the controllers to swagger
        //Also it is configuring the Swagger Docket
        return new Docket(DocumentationType.SWAGGER_2).select()
                // .apis(RequestHandlerSelectors.any())
                .apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.boot")))
                // .paths(PathSelectors.any())
                // .paths(PathSelectors.ant("/swagger2-demo"))
                .build();
        // @formatter:on
    }
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry)
    {
        //enabling swagger-ui part for visual documentation
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

验证Swagger2 JSON格式文档

执行maven并启动服务器。打开链接http:// localhost:8080 / swagger2-demo / v2 / api-docs,它应该以JSON格式提供整个文档。这并不是那么容易阅读和理解,实际上Swagger已经提供了将其用于其他系统中的功能,例如如今 popular 的API管理工具,它提供了API网关,API缓存,API文档等功能。

JSON文档

验证Swagger2 UI文档

打开http:// localhost:8080 / swagger2-demo / swagger-ui.html在浏览器中查看Swagger UI文档。

没有注解的Swagger2 UI文档
没有注解的Swagger2 UI文档

Swagger2注解

默认生成的API文档很好,但是缺少详细的API级别信息。Swagger提供了一些注解,可以将这些详细信息添加到API。例如

  1. @Api –我们可以将此注解添加到控制器,以添加有关控制器的基本信息。
    @Api(value = "Swagger2DemoRestController", description = "REST APIs related to Student Entity!!!!")
    @RestController
    public class Swagger2DemoRestController {
        ...
    }
  2. @ApiOperation and @ApiResponses–我们可以将这些注解添加到控制器中的任何rest方法,以添加与该方法有关的基本信息。例如
    @ApiOperation(value = "Get list of Students in the System ", response = Iterable.class, tags = "getStudents")
    @ApiResponses(value = {
                @ApiResponse(code = 200, message = "Success|OK"),
                @ApiResponse(code = 401, message = "not authorized!"),
                @ApiResponse(code = 403, message = "forbidden!!!"),
                @ApiResponse(code = 404, message = "not found!!!") })
    @RequestMapping(value = "/getStudents")
    public List<Student> getStudents() {
        return students;
    }

    在这里,我们可以添加tags方法以在中添加一些分组swagger-ui

  3. @ApiModelProperty–在Model属性中使用此注解可为该Model属性的Swagger输出添加一些描述。例如
    @ApiModelProperty(notes = "Name of the Student",name="name",required=true,value="test name")
    private String name;

添加swagger2注解后的Controller和Model类代码。

Swagger2DemoRestController.java

package com.example.springbootswagger2.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.springbootswagger2.model.Student;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
@Api(value = "Swagger2DemoRestController", description = "REST Apis related to Student Entity!!!!")
@RestController
public class Swagger2DemoRestController {
    List<Student> students = new ArrayList<Student>();
    {
        students.add(new Student("Sajal", "IV", "India"));
        students.add(new Student("Lokesh", "V", "India"));
        students.add(new Student("Kajal", "III", "USA"));
        students.add(new Student("Sukesh", "VI", "USA"));
    }
    @ApiOperation(value = "Get list of Students in the System ", response = Iterable.class, tags = "getStudents")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Suceess|OK"),
            @ApiResponse(code = 401, message = "not authorized!"),
            @ApiResponse(code = 403, message = "forbidden!!!"),
            @ApiResponse(code = 404, message = "not found!!!") })
    @RequestMapping(value = "/getStudents")
    public List<Student> getStudents() {
        return students;
    }
    @ApiOperation(value = "Get specific Student in the System ", response = Student.class, tags = "getStudent")
    @RequestMapping(value = "/getStudent/{name}")
    public Student getStudent(@PathVariable(value = "name") String name) {
        return students.stream().filter(x -> x.getName().equalsIgnoreCase(name)).collect(Collectors.toList()).get(0);
    }
    @ApiOperation(value = "Get specific Student By Country in the System ", response = Student.class, tags = "getStudentByCountry")
    @RequestMapping(value = "/getStudentByCountry/{country}")
    public List<Student> getStudentByCountry(@PathVariable(value = "country") String country) {
        System.out.println("Searching Student in country : " + country);
        List<Student> studentsByCountry = students.stream().filter(x -> x.getCountry().equalsIgnoreCase(country))
                .collect(Collectors.toList());
        System.out.println(studentsByCountry);
        return studentsByCountry;
    }
    // @ApiOperation(value = "Get specific Student By Class in the System ",response = Student.class,tags="getStudentByClass")
    @RequestMapping(value = "/getStudentByClass/{cls}")
    public List<Student> getStudentByClass(@PathVariable(value = "cls") String cls) {
        return students.stream().filter(x -> x.getCls().equalsIgnoreCase(cls)).collect(Collectors.toList());
    }
}

Student.java

package com.example.springbootswagger2.model;
import io.swagger.annotations.ApiModelProperty;
public class Student
{
    @ApiModelProperty(notes = "Name of the Student",name="name",required=true,value="test name")
    private String name;
    @ApiModelProperty(notes = "Class of the Student",name="cls",required=true,value="test class")
    private String cls;
    @ApiModelProperty(notes = "Country of the Student",name="country",required=true,value="test country")
    private String country;
    public Student(String name, String cls, String country) {
        super();
        this.name = name;
        this.cls = cls;
        this.country = country;
    }
    public String getName() {
        return name;
    }
    public String getCls() {
        return cls;
    }
    public String getCountry() {
        return country;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", cls=" + cls + ", country=" + country + "]";
    }
}

Demo

现在,当我们的REST API得到正确注解时,让我们看一下最终输出。打开http:// localhost:8080 / swagger2-demo / swagger-ui.html在浏览器中查看Swagger ui文档。

最终Swagger2 REST API输出
最终Swagger2 REST API输出

这就是通过Spring Boot应用程序使用swagger2创建REST API文档的全部。如果您有任何疑问,请在评论区留言,我会一一解答。

学习愉快!

saigon has written 1440 articles

Leave a Reply