Backend Development 5 min read

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.

Java Architecture Diary
Java Architecture Diary
Java Architecture Diary
How to Fix Spring Boot 3 Trailing Slash URL Mismatch After Upgrade

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/path

returns 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

setUseTrailingSlashMatch

method 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.

spring bootNginxSpring MVCSpring Cloud Gatewayfiltertrailing slashurl-matching
Java Architecture Diary
Written by

Java Architecture Diary

Committed to sharing original, high‑quality technical articles; no fluff or promotional content.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.