-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Open
Labels
in: webIssues in web modules (web, webmvc, webflux, websocket)Issues in web modules (web, webmvc, webflux, websocket)status: waiting-for-triageAn issue we've not yet triaged or decided onAn issue we've not yet triaged or decided on
Description
Problem
Array GET parameter using [] suffix is not work on Spring WebMVC .
- using GET method
- using ModelAttribute to resolve handler method argument
- using
[]suffix parameter and multipe values
Versions
- Spring Boot 3.5.7
- Spring Framework 6.2.12
Reproduction Code
production code
package com.example.demo
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.ModelAttribute
import org.springframework.web.bind.annotation.RestController
@SpringBootApplication
class DemoApplication
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
// ===== Form Class (Constructor Binding) =====
data class SomeForm(
val names: List<String>? = null
)
// ===== Controller =====
@RestController
class DemoController {
@GetMapping("/some")
fun some(@ModelAttribute form: SomeForm): Map<String, Any> {
val names = form.names ?: emptyList()
return mapOf(
"names" to names,
"size" to names.size,
"request" to "GET /some with names[] parameter"
)
}
}test code
package com.example.demo
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.get
@WebMvcTest(DemoController::class)
class DemoControllerTest {
@Autowired
private lateinit var mockMvc: MockMvc
@Test
fun `array parameter binding with brackets fails to bind multiple values`() {
// BUG: Only the first value is bound when using names[] notation
// Expected: names = ["1", "2"], size = 2
// Actual: names = ["1"], size = 1
mockMvc.get("/some") {
param("names[]", "1")
param("names[]", "2")
}.andDo {
print()
}.andExpect {
status { isOk() }
jsonPath("$.size") { value(2) } // This assertion should fail
jsonPath("$.names[0]") { value("1") }
jsonPath("$.names[1]") { value("2") } // names[1] doesn't exist
}
}
@Test
fun `array parameter binding without brackets works correctly`() {
// Control test: Without brackets, multiple values are bound correctly
mockMvc.get("/some") {
param("names", "1")
param("names", "2")
}.andDo {
print()
}.andExpect {
status { isOk() }
jsonPath("$.size") { value(2) }
jsonPath("$.names[0]") { value("1") }
jsonPath("$.names[1]") { value("2") }
}
}
@Test
fun `single value with brackets binds correctly`() {
// Verify behavior with single value
mockMvc.get("/some") {
param("names[]", "1")
}.andDo {
print()
}.andExpect {
status { isOk() }
jsonPath("$.size") { value(1) }
jsonPath("$.names[0]") { value("1") }
}
}
@Test
fun `empty parameters return empty list`() {
// Verify behavior with no parameters
mockMvc.get("/some")
.andDo {
print()
}.andExpect {
status { isOk() }
jsonPath("$.size") { value(0) }
jsonPath("$.names") { isArray() }
}
}
}Related
Metadata
Metadata
Assignees
Labels
in: webIssues in web modules (web, webmvc, webflux, websocket)Issues in web modules (web, webmvc, webflux, websocket)status: waiting-for-triageAn issue we've not yet triaged or decided onAn issue we've not yet triaged or decided on