前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Security技术栈开发企业级认证与授权(七)使用Swagger自动生成API文档

Spring Security技术栈开发企业级认证与授权(七)使用Swagger自动生成API文档

作者头像
itlemon
发布2020-04-03 14:22:08
6420
发布2020-04-03 14:22:08
举报
文章被收录于专栏:深入理解Java深入理解Java

由于Spring Boot能够快速开发、便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API。而我们构建RESTful API的目的通常都是由于多终端的原因,这些终端会共用很多底层业务逻辑,因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端。本文将介绍RESTful API的重磅好伙伴Swagger2,它可以轻松的整合到Spring Boot中,并与Spring MVC程序配合组织出强大RESTful API文档。它既可以减少我们创建文档的工作量,同时说明内容又整合入实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API。此引用来自程序猿DD

Spring Boot中应用中Swagger2构建强大的API文档十分方便,只需要在项目中添加Swagger2的依赖,然后在Spring Boot的启动的main方法的类上加上注解@EnableSwagger2就可以完成构建工作。效果图如下:

这里写图片描述
这里写图片描述

在图中可以看出,我自定义的Controller只有FileController,而其他的都是Spring Boot的一些控制器,而这些API文档往往是我们不需要的,所以,仅仅使用Swagger2的默认方式显然是不能满足我们的需求的,所以,我们需要自定义Swagger文档。

添加依赖
代码语言:javascript
复制
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.8.0</version>
</dependency>

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.8.0</version>
</dependency>
配置Swagger

我们写一个Swagger的配置类,添加上@Configuration注解方便被Spring Boot配置,添加@EnableSwagger2注解启动Swagger文档构建能力。需要注意的是,一般配置类可以放在Spring Boot启动类的同一个包里,如果没有放,那么请在Spring Boot的启动类上添加包扫描注解@ComponentScan(basePackages = {"com.lemon.security"}),然后配置类可以放在任何的这个包的子包下面。

代码语言:javascript
复制
package com.lemon.security.web.config;

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.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * @author lemon
 * @date 2018/4/3 下午1:01
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket createRestfulApiDocs() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.lemon.security.web.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("自定义RESTful API文档")
                .description("更多内容请关注CSDN博客:https://blog.csdn.net/Lammonpeter")
                .termsOfServiceUrl("https://blog.csdn.net/Lammonpeter")
                .contact(new Contact("Lemon", "https://blog.csdn.net/Lammonpeter", "lemon_jiang@aliyun.com"))
                .version("1.0.0")
                .build();
    }
}

对上面的代码有如下解释: 通过createRestfulApiDocs方法创建DocketBean之后,apiInfo()用来创建该API的基本信息(这些基本信息会展现在文档页面中)。select()函数返回一个ApiSelectorBuilder实例用来控制哪些接口暴露给Swagger来展现,本例采用指定扫描的包路径来定义,Swagger会扫描该包下所有Controller定义的API,并产生文档内容(除了被@ApiIgnore指定的请求)。

添加文档内容

在完成了上述配置后,其实已经可以生产文档内容,但是这样的文档主要针对请求本身,而描述主要来源于函数等命名产生,对用户并不友好,我们通常需要自己增加一些说明来丰富文档内容。如下所示,我们通过@ApiOperation注解来给API方法增加说明,通过@ApiImplicitParams@ApiImplicitParam注解来给参数增加说明,通过@ApiModelProperty注解来给实体类的属性增加说明。

  • Controller添加文档说明:
代码语言:javascript
复制
package com.lemon.security.web.controller;

import cn.hutool.core.io.IoUtil;
import com.lemon.security.web.dto.FileInfo;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * @author lemon
 * @date 2018/4/2 下午2:19
 */
@RestController
@RequestMapping("/file")
public class FileController {

    private static String folder = "/Users/lemon/IdeaProjects/spring-security/lemon-security-demo";

    @PostMapping
    @ApiOperation(value = "文件上传接口", notes = "访问此接口可以实现文件上传")
    @ApiImplicitParam(name = "file", value = "使用MultipartFile的实例对象来接收文件数据", required = true, dataTypeClass = MultipartFile.class)
    public FileInfo upload(@RequestParam("file") MultipartFile file) throws IOException {
        System.out.println("上传文件的表单name值为:" + file.getName());
        System.out.println("文件路径为:" + file.getOriginalFilename());
        System.out.println("文件大小为:" + file.getSize());
        File localFile = new File(folder, System.currentTimeMillis() + ".txt");
        // 执行上传操作
        file.transferTo(localFile);
        return new FileInfo(localFile.getAbsolutePath());
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "文件下载接口", notes = "访问此接口并提供文件ID即可下载文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "文件ID", required = true, dataTypeClass = String.class),
            @ApiImplicitParam(name = "request", value = "HttpServletRequest实例对象,自动注入,无需传递", required = true, dataTypeClass = HttpServletRequest.class),
            @ApiImplicitParam(name = "response", value = "HttpServletResponse实例对象,自动注入,无需传递", required = true, dataTypeClass = HttpServletResponse.class)
    })
    public void download(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) {
        System.out.println(folder);
        try (
                // 这是JDK7的特性,关于流的操作,可以写在try后面的圆括号里,这样就无需手动关闭流
                InputStream inputStream = new FileInputStream(new File(folder, id + ".txt"));
                OutputStream outputStream = response.getOutputStream()
        ) {
            // 设置下载的文件类型
            response.setContentType("application/x-download");
            // 设置下载后的文件名
            response.setHeader("Content-Disposition", "attachment;filename=test.txt");
            IoUtil.copy(inputStream, outputStream);
            // 刷新输出流
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

其中, @ApiOperation注解的value属性一般都是简单描述API的功能,notes属性详细描述API的功能; @ApiImplicitParams用来描述一个方法的多个参数的注解; @ApiImplicitParam用来表述单个参数,name属性来描述参数的名称,value用来描述参数的意思,required表示参数是否是必需值,dataTypeClass或者dataType指定了数据的类型。 这里仅仅是对注解进行说明,而代码本身来自上一节内容,即《Spring Security技术栈开发企业级认证与授权(六)使用REST方式处理文件服务》。

  • 给实体类添加文档说明:
代码语言:javascript
复制
package com.lemon.security.web.dto;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * @author lemon
 * @date 2018/4/2 下午2:24
 */
@Data
public class FileInfo {

    @ApiModelProperty(value = "文件上传后的文件路径")
    private String path;

    public FileInfo(String path) {
        this.path = path;
    }
}

其中,@ApiModelProperty用来描述参数的意义。

配置完成以后,运行Spring Boot应用,在地址栏访问http://localhost:8080/swagger-ui.html就可以进入自定义的Swagger文档界面,效果图如下:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
API文档访问与调试

在上图请求的页面中,Swagger除了查看接口功能外,还提供了调试测试功能,点击“Try it out!”按钮,即可完成了一次请求调用!此时,你也可以通过几个POST请求来验证之前的POST请求是否正确。相比为这些接口编写文档的工作,我们增加的配置内容是非常少而且精简的,对于原有代码的侵入也在忍受范围之内。因此,在构建RESTful API的同时,加入Swagger来对API文档进行管理,是个不错的选择。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-04-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 添加依赖
  • 配置Swagger
  • 添加文档内容
  • API文档访问与调试
相关产品与服务
Serverless HTTP 服务
Serverless HTTP 服务基于腾讯云 API 网关 和 Web Cloud Function(以下简称“Web Function”)建站云函数(云函数的一种类型)的产品能力,可以支持各种类型的 HTTP 服务开发,实现了 Serverless 与 Web 服务最优雅的结合。用户可以快速构建 Web 原生框架,把本地的 Express、Koa、Nextjs、Nuxtjs 等框架项目快速迁移到云端,同时也支持 Wordpress、Discuz Q 等现有应用模版一键快速创建。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档