Spring boot 2.0 升级到 3.3.1 的相关问题 (九)

Spring boot 2.0 升级到 3.3.1 的相关问题 (九)

Spring Doc 自定义authorization 请求头的处理

直接通过addOperationCustomizeraddParametersItem 处理添加的authorization的请求头在swagger UI的页面上是不会提交这个请求头的,authorization的请求头这个是作为Security的一部分。因此需要通过自定义SecurityScheme 来实现。

添加一个自定义的 Authorization SecurityScheme

/**
 * 自定义的Spring Doc Authorization 配置
 */
@Configuration
@SecurityScheme(
    type = SecuritySchemeType.APIKEY,
    description = "Custom token authentication",
    name = FrameConstant.HTTP_HEADER_AUTHORIZATION,
    in = SecuritySchemeIn.HEADER
)
public class SpringDocAuthorizationConfig {
}

修改OpenApi的配置

    @Bean @Profile("!prod") public GroupedOpenApi customOpenAPI() {
        log.info("自定义SpringDoc配置");
        return GroupedOpenApi.builder().group(applicationName).packagesToScan(controllerPackages)
            .addOperationCustomizer((operation, handlerMethod) -> {
	            //添加自定义的SecurityScheme
                operation.addSecurityItem(new SecurityRequirement().addList(FrameConstant.HTTP_HEADER_AUTHORIZATION));
                //添加其他的参数请求头
                operation.addParametersItem(
                    new HeaderParameter().name(FrameConstant.HTTP_HEADER_CLIENT_TYPE).description("客户端版本类型")
                        .required(true));
                operation.addParametersItem(
                    new HeaderParameter().name(FrameConstant.HTTP_HEADER_CLIENT_VERSION).description("客户端版本号")
                        .required(true));
                return operation;
            }).addOpenApiCustomizer(openApi -> openApi.info(
                new Info().title(applicationName).description(applicationDescription).version(applicationVersion)))
            .build();
    }

Spring Doc 访问 Swagger UI 异常的问题

问题描述

访问项目的Swagger UI显示Swagger Petstore 的一个demo 页面
在这里插入图片描述

原因是/v3/api-docs/swagger-config 这个请求没有正常返回,大概率是项目的拦截器拦截掉这个请求,比如鉴权

问题解决

降这个URL添加到过滤器的白名单中就可以了。

通过URL参数传入数组序列参数导致请求异常的BUG

问题描述

例如GET请求/page-info/list?keywordGroupList[0].keyword=abc&keywordGroupList[0].searchType=10&keywordGroupList[0].isExclude=false&limit=10&offset=0
会出现错误,导致请求直接报错,Socket 层的直接被拦截掉了,都进入不到Servlet。

通过跟踪请求链,在org.apache.coyote.http11.Http11Processor#service 中发现了下面这个异常信息的异常
Invalid character found in the request target [/page-info/list?keywordGroupList[0].keyword=abc&keywordGroupList[0].searchType=10&keywordGroupList[0].isExclude=false&limit=10&offset=0 ]. The valid characters are defined in RFC 7230 and RFC 3986

查询关键字 The valid characters are defined in RFC 7230 and RFC 3986 发现是Tomcat的执行了更严格的规范,导致[] 这种符号不允许出现在URL中。

解决方案

1、修改为GET 请求为POST 请求,Body的参数没限制(不推荐)

2、前端进行编码转换

/page-info/list?keywordGroupList[0].keyword=abc&keywordGroupList[0].searchType=10&keywordGroupList[0].isExclude=false&limit=10&offset=0 中的中括号[] 转换成%5B%5D

使用qsstringify进行转换就可以了qs.stringify(params,'comma');

axios 为例,配置paramsSerializer 就可以了。

import axios from 'axios';
import qs from 'qs';

  return axios(Object.assign({
    baseURL,
    headers,
    url,
    data,
    params,
    paramsSerializer: (params: any) => {
      if(params){
        return qs.stringify(params,'comma');
      }
      return "";
    },
    timeout
  }, options))
    .then((res) => {
      //
    })
    .catch(err => {
      //
    });

相关资料

RFC 7230(HTTP/1.1 Message Syntax and Routing)

  • 通用语法规则:RFC 7230定义了HTTP请求和响应的通用语法规则,包括对URL的引用和格式要求。
  • 字符集:HTTP协议使用的字符集是US-ASCII。
  • 转义机制:特殊字符需要使用转义序列,通常是百分号(%)后跟两位十六进制数来表示。

RFC 3986(Uniform Resource Identifier (URI): Generic Syntax)

  • URI组成:RFC 3986定义了URI的一般语法,包括方案(scheme)、授信部分(authority)、路径(path)、查询(query)和片段(fragment)。
  • 保留字符:在URI中,某些字符被视为保留字符,它们在URI的不同部分有特定的含义。例如,冒号(:)、斜杠(/)、问号(?)和井号(#)等。
  • 非ASCII字符:URI可以包含非ASCII字符,但需要进行编码。这通常通过使用UTF-8字符编码,然后对每个字节进行百分号编码来实现。
  • 路径部分:路径部分可以包含非保留字符,但这些字符可能需要进行编码,特别是如果它们是特殊字符或不可见字符。
    查询字符串:查询字符串可以包含键值对,其中等号(=)用作分隔符,每个键和值都可能需要编码。
  • 片段标识符:片段标识符用于指向资源内的特定部分,同样需要对特殊字符进行编码。
    字符限制
  • 允许的字符:字母(a-z, A-Z)、数字(0-9)、一些特殊字符如减号(-)、下划线(_)、点(.)和波浪线(~)。
    需要编码的字符:除了上述允许的字符外,其他字符,包括空格、标点符号、非ASCII字符等,都需要进行百分号编码。
  • 17
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值