Java string to URI with parameters - java

I have this query string to send a http request via a URI object, but the URI object reformats my query string, including the parameters.

You're adding the "query" part to the path. You want
queryString /* misnamed */ += "/v2/cart/addProduct";
String query = "?...";
...
uri = new URI("http", null, getDomain(), 80, queryString, query, null);

Related

Java.net.URI constructor is not encoding & character

I am trying to create a URL where the query parameters contain a symbol &. When I am passing this to Java.net.uri(https://docs.oracle.com/javase/8/docs/api/java/net/URI.html) class constructor its not encoding the & symbol to %26.
Example: https://www.anexample.com:443/hello/v5/letscheck/image/down?name=tom&jerry&episode=2
Now tom&jerry is the value of the query parameter but when we pass this to Java.net.uri constructor it encodes all spaces and special symbols but does not encode & to %26.
So tom and jerry both become separate query parameter which I don't want.
code will look something like below:
String query = "name=tom&jerry&episode=2"
URI uri = new URI(scheme, null, host, port, path, query, null);
I have also tried encoding the query parameters myself and then sending it to the constructor like below:
String query = "name=tom%26jerry&episode=2"
URI uri = new URI(scheme, null, host, port, path, query, null);
But in this case the encoded parameter becomes tom%2526jerry as % is encoded to %25
So how can I encode it so I can send & inside as a query parameter?
Have you tried something like below?
String tomJerry = "name=" + URLEncoder.encode("tom&jerry", StandardCharsets.UTF_8.toString());
String episode = "episode=" + URLEncoder.encode("2", StandardCharsets.UTF_8.toString());
String query = tomJerry + '&' + episode;
URI uri = new URI(scheme, null, host, port, path, query, null);
A better way would be looping through the key value pairing of the queries and applying URLEncoder to the value then joining the rest of the query with & after or perhaps stream, map then collect. But the point is to encode the value part of the query string.

How can I avoid that RestTemplate put %20 in place of white space character into request query parameters?

I am working on a Spring Boot project using RestTemplate in order to perform a POST request toward an URL containing query parameter
This is my code:
#Override
public boolean insertNotaryDistrictDetailsAsPost(NotaryDistrictDetails notaryDistrict) {
HttpHeaders basicAuthHeader = this.getWpBasicAuthenticationHeader();
HttpEntity<String> request = new HttpEntity<String>(basicAuthHeader);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(wpPortalWriteNotaryDistrictDetailsAsPostUrl)
// BASIC INFO:
.queryParam("title", notaryDistrict.getDistretto())
.queryParam("wpcf-distretto-notary-district", notaryDistrict.getDistretto())
.queryParam("wpcf-indirizzo-notary-district", notaryDistrict.getIndirizzo())
.queryParam("wpcf-denominazione-notary-district", notaryDistrict.getDenominazione())
.queryParam("wpcf-provincia-notary-district", notaryDistrict.getProvincia())
.queryParam("wpcf-regione-notary-district", notaryDistrict.getRegione())
.queryParam("wpcf-cap-notary-district", notaryDistrict.getCap())
.queryParam("wpcf-telefono-notary-district", notaryDistrict.getTelefono())
.queryParam("wpcf-fax-notary-district", notaryDistrict.getFax())
.queryParam("wpcf-email-notary-district", notaryDistrict.getEmail())
.queryParam("wpcf-pec-notary-district", notaryDistrict.getPec())
.queryParam("wpcf-web-url-notary-district", notaryDistrict.getWebUrl());
ResponseEntity<String> response = restTemplate.exchange(builder.toUriString(),
HttpMethod.POST,
request,
String.class);
System.out.println("RESPONSE STATUS: " + response.getStatusCodeValue());
System.out.println(response.getBody());
return true;
}
The problem is that the generated URL is this one:
https://www.MYURL.it/wp-json/custom-api/notary-district?title=DISTRICT%20NAME%20TEST&wpcf-distretto-notary-district=DISTRICT%20NAME%20TEST&wpcf-indirizzo-notary-district=INDIRIZZO%20TEST&wpcf-denominazione-notary-district=DENOMINAZIONE%20DISTRETTO&wpcf-provincia-notary-district=PROVINCIA%20TEST&wpcf-regione-notary-district=REGIONE%20TEST&wpcf-cap-notary-district=00100&wpcf-telefono-notary-district=3293332232&wpcf-fax-notary-district=23232322&wpcf-email-notary-district=test#test.it&wpcf-pec-notary-district=pec#test.it&wpcf-web-url-notary-district=www.test.it
As you can see some query parameters contains white spaces encoded with %20. This is a problem because when it is received and saved from the called API, these fields are saved with %20 instead a white space. I can not change the called API in order to decode it as white space because was not developed by me.
Using Postman I have no problem: inserting the value of a query parameter containing white space it is received and saved with white space (not with encoded %20).
Exist a way to say to RestTemplate to use white spaces instead %20 characted?
/****************************************
* URL with white spaces
****************************************/
String url "https://www.MYURL.it/wp-json/custom-api/notary-district?title=DISTRICT NAME TEST"
// set encoded = false
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url);
URI uri = builder.build(false).toUri();
result = restTemplate.exchange( uri, HttpMethod.GET, entity, Class.class);
/****************************************
* URL with %20
****************************************/
String url "https://www.MYURL.it/wp-json/custom-api/notary-district?title=DISTRICT%20NAME%20TEST"
// set encoded = true
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url);
URI uri = builder.build(true).toUri();
result = restTemplate.exchange( uri, HttpMethod.GET, entity, Class.class);

How to build an absolute URL from a relative URL using Java?

I have a relative url string, know host and protocol. How can I build an absolute url string?
Seems easy? Yes at first look, but until escaped characters coming. I have to build absolute url from 302 code http(s) response Location header.
lets consider an example
protocol: http
host: example.com
location: /path/path?param1=param1Data&param2= "
First I tried to build url string like:
Sting urlString = protocol+host+location
Constructor of URL class not escapes spaces and double quotes:
new URL(urlString)
Constructors of URI class fail with exception:
new URI(urlString)
URI.resolve method also fails with exception
Then I found URI can escape params in query string, but only with few constructors like for example:
URI uri = new URI("http", "example.com",
"/path/path", "param1=param1Data&param2= \"", null);
This constructor needs path and query be a separate arguments, but I have a relative URL, and it not split by path and query parts.
I could consider to check if relative URL contains "?" question sign and think everything before it is path, and everything after it is query, but what if relative url not contain path, but query only, and query contains "?" sign? Then this will not works because part of query will be considered as path.
Now I cannot get how to build absolute url from relative url.
These accepted answers seems just wrong:
how to get URL using relative path
Append relative URL to java.net.URL
Building an absolute URL from a relative URL in Java
It could be nice to consider scenario when relative url was given in relation to url with both host and some path part:
initial url http://example.com/...some path...
relative /home?...query here ...
It would be great to get java core solution, though it still possible to use a good lib.
The first ? indicates where the query string begins:
3.4. Query
[...] The query component is indicated by the first question mark (?) character and terminated by a number sign (#) character or by the end of the URI.
A simple approach (that won't handle fragments and assumes that the query string is always present) is as simple as:
String protocol = "http";
String host = "example.com";
String location = "/path/path?key1=value1&key2=value2";
String path = location.substring(0, location.indexOf("?"));
String query = location.substring(location.indexOf("?") + 1);
URI uri = new URI(protocol, host, path, query, null);
A better approach that can also handle fragments could be :
String protocol = "http";
String host = "example.com";
String location = "/path/path?key1=value1&key2=value2#fragment";
// Split the location without removing the delimiters
String[] parts = location.split("(?=\\?)|(?=#)");
String path = null;
String query = null;
String fragment = null;
// Iterate over the parts to find path, query and fragment
for (String part : parts) {
// The query string starts with ?
if (part.startsWith("?")) {
query = part.substring(1);
continue;
}
// The fragment starts with #
if (part.startsWith("#")) {
fragment = part.substring(1);
continue;
}
// Path is what's left
path = part;
}
URI uri = new URI(protocol, host, path, query, fragment);
The best way seems to be to create a URI object with the multi piece constructors, and then convert it to a URL like so:
URI uri = new URI("https", "sitename.domain.tld", "/path/goes/here", "param1=value&param2=otherValue");
URL url = uri.toURL();

Reading whole url from servlet

I would like to read from a servlet the exact URL that was set in the HTTP request. That is together with any URL rewritten parts (;jsessionid=…).
Is it possible?
You can get the request URL (the part before ; and ?) as follows:
StringBuffer requestURL = request.getRequestURL();
You can check as follows if the session ID was attached as URL path fragment:
if (request.isRequestedSessionIdFromURL()) {
requestURL.append(";jsessionid=").append(request.getSession().getId());
}
You can get and append the query string as follows, if any:
if (request.getQueryString() != null) {
requestURL.append('?').append(request.getQueryString());
}
Finally, get the full URL as follows:
String fullURL = requestURL.toString();

Get url parameters after # in java

I am trying to get the access_token from facebook. First I redirect to facebook using an url as the following
https://graph.facebook.com/oauth/authorize?type=user_agent&client_id=7316713919&redirect_uri=http://whomakescoffee.com:8080/app/welcome.jsf&scope=publish_stream
Then I have a listener that gets the url.
FacesContext fc = FacesContext.getCurrentInstance();
HttpServletRequest request =
(HttpServletRequest) fc.getExternalContext().getRequest();
String url = request.getRequestURL().toString();
if (url.contains("access_token")) {
int indexOfEqualsSign = url.indexOf("=");
int indexOfAndSign = url.indexOf("&");
accessToken = url.substring(indexOfEqualsSign + 1, indexOfAndSign);
handleFacebookLogin(accessToken, fc);
}
But it never gets inside the if..
How do I retrieve the parameter when it comes after a # instead of a usual parameter after ?.
The url looks something like
http://benbiddington.wordpress.com/#access_token=
116122545078207|
2.1vGZASUSFMHeMVgQ_9P60Q__.3600.1272535200-500880518|
QXlU1XfJR1mMagHLPtaMjJzFZp4
The URL is incorrectly encoded. It's XML-escaped instead of URL-encoded. The # is a reserved character in URL's which represents the client-side fragment which is never sent back to the server side.
The URL should more look like this:
https://graph.facebook.com/oauth/authorize?type=user_agent&client_id=7316713919&redirect_uri=http%3a%2f%2fwhomakescoffee.com%3a8080%2fapp%2fwelcome.jsf%26scope%3dpublish_stream
You can use java.net.URLEncoder for this.

Categories