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

如何声明接收嵌套列表查询参数的Controller方法及调用?

关于GET请求接收List<List>查询参数的解决方案

首先直接给出结论:你当前的写法默认不可行,因为Spring MVC的默认查询参数解析器无法自动将URL中的JSON格式字符串转换为List<List<String>>类型。不过可以通过自定义参数解析逻辑或者调整参数传递格式来实现,完全满足GET请求的幂等性和可缓存需求。

问题原因

Spring默认处理查询参数时,对于List类型的参数,只会解析两种格式:

  • 重复参数名:比如options=aaa&options=bbb,会解析为List<String>
  • 逗号分割字符串:比如options=aaa,bbb,需开启@RequestParam的split属性或全局配置

但你传入的是JSON格式的嵌套列表字符串,Spring没有内置的解析逻辑处理这种情况,因此会抛出类型转换异常。

解决方案一:自定义JSON参数解析器

通过实现Converter<String, List<List<String>>>,让Spring能够将JSON字符串转换为目标类型:

1. 编写自定义Converter

import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.core.convert.converter.Converter
import org.springframework.stereotype.Component

@Component
class NestedListConverter(private val objectMapper: ObjectMapper) : Converter<String, List<List<String>>> {
    override fun convert(source: String): List<List<String>> {
        return objectMapper.readValue(source, object : com.fasterxml.jackson.core.type.TypeReference<List<List<String>>>() {})
    }
}

2. 保留原有Controller写法

你的Controller方法无需改动,Spring会自动使用这个Converter来解析options参数:

import org.springframework.http.ResponseEntity
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

@RestController
@Validated
class SearchController {
    suspend fun v1GetSearch(
        @PathVariable("id") id: String,
        @Valid @RequestParam(value = "options", required = false) options: List<List<String>>?
    ): ResponseEntity<SearchResponse> {
        // 业务逻辑实现
        return ResponseEntity.ok(SearchResponse())
    }
}

3. 注意事项

  • 确保URL中的JSON字符串已正确编码(方括号、引号等特殊字符需转义),实际请求URL示例:
http://localhost:8080/search/id?options=%5B%5B%22aaa%22%2C%22bbb%22%2C%22ccc%22%2C%22ddd%22%5D%2C%5B%22abcd%22%2C%22abcd%22%2C%22abcd%22%2C%22abcd%22%5D%5D
  • Spring Boot环境下,Jackson的ObjectMapper会自动注入,无需额外配置。

解决方案二:使用扁平式参数传递

如果不想用JSON格式,可以采用更符合HTTP查询参数规范的扁平传递方式,Spring默认支持这种嵌套列表的解析:

1. 参数传递格式

有两种常用的扁平传递方式:

  • 索引式:
http://localhost:8080/search/id?options[0]=aaa&options[0]=bbb&options[0]=ccc&options[0]=ddd&options[1]=abcd&options[1]=abcd&options[1]=abcd&options[1]=abcd
  • 重复参数名+逗号分割子列表:
http://localhost:8080/search/id?options=aaa,bbb,ccc,ddd&options=abcd,abcd,abcd,abcd

使用第二种方式时,需要在application.yml中开启逗号分割列表的解析配置:

spring:
  mvc:
    format:
      query:
        comma-separated-lists: true

2. Controller方法写法

保持你原有的写法即可,Spring会自动将上述格式的参数解析为List<List<String>>。

总结

两种方案都能实现GET请求接收嵌套列表参数,满足幂等性和可缓存的需求:

  • 方案一更适合前端需要传递复杂嵌套结构的场景,但要注意URL编码问题
  • 方案二更符合HTTP查询参数的传统规范,避免JSON编码的麻烦

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 18:57:32