Java 17 backend fails to handle pipe character in query parameter from frontend request

I’m working on a web application where my React frontend sends requests to a Java 17 backend. I’m running into an issue with a specific character in my query parameters.

The frontend makes a request like this:

http://localhost:3000/api/data/1234?search=categoryName|7

My backend controller looks like this:

@GetMapping(value = "/data/{dataId:[0-9]+}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity fetchDataRecord(@PathVariable("dataId") Long dataId,
        @RequestParam(value = "search", required = false) String searchTerm) throws Exception {
    // processing logic here
}

This setup worked perfectly when I was using Java 8. The search parameter would correctly receive the value ‘categoryName|7’ with the pipe symbol.

After upgrading to Java 17, the endpoint returns a 404 error and doesn’t seem to match the route at all. When I remove the pipe character from the parameter value, everything works normally again.

I need to keep both the Java 17 upgrade and the pipe character in my parameter values. Has anyone encountered this issue before?

Interesting - did you notice if this started with a specific Tomcat version? I'm curious if it's actually the Spring Boot version causing this rather than Java 17. What version of Spring Boot are you running exactly?

This happens because newer Java versions parse URLs more strictly. The pipe character needs to be URL-encoded when you pass it as a query parameter. Your frontend should encode it before sending the request - so categoryName|7 becomes categoryName%7C7. Just use encodeURIComponent() in your React code before adding it to the URL. If you can’t change the frontend right away, there’s a quick fix: add server.tomcat.relaxed-query-chars=| to your application properties. But encoding is the right way to handle this long-term.

Same issue here after upgrading. The newer Tomcat version is pickier about query parameters. Quick fix: add server.tomcat.relaxed-query-chars=| to your properties file. But ur better off URL encoding the pipe character on the frontend - just use encodeURIComponent.