javajava-17

In a Java 17 app, is it possible to send an endpoint string from the frontend to the backend with a | character in a @RequestParam value?


I have an Angular front-end app that needs to send the following endpoint string to a Java 17 back-end.

Note the | character towards the end.

http://localhost:8080/revision/2609?filter=ruleNumber|4

And here's the endpoint in the backend:

@GetMapping(value = "/revision/{revisionId:[0-9][0-9]*}", produces = 
MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity getHazardBlock(@PathVariable("revisionId") Long revisionId,
        @RequestParam(value = "filter", required = false) String filter) throws ServiceException {

This worked fine when the back-end was running off of Java 8. The @RequestParam "filter" came through as 'ruleNumber|4'.

Now that I've upgraded to Java 17, however, it can't even find the back-end endpoint.

It's definitely dying on the | character. As long as I don't include the | character it hits the endpoint fine.

And yes, I have to do the upgrade to Java 17 and there has to be a | character in the value.

Any suggestions?


Solution

  • I attempted to test how the String is bound to the request parameter. This was the output I saw on my screen:

    2025-04-14 15:52:19.310  INFO 384861 [nio-8080-exec-1] o.a.j.l.DirectJDKLog                     : Error parsing HTTP request header
     Note: further occurrences of HTTP request parsing errors will be logged at DEBUG level.
    
    java.lang.IllegalArgumentException: Invalid character found in the request target [/revision?filter=rule|4 ]. The valid characters are defined in RFC 7230 and RFC 3986
        at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:482)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:257)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
        at java.base/java.lang.Thread.run(Thread.java:840)
    

    So, yes, while it is not a reserved character, it does not seem to be a valid character either. The valid characters are defined in RFC 7230 and RFC 3986. There are some solutions to this such as having relaxed query chars https://stackoverflow.com/a/77664676/16034206 besides URL encoding the character |