I am currently trying to encode part of the URL but not all of it
Here is a sample of it:
http://localhost:8080/resourceSearch?type=http%3A%2F%2Fexample.com%2FSSTG.owl%25252523Project&searchTerms={searchTerms}
For some reason it automatically encodes the last part with "searchTerms" whereas I want just the part prior to it to be encoded. The reason is because its a template URL that the client can replace the braces with the search term they want.
In Spring, we create the urls with query parameters and path variables using UriComponentsBuilder as below
Path Variable:
UriComponentsBuilder.newInstance()
.scheme("http")
.host("http://localhost:8080/contextpath/")
.path("/{variable1}/{variable2}/")
.build()
.expand("value1", "value2")
.encode();
Query parameter
.queryParam("value", "a") for http://localhost:8080/contextpath/?value=a
Related
LATER EDIT: not same problem as the suggested answer. In my case, I need to build the URI, relying on the fact that the original query string is not modified.
I have a String (coming from a request query String) that is already correctly escaped, like param1=%2Ffolder1%2Ffolder2%2Ffolder%26name%202¶m2=9481dxcv234.
The decoded value of param1 is /folder1/folder2/folder&name 2. Obviously, I cannot unescape that String (because of the & char in this value)...
I need to build an URI which has that original string as query value.
I tried using org.apache.http.client.utils.URIBuilder but could not get it to work: if I provide the original String to the URI(... constructor, the resulting URL is double-escaped, like param1=%252Ffolder1%252Ffolder2%252Ffolder%2526name%25202¶m2=9481dxcv234.
Can I somehow do what I need ? To build an URI by passing the query string already escaped and leave it unchanged ?
Thanks.
I think, the simplest way is unescape it first.
Then you can work with url as usualy.
You could use org.springframework.web.util.UriComponentsBuilder:
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
UriComponents components = builder.build(true); //EDIT: pass true when the URI was fully encoded already.
MultiValueMap<String, String> parameters = components.getQueryParams();
parameters.get("param1") //"%2Ffolder1%2Ffolder2%2Ffolder%26name%202"
You can then URLDecode to get what you need.
Edit:
Since you appear to be using Apache HttpClient,
List<NameValuePair> params = org.apache.http.client.utils.URLEncodedUtils.parse(new URI(url), Charset.forName("UTF-8"));
params.get("param1") //"/folder1/folder2/folder&name 2"
I am working on a Spring Boot application
I need to make a request to an external service, old and ill-conceived. The request take the form of a HTTP GET (or POST) call, but the payload, an xml content, need to be passed as a query parameter. For example,
GET http://ill-service.com/plain.cgi?XML_DATA=<request attribute="attributeValue"><content contentAttribute="plain"/></request>
Of course, the value of query param XML_DATA need to be URL encoded, and normally, the RestTemplate of Spring boot work good on that, following RFC 3986 (see http://www.ietf.org/rfc/rfc3986.txt).
Except that, as allowed by this RFC, '/' and '=' character are left in the param value, giving me the following query :
GET http://ill-service.com/plain.cgi?XML_DATA=%3Crequest%20attribute=%22attributeValue%22%3E%3Ccontent%20contentAttribute=%22plain%22/%3E%3C/request%3E
In a perfect wold, this would be good, but do you remember when I said that the service I am trying to call is ill-conceived ? In another world, it needs to have the full content of XML_DATA URL-encoded. In another words, it needs the following query:
GET http://ill-service.com/plain.cgi?XML_DATA=%3Crequest%20attribute%3D%22attributeValue%22%3E%3Ccontent%20contentAttribute%3D%22plain%22%2F%3E%3C%2Frequest%3E%0A
I am quite lost on how to instruct the rest template or the UriComponentBuilder I am using to do so. Any help would be greatly appreciated
Probably u can use spring's UriUtils class
Use java.net.URLEncoder to encode your XML payload first and then append the encoded payload.
Following the suggestion of Vasif, and some information about UriComponentBuilder I found the following solutions :
String xmlContent = "<request attribute="attributeValue"><content contentAttribute="plain"/></request>";
URI uri = UriComponentsBuilder.fromHttpUrl("http://ill-service.com/plain.cgi")
//This part set the query param as a full encoded value, not as query value encoded
.queryParam("XML_DATA", UriUtils.encode(xmlContent, "UTF-8"))
//The build(true) indicate to the builder that the Uri is already encoded
.build(true).toUri();
String responseStr = restTemplate.getForObject(uri ,String.class)
I am connecting to a third party tool that uses brackets inside their url parameters. I'm proxying someone else parameters, so I'm not building these parameters up and don't want to have to parse them exactly.
I've tried a basic encoding of parameters, this fails due to the third party application not knowing how to parse the encoding, it tries to read the encoded values directly as far as I can tell.
I realize this is not exactly how resttemplate is designed to work, but everywhere else in our code uses restTemplate and I don't want to bring in a new service simply for a basic proxy.
Is there any way to make resttemplate allow the brackets through without trying to do substitution on them?
You can use escape URL codes for special characters in the URL. e.g. If your URL is http://domainURL/{url-part}/rest-of-the-url then you could refer to it as http://domainURL/%7Burl-part%7D/rest-of-the-url.
Below is the code snippet for the reference:
LoginDetails loginDetails = restTemplate.getForObject(restServiceURL +
"%7Btest-paranthesis%7D/" + userUUID, LoginDetails.class);
For the above code the URL is http://localhost:8087/userLogin{test-paranthesis}/842063819010
I'm trying to use Uribuilder from:
javax.ws.rs.core.UriBuilder;
To update a URI. The issue is that the parameter name gets escaped when I use replaceQueryParam.
so:
UriBuilder uriBuilder = webResource.getUriBuilder().
replaceQueryParam("abcd!dcv, "wid").
replaceQueryParam("format", "json");
if there is already an existing "abcd!dcv" parameter in the Uribuilder, it will escape and add a new one. so it will become
?abcd!dcv=originalvalue&abcd%21cdv=wid
instead of
?abcd!dcv=wid
How should I get around this? Thanks!
URIBuilder is an abstract class and the implementation gets to decide which characters need special encoding and which do not. The URIBuilder we get from a WebResource is attempting to follow the guidelines of RFC 3986. On page 12, ! is listed as a sub-delimiter and this is why it is getting encoded. From my reading of the RFC, I don't think we should be using ! as part of a query parameter. For instance, Vaading uses ! to distinguish between sub-windows of the same application.
The simplest work around I can think of is to simply not use URIBuilder or use the fromURI method that takes a String as input. You can create the URI with everything except the part with the characters we don't want encoded, convert this to astring, manipulate astring to replace the query parameter and then call URIBuilder.fromURI(aString)
How do you encode a path parameter (not form-url-encoded) but just a single URL that's appended in the format:
public String method(#PathParam("url") String url) {
}
There are lots of references to form URL encoding, but I want to simply encode a string as in the above.
Like mentioned in the previous answer URLEncoder can only be used for query paramaters, not path parameters. This matters e.g. for spaces which are a + in the query parameter but a %20 in the path.
org.springframework.web.util.UriUtils.encodePath()
can be used. Also using an org.apache.http.client.utils.URIBuilder would work. setPath is escaping the path part here. Also pure Java by using a constructor of java.net.Uri works.
Why would you want to *en*code it there, if anything wouldn't you want to *de*code it? In any case, you would call the standard URLEncoder.