You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Andriy Redko <dr...@gmail.com> on 2020/12/09 01:41:35 UTC

Re: queryParam fails with javax.ws.rs.core.UriBuilderException: URI can not be built with JAX-RS 2.1 CXF Version 3.3.3

Hello John,

Sorry, I am a bit confused by the example you provided, it looks like the query 
string has name / value misplaced, shouldn't it be built like that?

    .queryParam("apiKeyQueryParam1Value", "/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@")
    

Anyway, if the name of the query parameter is indeed "/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@",
the CXF does always decode query parameter names, so the not-so-nice workaround is to encode the name twice:

    Response response = client.target("http://localhost:" + "8010" + "/paramconverter/")
      .path("application/resource/queryParamSpecialCharacters")
      .queryParam(URLEncoder.encode(URLEncoder.encode("/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@", "UTF-8"), "UTF-8"), "apiKeyQueryParam1Value")
      .request(MediaType.APPLICATION_JSON_TYPE)
      .get();
          
Probably could be considered a bug, please feel free to open an issue [1].
Hope it helps, thanks.

[1] https://issues.apache.org/jira/projects/CXF/issues/

Best Regards,
    Andriy Redko



JK> Hello everyone,

JK> I have a customer that is trying to use
JK> ("/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@",
JK>  "apiKeyQueryParam1Value"
JK> ) as a queryParam.  The get fails with a
JK> javax.ws.rs.core.UriBuilderException: URI can not be built.  I have looked
JK> for issues in github and  JIRA and I could not find any that match, so I
JK> thought I would ask here.

JK> I have reproduced the problem with JAX-RS 2.1 CXF Version 3.3.3. I have
JK> tried 2 options to get this to work

JK> Option 1 Not encoded
JK>         Response response = client.target("http://localhost:" + "8010" +
JK> "/paramconverter/")
JK>                         .path(
JK> "application/resource/queryParamSpecialCharacters")
JK>                         .queryParam(
JK> "/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@"
JK> , "apiKeyQueryParam1Value")
JK>                         .request(MediaType.APPLICATION_JSON_TYPE)
JK>                         .get();
JK> This fails with:
JK>  00000076 SystemErr                                                    R
JK> javax.ws.rs.core.UriBuilderException: URI can not be built
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.doBuild
JK> (UriBuilderImpl.java:120)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildFromEncoded
JK> (UriBuilderImpl.java:245)
JK>         at org.apache.cxf.jaxrs.client.AbstractClient.getCurrentURI
JK> (AbstractClient.java:319)
JK>         at org.apache.cxf.jaxrs.client.WebClient.fromClient
JK> (WebClient.java:315)
JK>         at org.apache.cxf.jaxrs.client.WebClient.fromClient
JK> (WebClient.java:295)
JK>         at org.apache.cxf.jaxrs.client.spec.ClientImpl$WebTargetImpl.request
JK> (ClientImpl.java:373)
JK>         at org.apache.cxf.jaxrs.client.spec.ClientImpl$WebTargetImpl.request
JK> (ClientImpl.java:438)
JK>        ...

JK> Caused by: java.net.URISyntaxException: Illegal character in query at index
JK> 154:
JK> http://localhost:8010/paramconverter/application/resource/queryParamSpecialCharacters?/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$'()* ,;:@=apiKeyQueryParam1Value
JK>         at java.base/java.net.URI$Parser.fail(URI.java:2915)
JK>         at java.base/java.net.URI$Parser.checkChars(URI.java:3086)
JK>         at java.base/java.net.URI$Parser.parseHierarchical(URI.java:3174)
JK>         at java.base/java.net.URI$Parser.parse(URI.java:3116)
JK>         at java.base/java.net.URI.<init>(URI.java:600)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildURIFromEncoded
JK> (UriBuilderImpl.java:202)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildURI
JK> (UriBuilderImpl.java:175)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.doBuild
JK> (UriBuilderImpl.java:118)
JK>         ... 39 more

JK> From what I can tell from the trace I have set up, buildURIFromEncoded is
JK> using a URI for the queryParam that has been decoded  in error.

JK> [12/8/20, 8:52:07:444 CST] 00000069 id=58888f6b
JK> org.apache.cxf.jaxrs.impl.UriBuilderImpl                     >
JK> buildURIFromEncoded Entry
JK> /paramconverter/application/resource/queryParamSpecialCharacters
JK> /?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$'()* ,;:@=apiKeyQueryParam1Value
JK> null



JK> Option 2 Encoded
JK>         Response response = client.target("http://localhost:" + "8010" +
JK> "/paramconverter/")
JK>                         .path(
JK> "application/resource/queryParamSpecialCharacters")
JK>                         .queryParam(URLEncoder.encode(
JK> "/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@"
JK> , "UTF-8"), "apiKeyQueryParam1Value")
JK>                         .request(MediaType.APPLICATION_JSON_TYPE)
JK>                         .get();
JK> URLEncoder.encode =
JK> %2F%3FabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._%7E%251A%21%24%27%28%29*%2B%2C%3B%3A%40


JK> This fails with:
JK>  00000074 SystemErr                                                    R
JK> javax.ws.rs.core.UriBuilderException: URI can not be built
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.doBuild
JK> (UriBuilderImpl.java:120)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildFromEncoded
JK> (UriBuilderImpl.java:245)
JK>         at org.apache.cxf.jaxrs.client.AbstractClient.getCurrentURI
JK> (AbstractClient.java:319)
JK>         at org.apache.cxf.jaxrs.client.WebClient.finalizeMessage
JK> (WebClient.java:1110)
JK>         at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation
JK> (WebClient.java:1084)
JK>         at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:932)
JK>         at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:901)
JK>         at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:461)
JK>         at org.apache.cxf.jaxrs.client.SyncInvokerImpl.method
JK> (SyncInvokerImpl.java:135)
JK>         at org.apache.cxf.jaxrs.client.SyncInvokerImpl.method
JK> (SyncInvokerImpl.java:130)
JK>         at org.apache.cxf.jaxrs.client.SyncInvokerImpl.get
JK> (SyncInvokerImpl.java:50)
JK>         at org.apache.cxf.jaxrs.client.spec.InvocationBuilderImpl.get
JK> (InvocationBuilderImpl.java:92)
JK>                 ...

JK> Caused by: java.net.URISyntaxException: Illegal character in query at index
JK> 154:
JK> http://localhost:8010/paramconverter/application/resource/queryParamSpecialCharacters?/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$'()* ,;:@=apiKeyQueryParam1Value
JK>         at java.base/java.net.URI$Parser.fail(URI.java:2915)
JK>         at java.base/java.net.URI$Parser.checkChars(URI.java:3086)
JK>         at java.base/java.net.URI$Parser.parseHierarchical(URI.java:3174)
JK>         at java.base/java.net.URI$Parser.parse(URI.java:3116)
JK>         at java.base/java.net.URI.<init>(URI.java:600)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildURIFromEncoded
JK> (UriBuilderImpl.java:202)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildURI
JK> (UriBuilderImpl.java:175)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.doBuild
JK> (UriBuilderImpl.java:118)
JK>         ... 44 more

JK> From what I can tell from the trace I have set up, buildURIFromEncoded is
JK> using a URI for the queryParam that has been decoded  a second time in
JK> error.

JK> [12/8/20, 14:40:48:700 CST] 00000070 id=bbcf19e7
JK> org.apache.cxf.jaxrs.impl.UriBuilderImpl                     >
JK> buildURIFromEncoded Entry
JK> /paramconverter/application/resource/queryParamSpecialCharacters
JK> /?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$'()* ,;:@=apiKeyQueryParam1Value
JK> null

JK> I have a simple resource class that handles the get:

JK>     @GET
JK>     @Path("queryParamSpecialCharacters")
JK>     public Response queryParamSpecialCharacters(@QueryParam(
JK> "/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@"
JK> ) final String queryParm1) {
JK>         System.out.println("queryParamSpecialCharacters queryParm1 = " +
JK> queryParm1);
JK>         return Response.ok(queryParm1).build();
JK>     }



JK> My question is:  Should either of the options work or is what the customer
JK> trying to do invalid?

JK> I have opened an Open Liberty Issue that has more details.
JK> https://github.com/OpenLiberty/open-liberty/issues/15234

JK> Thank you for the Help!

JK> Thanks....
JK> John L. Koehler
JK> Dept: WG8A Bld: 050-2
JK> WebSphere Development
JK> Rochester, MN 55901
JK> Phone: 507-513-6221, Tie: 342-6221, Home: 507-281-1874
JK> e-mail address: jkoehler@us.ibm.com


RE: queryParam fails with javax.ws.rs.core.UriBuilderException: URI can not be built with JAX-RS 2.1 CXF Version 3.3.3

Posted by John Koehler <jk...@us.ibm.com>.
Hello Andriy,

Thank you for the help.  I have opened an issue
https://issues.apache.org/jira/browse/CXF-8387 .  I tried the suggested
workaround to encode the queryParam name twice.

        Response response = client.target(URI_CONTEXT_ROOT)
                        .path(
"application/resource/queryParamSpecialCharacters")
                        .queryParam(URLEncoder.encode(URLEncoder.encode(
"/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@"
, "UTF-8"), "UTF-8"), "apiKeyQueryParam1Value")
                        .request(MediaType.APPLICATION_JSON_TYPE)
                        .get();

    @GET
    @Path("queryParamSpecialCharacters")
    public Response queryParamSpecialCharacters(@QueryParam(
"/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@"
) String queryParm1) {
        System.out.println("queryParamSpecialCharacters queryParm1 = " +
queryParm1);
        return Response.ok(queryParm1).build();
    }

I no longer get the error javax.ws.rs.core.UriBuilderException: URI can not
be built. . Unfortunately the test fails in a different way. The queryParam
value is set to null.

 SystemOut                                                    O
queryParamSpecialCharacters queryParm1 = null

Thank you again for all of the help!

Thanks....
John L. Koehler
Dept: WG8A Bld: 050-2
WebSphere Development
Rochester, MN 55901
Phone: 507-513-6221, Tie: 342-6221, Home: 507-281-1874
e-mail address: jkoehler@us.ibm.com




From:	Andriy Redko <dr...@gmail.com>
To:	"John Koehler" <jk...@us.ibm.com>, dev@cxf.apache.org
Date:	12/08/2020 07:41 PM
Subject:	[EXTERNAL] Re: queryParam fails with
            javax.ws.rs.core.UriBuilderException: URI can not be   built
            with JAX-RS 2.1 CXF Version 3.3.3



Hello John,

Sorry, I am a bit confused by the example you provided, it looks like the
query
string has name / value misplaced, shouldn't it be built like that?

    .queryParam("apiKeyQueryParam1Value",
"/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@")



Anyway, if the name of the query parameter is indeed
"/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@",

the CXF does always decode query parameter names, so the not-so-nice
workaround is to encode the name twice:

    Response response = client.target("
http://localhost
 :" + "8010" + "/paramconverter/")
      .path("application/resource/queryParamSpecialCharacters")
      .queryParam(URLEncoder.encode(URLEncoder.encode
("/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@",
 "UTF-8"), "UTF-8"), "apiKeyQueryParam1Value")
      .request(MediaType.APPLICATION_JSON_TYPE)
      .get();

Probably could be considered a bug, please feel free to open an issue [1].
Hope it helps, thanks.

[1]
https://issues.apache.org/jira/projects/CXF/issues/


Best Regards,
    Andriy Redko



JK> Hello everyone,

JK> I have a customer that is trying to use
JK>
("/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@",

JK>  "apiKeyQueryParam1Value"
JK> ) as a queryParam.  The get fails with a
JK> javax.ws.rs.core.UriBuilderException: URI can not be built.  I have
looked
JK> for issues in github and  JIRA and I could not find any that match, so
I
JK> thought I would ask here.

JK> I have reproduced the problem with JAX-RS 2.1 CXF Version 3.3.3. I have
JK> tried 2 options to get this to work

JK> Option 1 Not encoded
JK>         Response response = client.target("
http://localhost
 :" + "8010" +
JK> "/paramconverter/")
JK>                         .path(
JK> "application/resource/queryParamSpecialCharacters")
JK>                         .queryParam(
JK>
"/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@"

JK> , "apiKeyQueryParam1Value")
JK>                         .request(MediaType.APPLICATION_JSON_TYPE)
JK>                         .get();
JK> This fails with:
JK>  00000076 SystemErr
R
JK> javax.ws.rs.core.UriBuilderException: URI can not be built
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.doBuild
JK> (UriBuilderImpl.java:120)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildFromEncoded
JK> (UriBuilderImpl.java:245)
JK>         at org.apache.cxf.jaxrs.client.AbstractClient.getCurrentURI
JK> (AbstractClient.java:319)
JK>         at org.apache.cxf.jaxrs.client.WebClient.fromClient
JK> (WebClient.java:315)
JK>         at org.apache.cxf.jaxrs.client.WebClient.fromClient
JK> (WebClient.java:295)
JK>         at org.apache.cxf.jaxrs.client.spec.ClientImpl
$WebTargetImpl.request
JK> (ClientImpl.java:373)
JK>         at org.apache.cxf.jaxrs.client.spec.ClientImpl
$WebTargetImpl.request
JK> (ClientImpl.java:438)
JK>        ...

JK> Caused by: java.net.URISyntaxException: Illegal character in query at
index
JK> 154:
JK>
http://localhost:8010/paramconverter/application/resource/queryParamSpecialCharacters?/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
 !$'()* ,;:@=apiKeyQueryParam1Value
JK>         at java.base/java.net.URI$Parser.fail(URI.java:2915)
JK>         at java.base/java.net.URI$Parser.checkChars(URI.java:3086)
JK>         at java.base/java.net.URI$Parser.parseHierarchical
(URI.java:3174)
JK>         at java.base/java.net.URI$Parser.parse(URI.java:3116)
JK>         at java.base/java.net.URI.<init>(URI.java:600)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildURIFromEncoded
JK> (UriBuilderImpl.java:202)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildURI
JK> (UriBuilderImpl.java:175)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.doBuild
JK> (UriBuilderImpl.java:118)
JK>         ... 39 more

JK> From what I can tell from the trace I have set up, buildURIFromEncoded
is
JK> using a URI for the queryParam that has been decoded  in error.

JK> [12/8/20, 8:52:07:444 CST] 00000069 id=58888f6b
JK> org.apache.cxf.jaxrs.impl.UriBuilderImpl                     >
JK> buildURIFromEncoded Entry
JK> /paramconverter/application/resource/queryParamSpecialCharacters
JK> /?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$'()* ,;:@=apiKeyQueryParam1Value

JK> null



JK> Option 2 Encoded
JK>         Response response = client.target("
http://localhost
 :" + "8010" +
JK> "/paramconverter/")
JK>                         .path(
JK> "application/resource/queryParamSpecialCharacters")
JK>                         .queryParam(URLEncoder.encode(
JK>
"/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@"

JK> , "UTF-8"), "apiKeyQueryParam1Value")
JK>                         .request(MediaType.APPLICATION_JSON_TYPE)
JK>                         .get();
JK> URLEncoder.encode =
JK>
%2F%3FabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._%7E%251A%21%24%27%28%29*%2B%2C%3B%3A%40



JK> This fails with:
JK>  00000074 SystemErr
R
JK> javax.ws.rs.core.UriBuilderException: URI can not be built
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.doBuild
JK> (UriBuilderImpl.java:120)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildFromEncoded
JK> (UriBuilderImpl.java:245)
JK>         at org.apache.cxf.jaxrs.client.AbstractClient.getCurrentURI
JK> (AbstractClient.java:319)
JK>         at org.apache.cxf.jaxrs.client.WebClient.finalizeMessage
JK> (WebClient.java:1110)
JK>         at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation
JK> (WebClient.java:1084)
JK>         at org.apache.cxf.jaxrs.client.WebClient.doInvoke
(WebClient.java:932)
JK>         at org.apache.cxf.jaxrs.client.WebClient.doInvoke
(WebClient.java:901)
JK>         at org.apache.cxf.jaxrs.client.WebClient.invoke
(WebClient.java:461)
JK>         at org.apache.cxf.jaxrs.client.SyncInvokerImpl.method
JK> (SyncInvokerImpl.java:135)
JK>         at org.apache.cxf.jaxrs.client.SyncInvokerImpl.method
JK> (SyncInvokerImpl.java:130)
JK>         at org.apache.cxf.jaxrs.client.SyncInvokerImpl.get
JK> (SyncInvokerImpl.java:50)
JK>         at org.apache.cxf.jaxrs.client.spec.InvocationBuilderImpl.get
JK> (InvocationBuilderImpl.java:92)
JK>                 ...

JK> Caused by: java.net.URISyntaxException: Illegal character in query at
index
JK> 154:
JK>
http://localhost:8010/paramconverter/application/resource/queryParamSpecialCharacters?/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
 !$'()* ,;:@=apiKeyQueryParam1Value
JK>         at java.base/java.net.URI$Parser.fail(URI.java:2915)
JK>         at java.base/java.net.URI$Parser.checkChars(URI.java:3086)
JK>         at java.base/java.net.URI$Parser.parseHierarchical
(URI.java:3174)
JK>         at java.base/java.net.URI$Parser.parse(URI.java:3116)
JK>         at java.base/java.net.URI.<init>(URI.java:600)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildURIFromEncoded
JK> (UriBuilderImpl.java:202)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.buildURI
JK> (UriBuilderImpl.java:175)
JK>         at org.apache.cxf.jaxrs.impl.UriBuilderImpl.doBuild
JK> (UriBuilderImpl.java:118)
JK>         ... 44 more

JK> From what I can tell from the trace I have set up, buildURIFromEncoded
is
JK> using a URI for the queryParam that has been decoded  a second time in
JK> error.

JK> [12/8/20, 14:40:48:700 CST] 00000070 id=bbcf19e7
JK> org.apache.cxf.jaxrs.impl.UriBuilderImpl                     >
JK> buildURIFromEncoded Entry
JK> /paramconverter/application/resource/queryParamSpecialCharacters
JK> /?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$'()* ,;:@=apiKeyQueryParam1Value

JK> null

JK> I have a simple resource class that handles the get:

JK>     @GET
JK>     @Path("queryParamSpecialCharacters")
JK>     public Response queryParamSpecialCharacters(@QueryParam(
JK>
"/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~%1A!$'()*+,;:@"

JK> ) final String queryParm1) {
JK>         System.out.println("queryParamSpecialCharacters queryParm1 = "
+
JK> queryParm1);
JK>         return Response.ok(queryParm1).build();
JK>     }



JK> My question is:  Should either of the options work or is what the
customer
JK> trying to do invalid?

JK> I have opened an Open Liberty Issue that has more details.
JK>
https://github.com/OpenLiberty/open-liberty/issues/15234


JK> Thank you for the Help!

JK> Thanks....
JK> John L. Koehler
JK> Dept: WG8A Bld: 050-2
JK> WebSphere Development
JK> Rochester, MN 55901
JK> Phone: 507-513-6221, Tie: 342-6221, Home: 507-281-1874
JK> e-mail address: jkoehler@us.ibm.com