You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring接收请求参数时String转自定义枚举失败问题求助

问题

我在通过HTTP请求传递排序参数时遇到了问题:控制器接收的是OpenAPI生成的Sort枚举类型参数,但只能识别ASC或DESC格式的参数,无法处理created:ASC这种预期格式的输入。

生成的枚举代码如下:

/**
* 
* Values: ASC,DESC
*/
enum class Sort(val value: kotlin.String) {

    @JsonProperty("created:ASC") ASC("created:ASC"),
    @JsonProperty("created:DESC") DESC("created:DESC")
}

发送created:ASC时会抛出400类型不匹配异常,报错栈信息:

org.springframework.web.server.ServerWebInputException: 400 BAD_REQUEST "Type mismatch."

Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@io.swagger.v3.oas.annotations.Parameter @jakarta.validation.Valid @org.springframework.web.bind.annotation.RequestParam com.my.app.api.Sort] for value 'created:ASC'

Caused by: java.lang.IllegalArgumentException: No enum constant com.my.app.api.Sort.created:ASC
    at java.base/java.lang.Enum.valueOf(Enum.java:273)

使用的依赖版本:

  • spring-boot = 3.0.3
  • kotlin = "1.8.0"
  • openapi = "7.0.0-beta"
原因分析

Spring处理@RequestParam这类URL参数的枚举转换时,默认使用Enum.valueOf()方法,只会匹配枚举的名称(比如ASC、DESC),而不是@JsonProperty注解指定的值。@JsonProperty主要用于Jackson处理JSON请求体的序列化/反序列化,对URL参数的转换逻辑不生效。你之前遇到的类似控制器生效的情况,大概率是因为那个接口接收的是JSON请求体,而非URL参数。

解决方案

1. 自定义Spring枚举转换器

创建一个Spring Converter组件,手动实现字符串到Sort枚举的转换逻辑,匹配枚举的value字段:

import org.springframework.core.convert.converter.Converter
import org.springframework.stereotype.Component

@Component
class StringToSortConverter : Converter<String, Sort> {
    override fun convert(source: String): Sort? {
        return Sort.values().firstOrNull { it.value == source }
    }
}

这个转换器会被Spring自动识别,处理@RequestParam到Sort枚举的转换。

2. 修改OpenAPI生成配置(推荐)

因为枚举是OpenAPI自动生成的,手动修改代码会被下次生成覆盖,所以更推荐调整生成配置,让生成的枚举自带正确的转换逻辑:

在OpenAPI规范中明确枚举值

确保你的OpenAPI YAML/JSON里,排序参数的枚举值是created:ASC和created:DESC:

parameters:
  - name: sort
    in: query
    schema:
      type: string
      enum:
        - created:ASC
        - created:DESC

调整生成器配置

在Gradle/Maven的OpenAPI Generator插件配置中,添加参数让生成的枚举支持基于值的转换:
以Gradle为例:

openApiGenerate {
    generatorName = "spring"
    inputSpec = "$rootDir/src/main/resources/openapi.yaml".toString()
    outputDir = "$buildDir/generated".toString()
    apiPackage = "com.my.app.api"
    modelPackage = "com.my.app.model"
    configOptions = [
        enumPropertyNaming: "UPPERCASE",
        useJackson: "true",
        delegatePattern: "true",
        useSpringConverter: "true" // 启用Spring转换器生成
    ]
}

生成后的枚举会自动包含@JsonValue注解或者对应的转换器逻辑,无需手动修改。

3. 手动添加@JsonValue注解(临时方案)

如果允许临时修改生成的枚举代码,可以给value字段添加@JsonValue注解,让Spring和Jackson都以这个值作为转换依据:

/**
* 
* Values: ASC,DESC
*/
enum class Sort(val value: kotlin.String) {

    @JsonProperty("created:ASC") ASC("created:ASC"),
    @JsonProperty("created:DESC") DESC("created:DESC");

    @JsonValue
    fun getValue(): String = value
}

注意:下次生成代码时这个修改会被覆盖,仅作为临时解决办法。

内容的提问来源于stack exchange,提问作者agingcabbage32

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:14:53