首页 > 其他分享 >SpringBoot整合Swagger2,代码文档一手抓

SpringBoot整合Swagger2,代码文档一手抓

时间:2024-07-24 20:26:25浏览次数:16  
标签:java SpringBoot spring jar Swagger2 文档 springframework context org

文章目录

引言

什么是swagger

Swagger 是一个规范且完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务以及 集成Swagger自动生成API文档。
Swagger 的目标是对 REST [API] 定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档或网络流量监测就可以发现和理解服务的能力。当通过 Swagger 进行正确定义,用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互。与为底层编程所实现的接口类似,Swagger 消除了调用服务时可能会有的猜测。

Swagger 的优势

支持 API 自动生成同步的在线文档:使用 Swagger 后可以直接通过代码生成文档,不再需要自己手动编写接口文档了,对程序员来说非常方便,可以节约写文档的时间去学习新技术。
提供 Web 页面在线测试 API:光有文档还不够,Swagger 生成的文档还支持在线测试。参数和格式都定好了,直接在界面上输入参数对应的值即可在线测试接口。
前后端集成联调,前端人员和后端人员无法做到 “及时协商,尽早解决”,通过swagger可以直观展现实时调整,减少沟通成本。

SpringBoot整合Swagger 2

添加Swagger依赖

        <!--web起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.5.7</version>
        </dependency>

        <!--测试组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--添加Spring swagger 依赖 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

application.yml配置

server:
  port: 17006

配置类SwaggerConfig

/**
 * Swagger配置类
 * @author 共饮一杯无
 */
//指定为配置类
@Configuration
//开启Swagger2
@EnableSwagger2
public class SwaggerConfig {
    /**
     * 添加摘要信息(Docket)
     */
    @Bean
    public Docket controllerApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder()
                        .title("API文档标题")
                        .description("文档描述:用于实时查看、测试API")
                        .contact(new Contact("共饮一杯无", "https://zhanjq.blog.csdn.net/", ""))
                        .version("版本号:1.0")
                        .build())
                .select()
                //API基础扫描路径
                .apis(RequestHandlerSelectors.basePackage("com.zjq.swagger"))
                .paths(PathSelectors.any())
                .build();
    }
}

启动类配置

/**
 * SpringSwagger案例
 * @author zjq
 */
@SpringBootApplication
//启用swagger
@EnableSwagger2
public class SpringSwaggerApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringSwaggerApplication.class, args);
	}

}

RESTful实战案例参考

带swagger注解的Controller类:
带swagger注解的实体类:

常见swagger注解说明

  1. @Api: 这个注解用于类级别,用来描述一个Controller的作用。例如:
@Api(value = "用户管理", description = "系统中的用户操作")
  1. @ApiOperation: 这个注解用于方法级别,描述一个特定的API操作。例如:
@ApiOperation(value = "获取所有用户", notes = "返回所有用户列表")
  1. @ApiParam: 这个注解用于描述方法参数的细节,如用途、是否必需、默认值等。例如:
@ApiParam(value = "用户ID", required = true)
  1. @ApiResponse: 描述API的响应状态码及可能的响应体。例如:
@ApiResponse(code = 200, message = "成功获取用户", response = User.class)
  1. @ApiResponses: 包含多个@ApiResponse,可以描述多个可能的响应情况。例如:
@ApiResponses(value = {
    @ApiResponse(code = 200, message = "成功"),
    @ApiResponse(code = 404, message = "未找到资源"),
    @ApiResponse(code = 500, message = "服务器错误")
})
  1. @ApiIgnore: 如果你不希望某个方法出现在Swagger文档中,可以使用此注解。例如:
@ApiIgnore
@GetMapping("/test")
public String test() {
    return "This is a test endpoint";
}
  1. @ApiModel: 用于描述一个模型(即类)的结构。例如:
@ApiModel(value = "用户模型", description = "用户数据模型")
public class User {
}
  1. @ApiModelProperty: 描述模型属性的细节。例如:
@ApiModelProperty(value = "用户ID", example = "1")
private Integer id;
  1. @ApiImplicitParam

这个注解通常用于方法级别,而不是参数级别,它描述的是隐式参数,即那些可能不直接从方法签名中明显看出的参数。
它可以用来描述查询参数 (query parameters)、请求头 (headers) 或者其他非显式的参数类型。
当你需要描述多个这样的参数时,可以使用 @ApiImplicitParams,这是一个 @ApiImplicitParam 的数组。例如:

@GetMapping("/users")
@ApiImplicitParams({
    @ApiImplicitParam(name = "page", value = "Page number of the result set", paramType = "query", dataType = "integer"),
    @ApiImplicitParam(name = "limit", value = "Size of the page", paramType = "query", dataType = "integer")
})
public List<User> getUsers(@RequestParam Integer page, @RequestParam Integer limit) {
    // ...
}

@ApiParam 更适用于描述与方法签名直接相关的参数,而 @ApiImplicitParam 更适合描述那些通过其他方式(如请求查询字符串或头部)传递的参数。
@ApiImplicitParam 提供了一种方法来集中描述多个参数,特别是在参数数量较多的情况下,这比在每个参数上使用 @ApiParam 要更整洁。

页面访问效果

在这里插入图片描述

常见错误

  1. 使用 Spring Boot 2.7 及以上版本时,Swagger 2.9.2会有一些**兼容性问题,**报错如下:

org.springframework.context.ApplicationContextException: Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerException
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.27.jar:5.3.27]
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) ~[spring-context-5.3.27.jar:5.3.27]

Caused by: java.lang.NullPointerException: null
at springfox.documentation.spi.service.contexts.Orderings$8.compare(Orderings.java:112) ~[springfox-spi-2.9.2.jar:null]
at springfox.documentation.spi.service.contexts.Orderings$8.compare(Orderings.java:109) ~[springfox-spi-2.9.2.jar:null]

解决办法:
版本对应(Maven官方仓库:https://mvnrepository.com/

  • SPB(SpringBoot) 2.7 以下 + Swagger-ui 和Swagger2 2.9.2
    在这里插入图片描述

  • SPB(SpringBoot) 2.7 往上 + springfox-boot-starter(3.0.0包括Swagger-ui 和Swagger2 3.0.0)
    在这里插入图片描述

  • SPB(SpringBoot) 3.0往上直接改用Springdoc OpenAPI
    在这里插入图片描述

  1. 使用springboot2.7以上版本+springfox-boot-starter3.0.0依旧报错
org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.27.jar:5.3.27]
	at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) ~[spring-context-5.3.27.jar:5.3.27]
	at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-5.3.27.jar:5.3.27]
	at java.lang.Iterable.forEach(Iterable.java:75) ~[na:1.8.0_171]
	at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) ~[spring-context-5.3.27.jar:5.3.27]
	at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) ~[spring-context-5.3.27.jar:5.3.27]
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:937) ~[spring-context-5.3.27.jar:5.3.27]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.27.jar:5.3.27]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.11.jar:2.7.11]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) [spring-boot-2.7.11.jar:2.7.11]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) [spring-boot-2.7.11.jar:2.7.11]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-2.7.11.jar:2.7.11]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) [spring-boot-2.7.11.jar:2.7.11]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) [spring-boot-2.7.11.jar:2.7.11]
	at com.zjq.swagger.SpringSwaggerApplication.main(SpringSwaggerApplication.java:16) [classes/:na]
Caused by: java.lang.NullPointerException: null
	at springfox.documentation.spring.web.WebMvcPatternsRequestConditionWrapper.getPatterns(WebMvcPatternsRequestConditionWrapper.java:56) ~[springfox-spring-webmvc-3.0.0.jar:3.0.0]
	at springfox.documentation.RequestHandler.sortedPaths(RequestHandler.java:113) ~[springfox-core-3.0.0.jar:3.0.0]
	at springfox.documentation.spi.service.contexts.Orderings.lambda$byPatternsCondition$3(Orderings.java:89) ~[springfox-spi-3.0.0.jar:3.0.0]
	at java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469) ~[na:1.8.0_171]
	at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355) ~[na:1.8.0_171]
	at java.util.TimSort.sort(TimSort.java:220) ~[na:1.8.0_171]
	at java.util.Arrays.sort(Arrays.java:1512) ~[na:1.8.0_171]
	at java.util.ArrayList.sort(ArrayList.java:1462) ~[na:1.8.0_171]
	at java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:387) ~[na:1.8.0_171]
	at java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:1.8.0_171]
	at java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:1.8.0_171]
	at java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:1.8.0_171]
	at java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:1.8.0_171]
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[na:1.8.0_171]
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_171]
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_171]
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_171]
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_171]

解决办法:
在配置类注入如下bean:

    @Bean
    public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
        return new BeanPostProcessor() {

            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
                if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
                    customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
                }
                return bean;
            }

            private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
                List<T> copy = mappings.stream()
                        .filter(mapping -> mapping.getPatternParser() == null)
                        .collect(Collectors.toList());
                mappings.clear();
                mappings.addAll(copy);
            }

            @SuppressWarnings("unchecked")
            private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
                try {
                    Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
                    field.setAccessible(true);
                    return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    throw new IllegalStateException(e);
                }
            }
        };
    }

参考:
官方网站: API Documentation & Design Tools for Teams | Swagger
官方文档: Annotations · swagger-api/swagger-core Wiki · GitHub

本文内容到此结束了,
如有收获欢迎点赞

标签:java,SpringBoot,spring,jar,Swagger2,文档,springframework,context,org
From: https://blog.csdn.net/qq_35427589/article/details/140672560

相关文章

  • Springboot整合redis
    引入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>修改配置文件//单机模式配置spring.redis.host=172.16.7.21 //ip地址spring.redis.port=6379 //端口号s......
  • Java学习 - Springboot 集成 Security 入门小实例
    前言SpringSecurity是Spring家族中一个强大可定制的身份验证和访问控制框架,和Shiro一样,它们都具有认证、授权、加密等用于权限管理的功能。但相比于Shiro,SpringSecurity的功能无疑更加强大。而且作为Spring家族中的一份子,配合家族中的其它兄弟-SpringBoot、S......
  • 文档翻译成中文会麻烦吗?简单操作,快速获取翻译
    每当你工作的时候,看到一堆来自海外文档时,你的脑海中可能会出现大大的两个字:无语。跨国企业的合同、国际合作的项目报告、外国邮件等,不同语言间的沟通往往会让工作变得困难。如何快速高效地处理这些文档?让自己的工作变得轻松点?翻译文档工具,相信可以在这个时候帮上你的忙。它翻......
  • c#配置swagger文档
    .netcore6.0注入swagger,.netcore配置swagger文档6.1号更新token验证 builder.Services.AddSwaggerGen(c=>{//添加token验证c.AddSecurityDefinition("Bearer",newOpenApiSecurityScheme{Description="请输入token,格式为Bearerxxxxxxxx",......
  • Springboot的n多注解(自用)
    pojocontrollerservice(无)service.implmapper  ——————pojo@Dataget/set等@NoArgsConstructor无参构造@AllArgsConstructor有参构造 ——————controller@Slf4j......
  • python带界面实现word文档比对功能
    python实现word文档比对的功能较简单,笔者这里将其界面话,可以指定输入比对的文档,相似度,最小相似参数等。输出的结果以word的形式保存,重复部分会标出,基本实现了商业软件的功能。先看界面这里不废话了,直接给出全部源码,觉得好的点个赞。程序打包的话,自己百度。fromtkinterimp......
  • 基于SSM的家政服务管理系统【附源码+文档】
    ......
  • 基于SSM的高校课程评价系统【附源码+文档】
    ......
  • 易优CMS模板标签field字段值输出指定栏目ID的下级栏目的文档列表
    【基础用法】标签:field描述:获取channelartlist标签里的字段值,field标签只能在channelartlist标签里使用。用法:{eyou:channelartlisttypeid='栏目ID'type='son'row='20'}<ahref='{eyou:fieldname='typeurl'/}'>{eyou:fieldname='typen......
  • 易优CMS模板标签relevarticle相关文档
    [基础用法]标签:relevarticle描述:通过前3个TAG标签或前3个关键词,检索整站文档标题中含有tag标签或者关键词的相关文档,进行关联。在没有tag标签情况下,就以前3个关键词检索文档标题进行关联。这个标签随着数据量的增加可能会比较影响检索性能。提示:使用该标签之前,必须先安装相关文档......