Hi John
URITemplate was not escaping '*', which alongside with '.' seems to be the only
two characters are also used as reserved characteres
in regexs, '-' seems tp be ok... Fixed on mainline
thanks for raising this issue and please continue stressing the CXF JAXRS with
some real-world URIs :-)
cheers, Sergey
----- Original Message -----
From: "John Klassa" <[email protected]>
To: "Sergey Beryozkin" <[email protected]>
Cc: <[email protected]>
Sent: Friday, December 18, 2009 2:05 PM
Subject: Re: bug in URITemplate?
Hi Sergey,
By way of background, the result of pdq.getName() isn't something that goes through the CXF machinery until this point in time (when
I want to put it into a URI). I fetch it from a back-end database, and then want to put it into a URI to use in an xlink. Put
differently, it's not something I get from a query parameter (for example), and could preserve an encoding on. It's just a value
that needs to go into a URI (the URI for a "search" resource, in my case, is "/search/{USERNAME}/{NAMEOFSEARCH}").
(I'm actually running into this same thing on the unit test side, as well, when I try to use WebClient to fetch a URI with a "*" in
it. In particular, when the server side generates an xlink URI with a "*" in it, and my unit test code fetches the contents of that
URI in order to make sure that the xlink points to the right thing, it bombs. See attached ZIP file with test case in it.)
I'd actually tried HttpUtils.pathEncode() already, as in:
...path(HttpUtils.pathEncode(pdq.getName()))...
but pathEncode() doesn't encode the "*". As a workaround, I'd been turning "*" into "SOMETHINGUGLY" prior to the UriBuilder.path()
call, then building the URI, then turning "SOMETHINGUGLY" back into "*" in the final URI. That works (on the server end of things),
but doesn't seem "right". :-) On the client side, it still causes a bomb (per my previous paragraph), unless I then go so far as to
manually turn "*" into "%2A". Only then can my unit test code successfully fetch the resulting URI.
It seems that "*" is a legitimate URI character (see section 2.3 of http://www.ietf.org/rfc/rfc2396.txt). So, pathEncode() seems to
be doing the right thing by not encoding the "*". I'm just not sure how to get CXF to take it, and use it in a URI, without the
"something ugly" workaround I described... And again, that applies to both server- and client-level code (because WebClient seems
to use UriTemplate, as well).
Thanks!
JK
--------------------------------------------------------------------------------
On Dec 18, 2009, at 8:21 AM, Sergey Beryozkin wrote:
Actually, the problem seems to do with the fact that UriBuilderImpl has assumed
that unencoded
"** Web Query" contains template variables...
pdq.getName() returns a decoded (query sequence).
One possible option is to add @Encoded to the corresponding QueryParam declaration and then pass this (still encoded) value to
UriBuilder but the problem here is that some of the characters which may not be valid in queries and thus are encoded may be valid
in path components, so no need to encode them there. It should still work though...
See, if UriBuilder.path(String value) will attempt to encode the value then it may loose the information about the template
parameters a given path value may contain. ex, "bar{id}".
So try either preserving the encoded information, when getting it from the
query param, or do
builder.path(org.apache.cxf.jaxrs.utils.HttpUtils.pathEncode(pdq.getName()));
cheers, Sergey
Hi John
If encoded values are present then you need to use
UriBuilder.buildEncoded()
give it a try please. CXF JAXRS proxy-based api always uses
UriBuilder.buildEncoded()
Sergey
----- Original Message ----- From: "John Klassa" <[email protected]>
To: <[email protected]>
Sent: Thursday, December 17, 2009 1:32 PM
Subject: bug in URITemplate?
This code:
return getBaseURI(info) + UriBuilder.fromResource(SearchResource.class)
.path(pdq.getOwner())
.path(pdq.getName())
.build()
.toString();
dies thusly:
java.util.regex.Pattern.error(Pattern.java:1713)
java.util.regex.Pattern.sequence(Pattern.java:1878)
java.util.regex.Pattern.expr(Pattern.java:1752)
java.util.regex.Pattern.compile(Pattern.java:1460)
java.util.regex.Pattern.<init>(Pattern.java:1133)
java.util.regex.Pattern.compile(Pattern.java:823)
org.apache.cxf.jaxrs.model.URITemplate.<init>(URITemplate.java:89)
org.apache.cxf.jaxrs.impl.UriBuilderImpl.substituteVarargs(UriBuilderImpl.java:131)
org.apache.cxf.jaxrs.impl.UriBuilderImpl.doBuild(UriBuilderImpl.java:80)
org.apache.cxf.jaxrs.impl.UriBuilderImpl.build(UriBuilderImpl.java:74)
com.cisco.cdets.wsapi.resources.SearchResource.buildURI(SearchResource.java:132)
when the getName() call happens to return something like "** Web Query" (with asterisks). I had assumed that the CXF methods
would URL escape the information I pass in, in situations like this... I'm guessing that's either not the case, or perhaps
there's a bug?
As a best practice, in general, should I be escaping these sorts of values
myself?
FWIW, I'm using CXF 2.2.3.
Thanks!