Hi I'm using latest springboot-starter-web version 2.7.5.

    implementation 'org.springframework.boot:spring-boot-starter-web:2.7.5'

but I got a stackoverflow error when using the @Controller annotation.

I DON'T see the error when using @RestController.

Reproduce steps:

there are three class files: 1. Main.java

package org.test.example;

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}
  1. a interface ControllerI
package org.test.example;

import org.springframework.web.bind.annotation.*;

public interface ControllerI {
    @GetMapping("/greet/{user}")
    String greeting(@PathVariable("user") String user);
}
  1. a simple impl class:
package org.test.example;

import org.springframework.stereotype.*;

@Controller
//@RestController
public class ControllerImpl implements ControllerI{
    @Override
    public String greeting(String user) {
        return String.format("Hello" + user);
    }
}

and when I using curl http://127.0.0.1:8080/greet/myname, it shows stackoverflowerror:

    at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:244) ~[tomcat-embed-core-9.0.68.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:585) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:244) ~[tomcat-embed-core-9.0.68.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:585) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:244) ~[tomcat-embed-core-9

Comment From: wilkinsona

When you use @RestController, the controller method's return value is used as the body of the response. When you use @Controller, the controller's return value is the name of a view that should be rendered. I suspect you don't have a view named greet myname and this is somehow triggering a bug in Tomcat. I don't think we can do anything about Tomcat's behavior and, from what you've shared thus far, I don't think it will occur if you return the name of a view that exists.

Comment From: gaoxingliang

Hi @wilkinsona Thanks for your explanation. Yes. The view is not found. I think the embedded tomcat should return a 404 error or some other error instead of a stackoverflow error. I will check more about the source code.

Comment From: gaoxingliang

I found the root cause is when we search the view in class RequestMappingHandlerAdapter It will try to find the matched modelAndView object. and because my url use a path variable and this cause the recursive call.

so for my case, 1. if the initial request is /greet/edward and then it will try to find the view edward under /greet. and then it goes into the controller and the controller will return : Helloedward (see the source code here )and 2. then it will dispatch to the /greet/Helloedward and again, it will dispatch (by setting the mav.viewName) to /greet/HelloHelloedward (in DispatcherServlet and it will try to render it again in InternalResourceView)

and this cause the infinite loop.