Summary
The issue occurs when accessing the /login endpoint in a Spring Boot 4.0.2 application with Thymeleaf, resulting in a 404 error despite a valid @GetMapping("/login") mapping in the @Controller. The root cause is Spring Boot’s static resource handling overriding the controller mapping.
Root Cause
- Static resource precedence: Spring Boot serves static resources (e.g., HTML, CSS) before invoking controller methods.
- Missing
classpath:/static/configuration: The/loginendpoint conflicts with a nonexistent static resource, causing the 404 error.
Why This Happens in Real Systems
- Default behavior: Spring Boot automatically serves static content from
src/main/resources/staticorsrc/main/resources/public. - Path collision: When a controller mapping matches a static resource path, the static resource takes precedence.
Real-World Impact
- User experience: Users encounter broken links or error pages instead of the intended login form.
- Developer confusion: Junior engineers may mistakenly assume the controller mapping is incorrect.
Example or Code
package com.smart888.www.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class RootController {
@GetMapping("/")
public String index() { return "index"; }
@GetMapping("/login")
public String login() { return "login"; }
}
How Senior Engineers Fix It
- Rename the endpoint: Change the controller mapping to a non-conflicting path (e.g.,
/login-page). - Disable static resource handling: Configure
spring.mvc.static-path-patternto exclude the conflicting path. - Use a prefix: Add a prefix to all controller mappings (e.g.,
/app/login).
Why Juniors Miss It
- Lack of understanding: Juniors often overlook Spring Boot’s static resource precedence over controller mappings.
- Assumption of isolation: They assume controller mappings and static resources are completely isolated, leading to path collisions.