How to Fix Spring Boot 3 Trailing Slash URL Mismatch After Upgrade
This article explains why URL mappings that worked in Spring Boot 2.x break after upgrading to Spring Boot 3, demonstrates the issue with trailing slashes, and provides three practical solutions—including a filter, Nginx rule, and Spring Cloud Gateway optimization—to restore correct routing.
In this article we discuss the changes to URL matching introduced in Spring Boot 3 (Spring 6) and how they affect existing applications after upgrading from 2.x.
Problem Description
After upgrading a project to Spring Boot 3.1, requests that previously matched a controller no longer work when the URL ends with a trailing slash.
Problem Reproduction
@RestController
public class DemoController {
@GetMapping("/demo/path")
public String path() {
return "Hello lengleng";
}
}Request
/demo/pathreturns the expected result.
Request
/demo/path/returns 404.
Solution
Method 1: Enable trailing‑slash matching (not recommended)
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseTrailingSlashMatch(true);
}
}The
setUseTrailingSlashMatchmethod is deprecated in Spring 6 and will be removed in future versions.
Method 2: Create a filter to strip the trailing slash
public class TrailingSlashRedirectFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String path = httpRequest.getRequestURI();
if (path.endsWith("/")) {
String newPath = path.substring(0, path.length() - 1);
HttpServletRequest newRequest = new CustomHttpServletRequestWrapper(httpRequest, newPath);
chain.doFilter(newRequest, response);
} else {
chain.doFilter(request, response);
}
}
private static class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final String newPath;
public CustomHttpServletRequestWrapper(HttpServletRequest request, String newPath) {
super(request);
this.newPath = newPath;
}
@Override
public String getRequestURI() {
return newPath;
}
@Override
public StringBuffer getRequestURL() {
StringBuffer url = new StringBuffer();
url.append(getScheme()).append("://").append(getServerName()).append(":")
.append(getServerPort()).append(newPath);
return url;
}
}
}Method 3: Nginx redirect configuration
location / {
if ($request_uri ~ ^(.+)/$) {
return 301 $1;
}
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}Advanced: Optimization in PIG microservice architecture
When using Spring Cloud Gateway, the request‑path interceptor rewrites URLs and automatically removes the trailing slash, preventing the 404 error.
Java Architecture Diary
Committed to sharing original, high‑quality technical articles; no fluff or promotional content.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.