SpringBoot 生成美观的接口文档

前言

作为一名程序员,我们最讨厌两件事:1. 别人不写注释。2. 自己写注释。
而作为一名接口开发者,我们同样讨厌两件事:1. 别人不写接口文档,文档不及时更新。2. 需要自己写接口文档,还需要及时更新。

相信无论是前端还是后端开发,都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。

而随着Springboot、Springcloud等微服务的流行,每个项目都有成百上千个接口调用,这时候再要求人工编写接口文档并且保证文档的实时更新几乎是一件不可能完成的事,所以这时候我们迫切需要一个工具,一个能帮我们自动化生成接口文档以及自动更新文档的工具。它就是Swagger。

Swagger 提供了一个全新的维护 API 文档的方式,有4大优点:

  1. 自动生成文档:只需要少量的注解,Swagger 就可以根据代码自动生成 API 文档,很好的保证了文档的时效性。
  2. 跨语言性,支持 40 多种语言。
  3. Swagger UI 呈现出来的是一份可交互式的 API 文档,我们可以直接在文档页面尝试 API 的调用,省去了准备复杂的调用参数的过程。
  4. 还可以将文档规范导入相关的工具(例如 SoapUI), 这些工具将会为我们自动地创建自动化测试。

现在我们知道了Swagger的作用,接下来将其集成到我们项目中。

Swagger2集成

集成Swagger很简单,只需要简单三步。

第一步:引入依赖包

 		 <!-- 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>

第二步:增加一个swagger配置类

package com.king.other.short_link.config;

import org.springframework.beans.factory.annotation.Value;
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;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @program: springboot
 * @description:
 * @author: King
 * @create: 2021-10-10 22:33
 */
@Configuration
@EnableSwagger2  //启用swaggerr 注解解析器
public class Swagger2Config {

    // 是否开启swagger,正式环境一般是需要关闭的,可根据springboot的多环境配置进行设置
    @Value(value = "${swagger.enable}")  //通过 @Value  获取配置信息
    // 复习@Environement  @Value    @ConfigurationProperties
    private Boolean swaggerEnable;

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .ignoredParameterTypes(HttpSession.class, HttpServletRequest.class)  //在生成的文档将哪些类对象的属性排除
                // 是否开启
                .enable(swaggerEnable)
                .select()
                // 扫描的路径包,只要这些包中的类配有swagger注解,则启用这些注解
                .apis(RequestHandlerSelectors.basePackage("com.king"))
                // 指定路径处理PathSelectors.any()代表所有的路径
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("测试平台-平台管理API文档")
                .description("平台管理服务api")
                // 作者信息
                .contact(new Contact("king", "http://www.huahuazhw.xyz", "824276226@qq.com"))
                .version("1.0.0")
                .build();
    }
}

注:这里的swaggerEnable 用于控制是否开启Swagger,生产环境记得关闭Swagger,将值设置为 false 在application文件里面配置即可
在这里插入图片描述

第三步:在你的Controller类上加上注解

ShortLinkController.java

package com.king.other.short_link.controller;

import com.king.other.short_link.bean.ShortLink;
import com.king.other.short_link.service.ShortLinkServiceImpl;
import com.king.other.short_link.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * @program: springboot
 * @description:
 * @author: King
 * @create: 2021-09-18 14:20
 */
@RestController
@Api(value = "链接转换接口", tags = "测试接口1")
public class ShortLinkController {
    @Autowired
    ShortLinkServiceImpl shortLinkService;

    //生成分享链接
    @RequestMapping(value = "/share.do")
    @ApiOperation(value = "长链转短链", tags ="测试接口1")
    @ApiImplicitParam(name = "longLink", value = "长链", dataType = "string", paramType = "query", example = "www.baidu.com", required = true)
    public Result shareLink(HttpServletRequest request, String longLink) {
        Result result = new Result();
        if (longLink != null) {
            result.setData(shortLinkService.addShortLink(longLink, getUrlStart(request)));
            result.setStatus(true);
        }
        return result;
    }

    //实现短链跳转
    @RequestMapping(value = "/short/{shortLink}")
    @ApiOperation(value = "实现短链跳转", tags ="测试接口1")
    @ApiImplicitParam(name = "shortLink", value = "短链", dataType = "string", paramType = "query", example = "NbI6qbyb", required = true)
    public void sendRedirect(HttpServletResponse response,  @PathVariable String shortLink) {
        ShortLink shorts = shortLinkService.getLongLink(shortLink);
        if (shorts != null) {
            try {
                response.sendRedirect(shorts.getLongLink());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //获取请求的协议域名,端口号生成连接的前半部分
    public String getUrlStart(HttpServletRequest request) {
        StringBuilder url = new StringBuilder();
        url.append(request.getScheme());
        System.out.println(url);
        url.append("://").append(request.getServerName());
        System.out.println(url);
        url.append(":").append(request.getServerPort());
        System.out.println(url);
        return url.toString();
    }
}

TestController.java

package com.king.other.short_link.controller;

import com.king.other.short_link.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: springboot
 * @description:
 * @author: King
 * @create: 2021-10-10 23:14
 */
@RestController
@Api(value = "操作接口", tags = "测试接口2")
public class TestController {
    @PostMapping(value = "/test.do")
    @ApiOperation(value = "测试接口多个参数", tags = "测试接口2")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "用户名", dataType = "string", paramType = "query", example = "lihailin9073", required = true),
            @ApiImplicitParam(name = "email", value = "邮箱", dataType = "string", paramType = "query", example = "jinpeng.qmail@qq.com", required = true),
    })
    public Result test(String name, String email) {
        Result result = new Result();
        Map<String, String> map = new HashMap<>();
        map.put("用户名", name);
        map.put("邮箱", email);
        result.setData(map);
        result.setMessage("这是一个测试接口");
        result.setStatus(true);
        return result;
    }
}

通过@Api注解标注需要生成接口文档,通过@ApiOperation注解标注接口名。通过@ApiImplicitParam或者@ApiImplicitParams 用在请求的方法上,表示一组参数说明

同时我们给响应类也加上对应的注解

Result.java

package com.king.other.short_link.vo;

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

/**
 * @program: springboot
 * @description:
 * @author: King
 * @create: 2021-09-18 14:26
 */
@Data
@ApiModel(value = "返回响应类")
public class Result {
    @ApiModelProperty(value = "状态")
    protected boolean status;
    @ApiModelProperty(value = "返回信息")
    protected String message;
    @ApiModelProperty(value = "数据")
    protected Object data;
}

swagger2 注解说明

@Api:用在请求的类上,表示对类的说明
    tags="说明该类的作用,可以在UI界面上看到的注解"
    value="该参数没什么意义,在UI界面上也看到,所以不需要配置"
 
 
@ApiOperation:用在请求的方法上,说明方法的用途、作用
    value="说明方法的用途、作用"
    notes="方法的备注说明"
 
 
@ApiImplicitParams:用在请求的方法上,表示一组参数说明
    @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
        name:参数名
        value:参数的汉字说明、解释
        required:参数是否必须传
        paramType:参数放在哪个地方
            · header --> 请求参数的获取:@RequestHeader
            · query --> 请求参数的获取:@RequestParam
            · path(用于restful接口)--> 请求参数的获取:@PathVariable
            · body(不常用)
            · form(不常用)    
        dataType:参数类型,默认String,其它值dataType="Integer"       
        defaultValue:参数的默认值
 
 
@ApiResponses:用在请求的方法上,表示一组响应
    @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
        code:数字,例如400
        message:信息,例如"请求参数没填好"
        response:抛出异常的类
 
 
@ApiModel:用于响应类上,表示一个返回响应数据的信息
            (这种一般用在post创建的时候,使用@RequestBody这样的场景,
            请求参数无法使用@ApiImplicitParam注解进行描述的时候)
    @ApiModelProperty:用在属性上,描述响应类的属性

简单三步,我们项目就集成了Swagger接口文档,赶紧启动服务,访问http://localhost:9090/swagger-ui.html体验一下。
在这里插入图片描述

Swagger2美化

Swagger2原生UI有点丑,我们可以借助Swagger的增强工具knife4j优化一下。

第一步:引入依赖包

        <!-- knife4j -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>2.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

第二步:启用knife4j增强

@Configuration
@EnableSwagger2  //启用swaggerr 注解解析器
@EnableKnife4j //启用knife4j增强
@Import(BeanValidatorPluginsConfiguration.class)
public class Swagger2Config {
  ...
}

通过上面两步我们就完成了Swagger的美化,通过浏览器访问http://localhost:9090/doc.html即可看到效果。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最后附上源代码

Github https://github.com/KingJin-web/springboot/tree/master/other
Gitee https://gitee.com/KingJin-web/springboot/tree/master/other

以上内容属于个人笔记整理,如有错误,欢迎批评指正!

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值