PageableHandlerMethodArgumentResolver and qualifier delimiter - spring

We had an issue when trying to transform the parameters for the pagination and the sorting of an HTTP Request into a Pageable object in Spring Data/Spring MVC. Some of our sort parameters had an underscore character and when sorting on them we were getting an error. In the logs, these parameters were trimmed at the underscore character.
We have discovered that the org.springframework.data.web.PageableHandlerMethodArgumentResolver was using the underscore as default value for the qualifier delimiters. Now, we wonder if it's safe to modify this default value because we don't know what this qualifier delimiter is used for, and what consequence this would have.
The documentation of setQualifierDelimiter in the class PageableHandlerMethodArgumentResolver mentions:
The delimiter to be used between the qualifier and the actual page number
and size properties
So our questions: what is exactly the "qualifier delimiter" ? When is it used ?
Thanks for your help.

Searching into the documentation and code of Spring Data Web gave me the answer.
The qualifier delimiter is used in conjunction with the prefix. In the pageable arguments, it is the delimiter between the prefix and the page number argument, or between the prefix and the size argument. By default, the prefix is an empty string and, thus, the qualifier delimiter is not used. But, if you set the prefix, the qualifier delimiter will be used to parse the parameters of the http request.
Setting the prefix is useful if you have multiple tables with pagination in the same web page and these tables are updated via standard HTTP requests (not an AJAX query for each table separately). In that situation, the prefix allows to distinguish the http parameters for each table.
setQualifierDelimiter(String qualifierDelimiter):
the delimiter to be used between the qualifier and the actual page number and size properties.
setPrefix(String prefix):
configures a general prefix to be prepended to the page number and page size parameters.

Related

Accessing the parameter by dynamic name

How to access the parameter #{...} in Process configuration field if its name needs to be changed dynamically (for example, the name of this parameter is contained in some FlowFile attribute OR the name generating using expression language).
Illustrative example – for the LogMessage process, I have prepared several parameters in (msg1, msg2, msg3 etc.) that I would like to output depending on the attribute numofmessage
You can do it using evaluateELString()
${literal('{dynamic_${name}}'):prepend('#'):evaluateELString()}
Currently you cannot use EL inside of a parameter reference. If you put something like #{${abc}} it will look for a parameter named ${abc} and won't find one so it will be invalid.
You can only do the reverse, use parameter inside of EL, for example ${ #{abc}:replace('xxx', 'zzz') }.
In general, parameters are meant to be a better version/replacement for the existing variables functionality, but in this case variables may work better for you since variables are referenced through EL.

Spring ServletUriComponentsBuilder and square brackets in query params

I'm trying to use Spring's ServletUriComponentsBuilder to create paging next and prev links from the current request.
The problem I'm having is that the ServletUriComponentsBuilder.fromCurrentRequest() is not unencoding percent-encoded values like:
http://example.com/articles?page%5Bnumber%5D=2
The problem is uses could have called the page with unencoded square brackets like http://example.com/articles?page[number]=2 without any problems.
Spring Data is accepting both variants (both unencoded square brackets and encoded square brackets) in it's pageable argument resolver.
This to the fact that under water the Coyote web request get parameter is used which contains the unencoded param names.
Also Spring's #RequestParam("page[number]") accepts without any problem the encoded request like http://example.com/articles?page%5Bnumber%5D=2.
From the server side I always want to return percent encoded url's as per RFC 3986.
But there does not seem a way to this as the UriComponents query params might contain both encoded en uncoded names. Because to that, if I would call encode() on the builder the already encoded query params get encoded another time, but if would contain unencoded names toURI() will fail as an unencoded [ is not allowed.
Note that the url's might contain multiple query params besides paging, e.g. for filtering.
A request could come in like:
http://example.com/articles?filter[category]=food
And would return a response with a encoded next link like:
http://example.com/articles?page%5Bnumber%5D=2&filter%5Bcategory%5D=food
My workaround it to ignore ServletUriComponentsBuilder and simply get the request url and do so custom regexp replacing.
I know this is an older question and you also found a workaround. But did you try to use ServletUriComponentsBuilder's build() method?
Some kind of the following:
ServletUriComponentsBuilder.fromCurrentRequest().build().toUriString();
I had some issues when handling JSON Strings and this helped.

Importance of ? in ES query

how the query URL is formed in elastic search and why we have a ? as below.Does this ? have any importance.Sample =” /kibana-int/dashboard/log-analytics-s?1431600189554
1431600189554 appears to be a timestamp (UNIX timestamp w/milliseconds), likely used to prevent caching of requests. It's not necessary for ElasticSearch (which will ignore it entirely), but it means the browser treats every request as a new URL and fetches new data.
The "?" states that the rest of the URL will be parameters. As an example it's often used with the parameter "pretty" in ElasticSearch, when you query a mapping (like http://localhost:8080//_mapping?pretty). The "pretty" argument forces the return to be formatted in a way that is eye-friendly.
As a side note, the "&" character is used to separate arguments. For exemple http://localhost:8080//?lastname=foo&firstname=bar

What is the meaning of {id:.+} in a Spring MVC requestmapping handler method?

I came across a method in the controller. What is this id:.+ ??
#RequestMapping(value="/index/{endpoint}/{type}/{id:.+}", method=RequestMethod.POST, consumes=kContentType, produces=kProducesType)
#ResponseBody
public String indexData(#PathVariable(value="endpoint") String endpoint, #PathVariable(value="type") String type, #PathVariable(value="id") String id, #RequestBody String body, HttpServletRequest request) {
logger.debug("In web controller for endpoint " + endpoint);
return indexController.indexData(endpoint, type, id, body, getSecurityContextProvider(request));
}
The syntax of a path variable in a spring MVC controller requestmapping is {variable_name:regular_expression}. You can optionally omit the regular expression, which leads to what you see more often, {id}.
So, for the example /index/{endpoint}/{type}/{id:.+} the variable name is id and the regular expression is .+ (see below reference to spring docs).
The regular expression .+ is stating "match the metacharacter . one or more times". The '.' metacharacter represents any character including white space (though some implementations will not match newlines). See http://en.wikipedia.org/wiki/Regular_expression
The regular expression is being used to help Spring determine the value of the variable because you can have complex variable names or there might be other important information at the end of the path that would otherwise get sucked into the variable value if Spring just said "go until the end of the path" (eg. filename extensions or path variables).
It's possible that in your example, the id variable can contain special characters that would otherwise cause Spring to terminate the variable prematurely. I've run into this problem before when trying to use a filename that contained a file extension (foobar.jpg). Spring would return only the "foobar" part of the variable because Spring was assuming I wanted it to terminate the variable value at the period delimiter. So, in this case, to make sure that "id" matches the full value, you put the regex that tells Spring to go ahead and match everything between the last forward slash and the end of the path. SO Reference: Spring MVC #PathVariable getting truncated
Here's the excerpt from the Spring docs that deals with complex variable matching:
Sometimes you need more precision in defining URI template variables. Consider the URL "/spring-web/spring-web-3.0.5.jar". How do you break it down into multiple parts?
The #RequestMapping annotation supports the use of regular expressions in URI template variables. The syntax is {varName:regex} where the first part defines the variable name and the second - the regular expression."
Here is their (fairly complex) example:
#RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{extension:\\.[a-z]+}")
public void handle(#PathVariable String version, #PathVariable String extension) {
// ...
}
Source: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html
The example they provide shows how you perform complex mappings from requests to controller method paramters that you wouldn't be able to without using a regular expression.

Spring REST URL Encoding Scheme: %20 or + Which one?

I made a Spring REST application where you can perform CRUD operations based on HTTP methods of POST, PUT, GET, DELETE. I have the typical URI template of
http://host/root/{id}/{name}/{address} and etc.
We have a client who is accessing this REST service. Apparently they are sending parameters for multi-word name and address in the following form:
http://host/root/11/John+Smith/10+Las+Vegas+USA
They are using the HTML encoding scheme based on application/x-www-form-urlencoded type. According to the article in Wikipedia
The application/x-www-form-urlencoded
type
The encoding used by default is based
on a very early version of the general
URI percent-encoding rules, with a
number of modifications such as
newline normalization and replacing
spaces with "+" instead of "%20". -
http://en.wikipedia.org/wiki/Percent-encoding
However it appears the standard URL encoding scheme is to use %20 in replacing spaces in URI templates. Which one is correct?
My Spring REST automatically converts %20 to spaces. It's interpreted correctly. I'm using Spring 3.0.4. When + is met by my REST service, it's accepted as is. Of course when I put validation to exclude +, it is indeed excluded as expected.
Am I within standards or are there such double standards? Or is the client using an ancient scheme?
The point is that application/x-www-form-urlencoded can be used only in request parameters, whereas percent encoding is also supported in a path.
So,
http://host/root/11/?name=John+Smith&address=10+Las+Vegas+USA
is fine and will be properly decoded by Spring MVC, but
http://host/root/11/John+Smith/10+Las+Vegas+USA
is wrong and Spring MVC doesn't decode it, because the following form should be used instead:
http://host/root/11/John%20Smith/10%20Las%20Vegas%20USA

Resources