users@jax-rs-spec.java.net

[jax-rs-spec users] [jsr339-experts] Re: Re: HEADS-UP: Encoding values of UriBuilder template parameters

From: Markus KARG <markus_at_headcrashing.eu>
Date: Fri, 23 Dec 2011 13:43:16 +0100

> The situation with path(Class) is completely different ? The case where
> we are reading from the legacy DB is about submitting the values we do
> not control to UriBuilder. We are in control when annotating the
> resource classes.

No that exactly is the case we talk about: The annotation is given by the
programmer and it provides the path template given to .path(). But the value
provided to .build() is taken form a database and must get encoded ALWAYS.
That is what we discuss in this thread: The fact that slashes taken from
databases and given to .build() are NOT encoded currently but MUST get
encoded ALWAYS as those NEVER are intended to be path separators but ALWAYS
are intended to be DATA.

> > (c) As described earlier in depth, segment is defined in the RFC as a
> > part of the path element (not as something different to path), so
> > without improved JavaDocs people will not assume to find different
> > encoding rules for .path() and .segment(). It is counterintuitive
> that
> > it is up to the
> > *declaration* method how the encoding works like, as people are used
> > to other templating mechanisms like JDBC where this plays no role (it
> > ALWAYS encodes data, even if not necessary, as people could fill in
> > unencoded values by .path(variable) instead of
> > .path("{x}").build(variable) -- which is much more straightforward).
> >
> >> 2. What happens with builder.segment("{bar}").path("{foo}") and a
> >> value 'true' passed to a new overload, where a "{bar}" substitution
> >> will also contain "/" characters. I feel at the moment that given
> >> that both
> >> segment() and path() operate on the same URI component this extra
> >> flag will confuse people like me at least a lot
> >
> > As 'true' means 'always encode all values' it will enforce complete
> > encoding. You will get %2F for each slash in both, the values for bar
> > and foo.
> >
> > Rule: As long as you pass 'true' to the new overload, you can simply
> > pass variables to .segment() and .path() to get slashes ALWAYS, and
> > simply pass variables to .build() to get %2F ALWAYS. This rule is
> much
> > simpler to understand than the current (default, 'false') behaviour.
> > Nothing to think really. Just pass 'true' and decide whether you want
> > slashs (--> .segment(x), .path(x)) or your want %2F --> .build(x)).
> >
> I guess I'm really slow,
>
> What happens if I do segment("a/x/c") and pass 'false' ? Guess we
> should get "a/x/c" as this boolean applies to template vars, right ?

YES, as the new boolean only decides what to do with VALUES provided to
.BUILD(). LITERALS provided to .SEGMENT() or .PATH() are OUT OF SCOPE of
this thread.

> How about
> segment("{x}") and false, should not we get "a%2Fx%2Fc" ?

Marek, your new parameter, your business, your turn. ;-)

> > Hope that you see the simplicity in this new overload?
> >
>
> I see better why you and Marek see it improving the situation. I won't
> rush with my final conclusion this time, but so far what I see is that
> when we have a case where
> we do path("{a}") and seeing the substitution value (say a key read
> from the legacy data source and similar) still containing "/" then we
> are simply doing a wrong code, we should be doing
>
> segment("{a}")

BUT YOU CANNOT IF THE TEMPLATE IS TAKEN FROM SOMEWHERE ELESE AS ONE COMPLETE
PATH STRING, E. G. FROM EXTERNAL CONFIGURATION OR FROM @PATH, AS THERE IS
NEITHER SEGMENT(STRING) WHICH WILL SPLIT INTO SEGMENTS (AS IT THINKS IT IS A
SINGLE SEGMENT), NOR THERE IS SEGMENT(CLASS) NOR SEGMENT(CLASS, STRING). GOT
THE PROBLEM NOW?

Don't know how often I explained already on this list... ;-(

Regards
Markus