-
Notifications
You must be signed in to change notification settings - Fork 472
Request param value with curly braces throws IllegalArgumentException #335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
According to RFC 1738, curly braces are illegal in URLs, so what you have is actually not a valid URL. if your query parameter has a JSON value, you should URL encode it. |
@vivin, seems spring-hateoas should do this automatically |
Oh, my mistake. I thought that was a request coming in. This is a URL that Spring HATEOAS generates? |
Parameter came as URL encoded value, then spring-mvc automatically decodes it and if I pass it to the linkTo method, it throws strange exception. |
Yeah, I'd imagine that it should urlencode it on its own. |
There appears no way around this. If one encodes the query parameter, it ends up double-encoded. An example of how we are encountering this error:
Note this is not JSON - our domain has text with curly braces in it. It appears Spring HATEOAS is trying to do template variable expansion on a value passed into the linkTo/methodOn controller signature. |
We are just gonna do a workaround for this, which is to call
Then we call a method that knows about that particular parameters (in our case, it is called "query") and adds it into the URL manually:
Obviously this can be improved upon, made more generic, etc. but ideally we should not have to do it. |
So, i hit this once per quarter or so, and it seems to always be a user error: I'll annotate the request method arguments as @PathParam. smh Should be @PathVariable. @PathVariable for the win. fwiw |
I just crafted a test case that has a controller like this: @RestController
static class RequestParamBasedController {
@GetMapping
CollectionModel<FileSystemResource> listFiles(@RequestParam("q") String query) {
Link self = linkTo(methodOn(RequestParamBasedController.class).listFiles(query)).withSelfRel();
return CollectionModel.of(Collections.emptyList(), self);
}
} And the tests look like this: @Test
void requestParamBasedLink() {
Link link = linkTo(methodOn(RequestParamBasedController.class).listFiles("my search")).withSelfRel();
assertThat(link.getHref()).isEqualTo("http://localhost?q=my%20search");
assertThat(link.isTemplated()).isFalse();
link = linkTo(methodOn(RequestParamBasedController.class).listFiles("{\"foo\": \"bar\"}")).withSelfRel();
assertThat(link.getHref()).isEqualTo("http://localhost?q=%7B%22foo%22:%20%22bar%22%7D");
assertThat(link.isTemplated()).isFalse();
link = linkTo(methodOn(RequestParamBasedController.class).listFiles(null)).withSelfRel();
assertThat(link.getHref()).isEqualTo("http://localhost?q={q}");
assertThat(link.isTemplated()).isTrue();
} Does this not create things properly now since #593. |
Example:
If
q
contains curly braces (and it does because it's JSON) then linkTo throwsGET http://localhost:8080/files?q={"foo": "bar"}
The text was updated successfully, but these errors were encountered: