Swagger原理

最近在基于Swagger进行二次开发, 来对项目的接口进行管理,功能实现了,但是不清楚swagger的工作原理,为了后续能更好利用Swagger来管理接口,而且能借鉴Swagger的原理,将项目中其他信息可视化展示,决定DebugSwagger的流程。版本使用的是springdoc-openapi,并不是旧版的swagger,但是口语上还是用swagger表示。

Swagger使用分两个阶段,第一个阶段是注册一些Bean,初始化一些配置。第二阶段是页面访问、接口调用,将数据填充到HTML页面展示在浏览器上。

注册静态资源

WebMvcConfigurationSupport类会实例化HandlerMapping这个Bean

在这里插入图片描述

实例化过程中,将所有的WebMvcConfigurer中定义的ResourceHandler放到ResourceHandlerRegistry中去。所有的WebMvcConfigurer包括系统默认的和自定义的,其中和Swagger相关的就是WebMvcAutoConfiguration类的内部类WebMvcAutoConfigurationAdapter中注册的ResourceHandler,处理的URL是/webjars/**,locations是classpath:/META-INF/resources/webjars/

在这里插入图片描述

另外一个和Swagger相关的是SwaggerWebMvcConfigurer,里面会处理/swagger-ui*/**路径,locations是classpath:/META-INF/resources/webjars/

在这里插入图片描述

在这里插入图片描述

ResourceHandlerRegistry注册完后,会调用ResourceHandlerRegistrygetHandlerMapping方法,实例化AbstractHandlerMapping

在这里插入图片描述

在这里插入图片描述

对于Swagger静态资源,对应的是ResourceHttpRequestHandler。还需要注意到,最后生成AbstractHandlerMappingSimpleUrlHandlerMapping,这在后面请求时会用到。

访问Swagger静态资源

首先访问Swagger首页地址,/swagger-ui/index.html,进入DispatcherServletdoDispatch方法,根据Request对象获取mappedHandler

在这里插入图片描述

getHandler方法里面就是从不同的handlerMappings中获取HandlerExecutionChain,实际走的就是SimpleUrlHandlerMapping

在这里插入图片描述

SimpleUrlHandlerMappinggetHandler方法里看,最终是在SimpleUrlHandlerMapping父类AbstractUrlHandlerMappinglookupHandler方法中,根据URL匹配出ResourceHttpRequestHandler,构造成HandlerExecutionChain对象返回。

在这里插入图片描述

再往下根据mappedHandler获取HandlerAdapter,实际获取到的就是HttpRequestHandlerAdapter

在这里插入图片描述

在这里插入图片描述

接着就会调用HttpRequestHandlerAdapterhandler方法,handler方法会将请求交给HttpRequestHandlerhandleRequest方法,最终是交给ResourceHttpRequestHandlerhandleRequest方法。在该方法中,首先就是获取Resource对象。

在这里插入图片描述

实际上是通过DefaultResourceResolverChain里面的WebJarsResourceResolverPathResourceResolver得到最终的Resource对象,首先是将swagger-ui/index.html通过WebJarsResourceResolver转成swagger-ui/4.14.0/index.html,在将转化后的URL通过PathResourceResolver解析出Resource对象。

在这里插入图片描述

Swagger的静态资源是在org.webjars:swagger-ui:4.14.0中resources目录下

在这里插入图片描述

最后是将Resource对象的内容,写入HttpServletResponse中返回。

访问Swagger Rest接口

访问Swagger首页时,除了一些静态资源如htmlcssjsSwagger还会访问/v3/api-docs/开头的后台Rest接口,这些接口会返回数据供页面使用,共同实现Swagger的功能。

在这里插入图片描述

像上图的swagger-config接口完整路径是/v3/api-docs/swagger-config,这个接口是在SwaggerConfigResource类中定义的。功能就是获取所有的group和对应的URL。

下面主要介绍另外一个接口,/v3/api-docs/{group},这个接口是根据group名称获取该组下的所有接口。

接口定义是这样的

在这里插入图片描述

首先获取OpenApiResource对象,实际获取的是OpenApiWebMvcResource对象

在这里插入图片描述

接着调用openapiJson方法,最终调用的是AbstractOpenApiResourcegetOpenApi方法

在这里插入图片描述

这个方法就是主要扫描接口的方法了,在openAPIService.build(finalLocale)那一句,就是扫描Controller的接口

在这里插入图片描述

当然还有其他处理,处理参数、返回值、执行一些自定义的customisers等等(后面有时间再每一步进去看下是Swagger是如何解析接口、请求数据、返回值的),最终返回一个OpenAPI对象,然后以Json格式的字符串返回给前端。

OpenAPI这个实体类的结构如下,从官网截取部分,以便理解,有了这个结构,可以自定义一些OpenApiCustomiser,对OpenAPI对象进行改动,进行二次开发,实现一些自定义功能。

openapi: 3.0.3
info:
  title: Swagger Petstore - OpenAPI 3.0
  description: |-
    This is a sample Pet Store Server based on the OpenAPI 3.0 specification.  You can find out more about
    Swagger at [https://swagger.io](https://swagger.io). In the third iteration of the pet store, we've switched to the design first approach!
    You can now help us improve the API whether it's by making changes to the definition itself or to the code.
    That way, with time, we can improve the API in general, and expose some of the new features in OAS3.
  termsOfService: http://swagger.io/terms/
  contact:
    email: apiteam@swagger.io
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
  version: 1.0.11
externalDocs:
  description: Find out more about Swagger
  url: http://swagger.io
servers:
  - url: https://petstore3.swagger.io/api/v3
tags:
  - name: pet
    description: Everything about your Pets
    externalDocs:
      description: Find out more
      url: http://swagger.io
  - name: store
    description: Access to Petstore orders
    externalDocs:
      description: Find out more about our store
      url: http://swagger.io
paths:
  /pet:
    put:
      tags:
        - pet
      summary: Update an existing pet
      description: Update an existing pet by Id
      operationId: updatePet
      requestBody:
        description: Update an existent pet in the store
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
          application/xml:
            schema:
              $ref: '#/components/schemas/Pet'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/Pet'
        required: true
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'          
            application/xml:
              schema:
                $ref: '#/components/schemas/Pet'
        '400':
          description: Invalid ID supplied
        '404':
          description: Pet not found
        '405':
          description: Validation exception
      security:
        - petstore_auth:
            - write:pets
            - read:pets
    post:
      tags:
        - pet
      summary: Add a new pet to the store
      description: Add a new pet to the store
      operationId: addPet
      requestBody:
        description: Create a new pet in the store
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
          application/xml:
            schema:
              $ref: '#/components/schemas/Pet'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/Pet'
        required: true
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'          
            application/xml:
              schema:
                $ref: '#/components/schemas/Pet'
        '405':
          description: Invalid input
      security:
        - petstore_auth:
            - write:pets
            - read:pets

总结

流程还是比较清晰,Swagger提供一些Jar包,包含Rest接口和静态资源,应用启动时先注册静态资源、确定访问的URL,访问Swagger首页时,通过SpringMVC将Jar包中的静态资源取出,静态资源中请求后台Rest接口,由后台接口解析项目的Controller接口,返回接口信息给前端展示在页面上。

写这篇文章除了介绍Swagger原理,在Swagger基础上进行二次开发,另外一个目的就是是借鉴这种设计思路,和项目相关的信息可视化展示。比如项目脚本数据和数据表结构变更记录、Git文件提交记录等等。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot是一个快速开发框架,Swagger是一个API文档生成工具,OAuth2是一个授权框架,可以用于保护API。 下面是Spring Boot集成Swagger和OAuth2的代码实现和原理解释: 1. 添加Swagger依赖 在pom.xml中添加Swagger依赖: ```xml <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> ``` 2. 添加Swagger配置 在Spring Boot的配置类中添加Swagger配置: ```java @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } } ``` 3. 添加OAuth2依赖 在pom.xml中添加OAuth2依赖: ```xml <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> <version>2.1.4.RELEASE</version> </dependency> ``` 4. 添加OAuth2配置 在Spring Boot的配置类中添加OAuth2配置: ```java @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated(); } } ``` 5. 添加Token鉴权 添加Token鉴权的方式是在控制器方法上添加@PreAuthorize注解,指定需要的角色或权限: ```java @RestController @RequestMapping("/api") public class ApiController { @GetMapping("/hello") @PreAuthorize("hasRole('ADMIN')") public String hello() { return "Hello World!"; } } ``` 6. 请求Token 使用OAuth2的客户端工具请求Token: ```java public class OAuth2Client { public static void main(String[] args) { Base64.Encoder encoder = Base64.getEncoder(); String clientCredentials = "client_id:client_secret"; String encodedClientCredentials = encoder.encodeToString(clientCredentials.getBytes()); String url = "http://localhost:8080/oauth/token"; HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); headers.add("Authorization", "Basic " + encodedClientCredentials); MultiValueMap<String, String> map = new LinkedMultiValueMap<>(); map.add("grant_type", "client_credentials"); HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers); RestTemplate restTemplate = new RestTemplate(); ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class); System.out.println(response.getBody()); } } ``` 以上就是Spring Boot集成Swagger和OAuth2的代码实现和原理解释。其中Swagger用于生成API文档,OAuth2用于保护API,Token鉴权用于限制访问API的角色或权限。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AE86Jag

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值