URL change encoding + instead of %20 - java

URL encoding normally replaces a space with a plus (+) sign or with %20.
In spring MVC it replaces with %20. My controller as:
#GetMapping(path = "/post/{id}/{title}")
public String postView(#PathVariable("id") Long id, #PathVariable("title") String title, Model model){
Post post = postService.findById(id);
model.addAttribute("post", post);
return "singlePost";
}
I need to replace the %20 with (+) or (-)
Thanks

You can use decode method of URLDecoder class. As an example, if title have url encoded values,
String urlDecodedTitle = URLDecoder.decode(title, StandardCharsets.UTF_8.toString())

In the path of a URL the spaces are replaced by %20 ([RFC3986][1]), while URL query parameters follow the application/x-www-form-urlencoded that replaces spaces by +.
If you need to encode a query string parameter, you can use java.net.URLEncoder.
But as you are using #PathVariable, your parameters are part of the path, hence they must be encoded with spaces replaced by %20. Spring provides UriUtils.encodePath for this task.
For example, to build a query to your /post/{id}/{title} mapping:
Long id = 1L;
String title = "My title";
String path = "/post/" + id + "/" + UriUtils.encodePathSegment(title, "UTF-8");
On your postView method you don't need to do any decoding, as Spring does it already.
[1]: https://www.rfc-editor.org/rfc/rfc3986

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.

URLEncoder - what character set to use for empty space instead of %20 or +

I am trying to open new email from my Java app:
String str=String.valueOf(email);
String body="This is body";
String subject="Hello worlds";
String newStr="mailto:"+str.trim()+"?subject="+URLEncoder.encode(subject,"UTF-8")+"&body="+URLEncoder.encode(body, "UTF-8")+"";
Desktop.getDesktop().mail(new URI(newStr));
Here it is my URLEncoding. As I cannot use body or subject string in URL without encoding them, my output here is with "+" instead of whitespace. Which is normal, I understand that. I was thinking if there is a way to visualize subject and body normally in my message? I tried with .replace("+"," ") but it is not working as it is giving an error. This is how it is now:
I think there might be different character set but I am not sure.
That's the way URLEncoder works.
One possible approach would be to replace all + with %20 after URLEncoder.enocde(...)
Or you could rely on URI constructor to encode your parameters correctly:
String scheme = "mailto";
String recipient = "recipient#snakeoil.com";
String subject = "The Meaning of Life";
String content = "..., the universe and all the rest is 42.\n Rly? Just kidding. Special characters: äöü";
String path = "";
String query = "subject=" + subject + "&body=" + content;
Desktop.getDesktop().mail(new URI(scheme, recipient, path, query, null));
Both solutions have issues:
In the first approach, you might replace actual + signs, with the second, you'll have issues with & character.

How to use getRequestUri().getRawQuery() in the url on Java escape

As know url would not allow some special character there, so need encode for that:
: metadata=[{name: serialnumber, value: aaaaaaaaa},{name: register, value: abcde}] in the url
I tried this encode would work
String abc= java.net.URLEncoder.encode("http://localhost:9080/myapp/myapp/search?metadata=[{name: serialnumber, value: aaaaaaaaa},{name: register, value: abcde}]", "utf-8");
But why would be fail following if use info.getRequestUri().getRawQuery() instead?
public Response search(#Context final UriInfo info, #Context final HttpHeaders httpHeaders) throws Exception {
String requestURI = java.net.URLEncoder.encode(info.getRequestUri().getRawQuery(), "utf-8");
error:
Caused by: java.net.URISyntaxException: Illegal character in query
How can I encode this successfully if I will use info.getRequestUri().getRawQuery()
This might be due to the white space in metadata.
You may either -
Remove the white spaces (metadata=[{name:serialnumber,value:aaaaaaaaa},{name:register,value:abcde}]
replace white spaces with +
as mentioned in this question
Hope that work!

Get last part of url using a regex

How do I get the last part of the a URL using a regex, here is my URL, I want the segmeent between the last forward slash and the #
http://mycompany.com/test/id/1234#this
So I only want to get 1234.
I have the following but is not removing the '#this'
".*/(.*)(#|$)",
I need this while indexing data so don't want to use the URL class.
Just use URI:
final URI uri = URI.create(yourInput);
final String path = uri.getPath();
path.substring(path.lastIndexOf('/') + 1); // will return what you want
Will also take care of URIs with query strings etc. In any event, when having to extract any part from a URL (which is a URI), using a regex is not what you want: URI can handle it all for you, at a much lower cost -- since it has a dedicated parser.
Demo code using, in addition, Guava's Optional to detect the case where the URI has no path component:
public static void main(final String... args) {
final String url = "http://mycompany.com/test/id/1234#this";
final URI uri = URI.create(url);
final String path = Optional.fromNullable(uri.getPath()).or("/");
System.out.println(path.substring(path.lastIndexOf('/') + 1));
}
how about:
".*/([^/#]*)(#.*|$)"
Addition to what #jtahlborn answer to include query string:
".*/([^/#|?]*)(#.*|$)"

Extract part of a URL with URL/URI objects

I have a String holding a URL in this format: http://hello.world.com/service/sps/f4c0e810456t
And I would like to extract the last part of the URL, i.e. f4c0e810456t.
I can do it with substrings:
System.out.println(s.substring(s.lastIndexOf("/") + 1, s.length()));
Or regexp however looking for something more elegant using URL/URI objects but couldn't find something.
Any ideas...?
If you can change the URL to "http://hello.world.com/service/sps/?f4c0e810456t" then you could use the getQuery() method (both on URL and URI).
Example with URL and split (it wrap regular expression for you):
String address = "http://hello.world.com/service/sps/f4c0e810456t";
URL url = new URL(address);
String [] str = url.getPath().split("/");
String result = str[str.length-1];

Categories