Search code examples
javaspring-bootresturlencode

Odd behavior with URL encoded string when used with RestTemplate.delete()


I have a Java Spring Boot application (Java 8 JDK) that makes calls to a REST service. For the delete resource case, I need to specify the path as follows: /api/v4/projects/<URL encoded project path>, where the project path is typically represented as a parent "group" followed by the project name. For example: my-group/my-project. So, when I invoke the delete case, the example path needs to be my-group%2Fmy-project.

I am using java.net.URLEncoder.encode(value, StandardCharsets.UTF_8.toString()) to do the encoding and it converts the example path to what it needs to be (the group is test and the project is test-cold-storage):

https://<removed>/api/v4/projects/test%2Ftest-cold-storage

When I invoke the call, however, it fails. I have an interceptor that prints out the details of the request being made. It's showing something unexpected.

2022-07-18 15:49:18.030  INFO 21888 --- [           main] c.b.d.c.c.CustomRequestInterceptor       : Request:
2022-07-18 15:49:18.030  INFO 21888 --- [           main] c.b.d.c.c.CustomRequestInterceptor       :   URI: https://<removed>/api/v4/projects/test%252Ftest-cold-storage
2022-07-18 15:49:18.030  INFO 21888 --- [           main] c.b.d.c.c.CustomRequestInterceptor       :   Method: DELETE

It looks like it's being encoded again (maybe?). 0x25 = '%' and 0x2F = '/'. If I do it without encoding the group/path, no encoding occurs and it fails again.

2022-07-19 07:47:02.146  INFO 5200 --- [           main] c.b.d.c.c.CustomRequestInterceptor       : Request:
2022-07-19 07:47:02.147  INFO 5200 --- [           main] c.b.d.c.c.CustomRequestInterceptor       :   URI: https://<removed>/api/v4/projects/test/test-cold-storage
2022-07-19 07:47:02.147  INFO 5200 --- [           main] c.b.d.c.c.CustomRequestInterceptor       :   Method: DELETE

Has anyone else run into this? Is there some setting in the configuration of the RestTemplate object that affects this?

UPDATE

I have managed to trace execution in the debugger and found that it is encoding the URL. This is happening in org.springframework.web.util.DefaultUriBuilderFactory.createURI().

I don't know if this information is helpful.


Solution

  • Figured it out. I needed to pass the project path (i.e. test/test-cold-storage) as a URI variable instead of tacking it on the end of the URL. The endpoint URL need to change as follows:

    String endpointURL = baseURL + GITLAB_REST_API + "projects/{path}";

    and the delete call changed to add URI variable (projectPath):

    template.delete(endpointURL, projectPath);, where in this example projectPath is test/test-cold-storage.