- 
                Notifications
    You must be signed in to change notification settings 
- Fork 38.8k
Description
Since updating to Spring Boot 3.4.0 / 3.4.1
Given this TestController:
@RestController
public class TestController {
    @GetMapping("/test")
    public ResponseEntity<String> testMe(Parameter params) {
        return ResponseEntity.ok("Hello World");
    }
}with this Parameter Bean:
public class Parameter {
    // This constructor will cause the request to result in an error 500....
    public Parameter(List<String> params) {
        this.params = params;
    }
    private List<String> params;
   // ... getter & setter
}A request to /test?params[]=123 will fail with this Exception:
Request processing failed: java.lang.StringIndexOutOfBoundsException: begin 7, end -1, length 8
jakarta.servlet.ServletException: Request processing failed: java.lang.StringIndexOutOfBoundsException: begin 7, end -1, length 8
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1022)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
	at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:72)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
	at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:165)
	at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.springframework.test.web.servlet.setup.MockMvcFilterDecorator.doFilter(MockMvcFilterDecorator.java:162)
	at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.springframework.test.web.servlet.setup.MockMvcFilterDecorator.doFilter(MockMvcFilterDecorator.java:162)
	at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.springframework.test.web.servlet.setup.MockMvcFilterDecorator.doFilter(MockMvcFilterDecorator.java:162)
	at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
	at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:201)
	at test.spring.databindererror500.TestControllerTest.shouldNotGetError500(TestControllerTest.java:23)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.StringIndexOutOfBoundsException: begin 7, end -1, length 8
	at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4601)
	at java.base/java.lang.String.substring(String.java:2704)
	at org.springframework.validation.DataBinder.getIndexes(DataBinder.java:1118)
	at org.springframework.validation.DataBinder.createList(DataBinder.java:1057)
	at org.springframework.validation.DataBinder.createObject(DataBinder.java:961)
	at org.springframework.validation.DataBinder.construct(DataBinder.java:909)
	at org.springframework.web.bind.ServletRequestDataBinder.construct(ServletRequestDataBinder.java:116)
	at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.constructAttribute(ServletModelAttributeMethodProcessor.java:157)
	at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:148)
	at
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)
	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:226)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:180)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	... 24 moreWhen requesting /test?params=123 everything works as expected.
When requesting /test?params[]=123 but without the constructor, everything also works as expected.
In Spring Boot <= 3.3.7 also everything works as expected.
You can find a simple demo application here: dataBinderError500.zip
My expectation would be that the parameter is parsed correctly despite the []. I could also live with a validation error or a BadRequest. But an Error 500 with StringOutOfBounds exception is unpleasant.
Edit: My first idea was that it was the @ConstructorProperties(“params”), but it is the constructor itself that causes the error.