jsr339-experts@jax-rs-spec.java.net

[jsr339-experts] Re: HEADS-UP: Encoding values of UriBuilder template parameters

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Mon, 14 Nov 2011 10:55:31 +0000

On 11/11/11 19:23, Markus KARG wrote:
> Well, in fact I do not see any confusing in URI encoding, but a lot of confusion in the description of the way JAX-RS handles it. It is just not natural that one has to read *two* JavaDoc locations (path() AND build()) to understand the whole story. It all should be described in one single place in few but clear words. Not scattered among several locations.
>

In my previous response I tried to sympathize a bit with the plight of
the team which spent two days on the URI encoding issue, but you having
none of that and just keep blaming the documentation which I just find
ridiculous, sorry.

This particular issue is very straightforward to resolve, the
documentation for build() states:
"Build a URI, using the supplied values in order to replace any URI
template parameters. Values are converted to String using their toString
method and are then ***encoded to match the rules of the URI component
to which they pertain***"

What else one need to tell the users for them to figure out that they
need to go and check the documentation of path(), segment(), query(), etc ?

IMHO, if someone gets how URI has to be encoded then surely the arguable
deficiencies of the docs won't stop him/her from figuring out what the
end result has to be. And that was my point. Now, I had my share of
confusion to do with the way build() and buildFromEncoded() are supposed
to operate but that is another story...

Sergey


>> -----Original Message-----
>> From: Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>> Sent: Mittwoch, 9. November 2011 13:22
>> To: jsr339-experts_at_jax-rs-spec.java.net
>> Subject: [jsr339-experts] Re: HEADS-UP: Encoding values of UriBuilder
>> template parameters
>>
>> Hi Markus, just reread your message, kind of skipped through it
>> yesterday :-) On 08/11/11 17:37, Markus KARG wrote:
>>> I totally agree with you that the API must be absolutely unambiguous.
>>> But exactly this is the point: It IS ambiguous currently. See, our
>>> complete team of graduated engineers totally misunderstood how path /
>>> segment / build is intended to work in the case of slash encoding.
>>> After spending two days (then we invented a workaround). So either we
>>> all are dumb idiots (what might be the case), OR the API IS
>> ambiguous.
>>> I won't actually say that there ain't a possibility that we ARE dumb
>>> idiots, really, but in fact, I do more believe that this particular
>>> piece of JavaDoc is just not clearly documented regarding what
>> happens
>>> when a slash is found in build(). If the solution is to use segment
>>> instead of path, well, that's pretty nice. But THEN we should at
>> least
>>> improve the JavaDocs so dumb idiots like our team will understand how
>>> the F* one can get %2F in the end when putting in a slash into
>>> build(). Particularly, build() should clearly say what happens with
>>> slashes for parameter in
>> path() / segment() placeholders, as the encoding is described in
>> build(), and readers do not expect to check a second location to get
>> the whole story.
>>>
>> Well, I think all to do with URI encoding is confusing and one needs to
>> be really well prepared, I can't assert that I really am myself, but I
>> think as far as this particular issue is concerned I believe the rules
>> are kind of simple, the way the values provided to build() have to be
>> encoded according to the rules of particular URI components.
>> In this case both path() and segment() all identify the URI path one,
>> but we also have segment() further specifying that a "/" has to be
>> encoded. Agreed that some better documentation can help
>>
>> Cheers, Sergey
>>
>>> Regards
>>> Markus
>>>
>>>> -----Original Message-----
>>>> From: Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>>>> Sent: Montag, 7. November 2011 11:41
>>>> To: jsr339-experts_at_jax-rs-spec.java.net
>>>> Subject: [jsr339-experts] Re: HEADS-UP: Encoding values of
>> UriBuilder
>>>> template parameters
>>>>
>>>> On 06/11/11 13:51, Markus KARG wrote:
>>>>> Sergey,
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>>>>>> Sent: Mittwoch, 2. November 2011 11:13
>>>>>> To: jsr339-experts_at_jax-rs-spec.java.net
>>>>>> Subject: [jsr339-experts] Re: HEADS-UP: Encoding values of
>>>> UriBuilder
>>>>>> template parameters
>>>>>>
>>>>>> On 01/11/11 18:37, Markus KARG wrote:
>>>>>>>>> what the JIRA issue actually is talking about is not the *name*
>>>> of
>>>>>>>> the parameter, but _solely_ slashes contained in *values*
>>>>>>>> provided
>>>>>> to
>>>>>>>> *build()* (maybe this is not clear in JIRA?).
>>>>>>>> That is the value, with UriBuilder one can just do
>>>>>>>> path("bar").build();
>>>>>>> Wrong. Check http://jackson.codehaus.org/javadoc/jax-
>>>>>>>
>> rs/1.0/javax/ws/rs/core/UriBuilder.html#build(java.lang.Object...):
>>>>>>> Certainly you can provide values to build().
>>>>>>
>>>>>> What is wrong ? Have I said you can't pass pass values to build ?
>>>>>> Look at my last response again please.
>>>>>
>>>>> Well, you response said that one can just do path("bar").build() --
>>>>> I
>>>> don't see any parameters in build() there. So yes, you said that --
>>>> or at least I read it that way.
>>>>>
>>>>
>>>> Sorry, I guess I should've used 'also' instead of 'just'...
>>>>
>>>>>>> Actually this issue is just about the values provided to *build*,
>>>>>>> not to *path*. In fact, I opened that JIRA issue *because* I
>>>>>>> experienced the described problem with values passed into
>> *build*.
>>>>>> Well. IMHO whether it's a value which is passed directly to path()
>>>> or
>>>>>> to build(), it probably needs to be consistent.
>>>>>> In other words, the output of
>>>>>>
>>>>>> builder.path(value).build()
>>>>>>
>>>>>> and
>>>>>>
>>>>>> builder.path("{value}").build(value)
>>>>>>
>>>>>> should produce the same output, no ?
>>>>>>
>>>>>> same for segment calls...
>>>>>
>>>>> I think here is the difference in out visions. I actually expect it
>>>> TO BE a difference wheter I pass a value to path(), or to build().
>>>> Otherwise it wouldn't make much sense to have either way to do it.
>>>> The sense of path() is to define position and semantics of
>> parameters.
>>>>
>>>>
>>>> From
>>>>
>> http://jsr311.java.net/nonav/releases/1.1/javax/ws/rs/core/UriBuilder
>>>> .h
>>>> tml#path(java.lang.String):
>>>>
>>>> "Append path to the existing path. When constructing the final path,
>>>> a '/' separator will be inserted between the existing path and the
>>>> supplied path if necessary. Existing '/' characters are preserved
>>>> thus a single value can represent multiple URI path segments."
>>>>
>>>> It's clear that a single path values may represent multiple
>> segments.
>>>>
>>>> From
>>>>
>> http://jsr311.java.net/nonav/releases/1.1/javax/ws/rs/core/UriBuilder
>>>> .h
>>>> tml#segment(java.lang.String...):
>>>>
>>>> "Append path segments to the existing path. When constructing the
>>>> final path, a '/' separator will be inserted between the existing
>>>> path and the first path segment if necessary and each supplied
>>>> segment will also be separated by '/'. Existing '/' characters are
>>>> encoded thus a single value can only represent a single URI path
>> segment."
>>>>
>>>> It's also plain obvious that a single parameter to segment(...)
>>>> represents a single URI path segment.
>>>>
>>>> I don't care what build(...) docs say, I'm not even there yet, if I
>>>> do
>>>> segment("a/b") I need to get "/" encoded but keep "/" if I do
>>>> path("a/b").
>>>>
>>>> The sense of build is to encode values. At least that is what
>>>> makes sense from the view of a user, and it is what the javadocs of
>>>> JAX-RS
>>>> 1.0 say.
>>>>>
>>>>> Anyway, this is what users need.
>>>>
>>>> Really ? Users need a simple, unambiguous and straightforward api
>>>> which does not give a space for multiple interpretations of how this
>>>> API will work.
>>>>
>>>>> So we have to find a way to make it work. If you have a better
>>>> solution how users can write applications without thinking about
>>>> encoding, please present it. Until then, I do not see another way of
>>>> working with data that contains slashes.
>>>>>
>>>>
>>>> Lets focus at the issue at hand.
>>>> Segment value, either passed to build() or buildFromEncoded() or
>>>> directly to segment() represents a single URI path segment. That is
>>>> all.
>>>> Hence the "/" characters needs to be encoded but in case of
>>>> buildFromEncoded() a care should be taken to avoid the
>>>> double-encoding
>>>>
>>>> Sergey
>>>>
>>>>> Regards
>>>>> Markus
>>>>>
>>>>>>
>>>>>> Sergey
>>>>>>
>>>>>>>>> Regarding your example: (1) http is part of the scheme, not
>> part
>>>>>>>>> of
>>>>>>>> the path, so the below code is rather error prone. Shouldn't we
>>>>>>>> define specs for correct use instead? (2) As the slashes are
>> part
>>>>>>>> of the
>>>>>>>> *name* of the parameter, and as it just makes no sense to render
>>>>>>>> the URI without providing a value to each parameter in this
>> case,
>>>>>>>> there is no need to touch the name of the parameter, so you will
>>>>>>>> not
>>>>>> encode it.
>>>>>>>>>
>>>>>>>> Cheers, Sergey
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Regards
>>>>>>>>> Markus
>>>>>>>>>
>>>>>>>>>> -----Original Message-----
>>>>>>>>>> From: Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>>>>>>>>>> Sent: Dienstag, 1. November 2011 18:07
>>>>>>>>>> To: jsr339-experts_at_jax-rs-spec.java.net
>>>>>>>>>> Subject: [jsr339-experts] Re: HEADS-UP: Encoding values of
>>>>>>>> UriBuilder
>>>>>>>>>> template parameters
>>>>>>>>>>
>>>>>>>>>> just recently we had a case like this:
>>>>>>>>>>
>>>>>>>>>> builder.path("{http://myns}service").build().
>>>>>>>>>>
>>>>>>>>>> Does "//" have to be encoded or not ?
>>>>>>>>>> I think if I do want to encode then saying
>>>>>>>>>>
>>>>>>>>>> builder.segment("{http://myns}service").build().
>>>>>>>>>>
>>>>>>>>>> makes sense.
>>>>>>>>>>
>>>>>>>>>> However, perhaps this should be treated differently when
>>>> template
>>>>>>>>>> parameters are involved, but I'd not be worried about it
>>>>>>>>>>
>>>>>>>>>> Sergey
>>>>>>>>>>
>>>>>>>>>> On 01/11/11 16:38, Markus KARG wrote:
>>>>>>>>>>> Sorry for the late answer, had been out of office.
>>>>>>>>>>>
>>>>>>>>>>> Actually I have to disagree to your conclusion! I do not see
>>>> any
>>>>>>>>>> difference in path parameters vs. segment parameters. I think
>>>>>>>>>> your fault is that you think encoding is depentent of the
>>>> method,
>>>>>>>>>> but
>>>>>> it
>>>>>>>>>> is solely dependend of the target. And the target of both,
>> path
>>>>>> and
>>>>>>>>>> segment, is the URI's path -- so there is no difference (while
>>>>>>>>>> there is one for the query part, obviously)! In fact, *both
>>>>>> places*
>>>>>>>>>> have
>>>>>>>> to
>>>>>>>>>> resolve to an encoded form, as *both* have to take respect of
>>>> the
>>>>>>>>>> target, which is the URI's path:
>>>>>>>>>>>
>>>>>>>>>>> UriBuilder.path("abc/def/{arg1}).segment("123", "456",
>>>>>>>>>>> "{arg1}").build("A/B")
>>>>>>>>>>>
>>>>>>>>>>> *obviously* have to resolve exactly to:
>>>>>>>>>>>
>>>>>>>>>>> abc/def/A%2FB/123/456/A%2FB
>>>>>>>>>>>
>>>>>>>>>>> and to nothing else!
>>>>>>>>>>>
>>>>>>>>>>> (If arg1 would be a queryParam, too, THEN (!) it would stay
>> as
>>>>>> A/B
>>>>>>>>>>> as a slash is valid in the query part of the URI!)
>>>>>>>>>>>
>>>>>>>>>>> Can you please explain why you think it would be beneficial
>> to
>>>>>>>> *not*
>>>>>>>>>> encode the provided value? In what case would that make any
>>>> sense?
>>>>>>>>>> And what is your source (spec)?
>>>>>>>>>>>
>>>>>>>>>>> The sole difference between path and segment is only that
>>>>>>>>>>> using
>>>>>>>>>> path() you can supply a complete chain of segments, i. e.
>>>>>>>>>> path("abc/def"), while you have to provide a set of segments
>>>>>>>>>> using segment(), i. e. segment ("abc", "def"). In fact, it is
>> a
>>>>>>>>>> fault to provide a slash to a segment as by URI's definition,
>> a
>>>>>>>>>> segment
>>>>>>>> cannot
>>>>>>>>>> contain a slash.
>>>>>>>>>>>
>>>>>>>>>>> But, that has nothing to do with encoding! Encoding will
>>>>>>>>>>> *always*
>>>>>>>> be
>>>>>>>>>> applied to any build() paramater's value *according to the
>>>>>> template
>>>>>>>>>> parameter's position in the template"! That means, a slash
>> must
>>>>>>>>>> be encoded in a path() or segment() template, but not in a
>>>>>>>>>> queryParam() template. And, whatever is given to path() or
>>>>>>>>>> segment(), will itself get never encoded, as only the values
>>>>>>>>>> provided to build() are
>>>>>>>> getting
>>>>>>>>>> encoded.
>>>>>>>>>>>
>>>>>>>>>>> Everything else just makes no sense to me.
>>>>>>>>>>>
>>>>>>>>>>> Or can you provide a real world example, where it makes sense
>>>> to
>>>>>>>>>> either encode the value given to path() or segment() / not to
>>>>>>>>>> encode the value given to build()?
>>>>>>>>>>>
>>>>>>>>>>> Regards
>>>>>>>>>>> Markus
>>>>>>>>>>>
>>>>>>>>>>>> -----Original Message-----
>>>>>>>>>>>> From: Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
>>>>>>>>>>>> Sent: Dienstag, 25. Oktober 2011 23:27
>>>>>>>>>>>> To: jsr339-experts_at_jax-rs-spec.java.net
>>>>>>>>>>>> Subject: [jsr339-experts] Re: HEADS-UP: Encoding values of
>>>>>>>>>> UriBuilder
>>>>>>>>>>>> template parameters
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On 25/10/11 20:50, Marek Potociar wrote:
>>>>>>>>>>>>> Experts,
>>>>>>>>>>>>> please read through the following CRITICAL issue& the
>>>>>> attached
>>>>>>>>>>>> comments:
>>>>>>>>>>>>>
>>>>>>>>>>>>> http://java.net/jira/browse/JAX_RS_SPEC-70
>>>>>>>>>>>>>
>>>>>>>>>>>>> I am interested in your feedback to the conclusion I
>>>>>>>>>>>>> provided
>>>>>> in
>>>>>>>>>>>>> my comment attached to the issue. Please provide your
>>>> feedback
>>>>>>>>>>>>> by Monday
>>>>>>>>>>>> next week Oct 31, 2011 CoB.
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> agreed
>>>>>>>>>>>>
>>>>>>>>>>>>> Feel free to attach the feedback or any new comments
>>>>>>>>>>>>> directly
>>>>>> to
>>>>>>>>>> the
>>>>>>>>>>>> issue.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Many thanks,
>>>>>>>>>>>>> Marek
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>


-- 
Sergey Beryozkin
http://sberyozkin.blogspot.com
Talend - http://www.talend.com