JSR168 portlet request cuts param value after # symbol - java

One of parameters for action link looks like:
itemUrl=feedLink.html#xtor=RSS-3208
when I execute next code in backend in processAction():
String itemUrl = (String) request.getParameter("itemUrl");
,that I get next value: feedLink.html
e.g. request cuts itemUrl value after # symbol
escapeXml="true" in .jsp file doesn't help.

You have to URI encode the parameter names and values - your link should be itemUrl=feedLink.html%23xtor=RSS-3208.

Anything after the # in an URL specifies the location on the page the browser should display; it's not part of the URL itself. As such, if you want an actual # in your URL, it needs to be escaped (if the parser is actually compliant).
In theory, you could parse the whole URL being sent to you manually, but the better solution is to get the caller of your page to send you a correct URL in the first place (well, a URL that represents what they want, since the one in question is valid, per se).

Related

Prevent java.net.URL from stripping "?" if there are no query paramters

I am trying to use java.net.HttpURLConnection in order to make a request to a URL like this:
https://example.com/app/?#/something=else&someting2=else2
In order to do this, I need to construct a java.net.url, but the constructor strips away the question mark "?":
java.net.URL url = new URL("https://example.com/app/?#/something=else&someting2=else2");
String string = url.toString();
// String is https://example.com/app/#/something=else&someting2=else2
And when I create the connection with url.openConnection(), I just get a 404.
I get why it does this. It righfully recognizes everything after and including the hash # as a url fragment, which means that the actual url becomes https://example.com/app/?. And then, it just strips the trailing question mark. But I need the URL to be rendered as is.
This is for an Android app.
How can I force HTTPUrlConnection to make the GET request with the question mark in the URL?
In a URL, the part after ? is a query string, and the part after # is a fragment identifier, as you already noted.
While the query string is sent to the server, the fragment identifier is not, so trying to send one does not make sense.
2 possibilities:
if it is a fragment identifier, you don't need to send it and Android's behavior (normalizing the URL) is correct. Stripping the trailing ? (empty query string) should not be a problem as it makes no sense alone (for both server and client). If you want to preserve the fragment in your client code, what you want is to create a URI, use that to display wherever you want, then convert to URL with toURL() when you need to speak with server.
if it is not actually a fragment identifier, it's supposed to be part of the query string, so you need to send a hash sign as part of the URL: in that case, you need to url-encode it to %23, the part after the ? won't be stripped, and the server will know what to do with the encoded %23.

Jave getparameter with # in it

Say I have the URL:
http://185.112.249.77:9999/Api/Search?search=#9QLU9CY8
And then code:
String search = request.getParameter("search");
Then search is blank...
I need a way to get around this. The url is visited directly. Is there something I can do in Tomcat's config to make this work?
I tried replacing "#" with "%23" with a search.replace but that also didn't work.
Thanks!
That's because the '#' character is not part of the parameter but is a fragment identifier. So your parameter is actually empty
see this link to get more info about url params structure
[https://www.rfc-editor.org/rfc/rfc3986#section-3.5]
Or
[https://www.rfc-editor.org/rfc/rfc3986#appendix-A]
For the formal definition

java servlet: request parameter contains plus

The request parameter is like decrypt?param=5FHjiSJ6NOTmi7/+2tnnkQ==.
In the servlet, when I try to print the parameter by String param = request.getParameter("param"); I get 5FHjiSJ6NOTmi7/ 2tnnkQ==. It turns the character + into a space. How can I keep the orginal paramter or how can I properly handle the character +.
Besides, what else characters should I handle?
You have two choices
URL encode the parameter
If you have control over the generation of the URL you should choose this. If not...
Manually retrieve the parameter
If you can't change how the URL is generated (above) then you can manually retrieve the raw URL. Certain methods decode parameters for you. getParameter is one of them. On the other hand, getQueryString does not decode the String. If you have only a few parameters it shouldn't be difficult to parse the value yourself.
request.getQueryString();
//?param=5FHjiSJ6NOTmi7/+2tnnkQ==
If you want to use the '+' character in a URL you need to encode it when it is generated. For '+' the correct encoding is %2b
Use URLEncoder,URLDecoder's static methods for encoding and decoding URLs.
For example : -
Encode the URL param using
URLEncoder.encode(url,"UTF-8")
Back in the server side , decode this parameter using
URLDecoder.decode(url,"UTF-8")
decode method returns a String type of the decoded URL.
Allthough the question is some years old, I'd like to write down how I fixed the problem in my case: the download link to a file is created in a GWT page where
com.google.gwt.http.client.URL.encode(finalurl)
is used to encode the URL.
The problem was that the "+" sign a customer of us had in the filename wasn't encoded/escaped. So I had to remove the URL.encode(finalurl) and encode each parameter in the url with
URL.encodePathSegment(fileName)
I know my question is bound to GWT but it seems, URLEncoder.encode(string, encoding) should be applied to the parameter only aswell.

Uri.parse(), how to get the encoding correct?

I am doing an application where I have to read a URL from a webpage as a String[Its not the address of the page]. The URL that I will be reading contains query string, and I specifically need two queries from that URL. So I am using the Uri class available in Android. Now, the problem lies in the encoding/format of the URL and the query. One of the queries that I need is always an URL. Sometimes the query URL is %-encoded and sometimes not.
The URLs can be like the following :
Case 1 :
http://www.example.com/example/example.aspx?file=http%3A%2F%2FXX.XXX.XX.XXX%2FExample.file%3Ftoken%3D9dacfc85
Case 2 :
http://www.example.com/example/example.aspx?file=http://XX.XXX.XX.XXX/Example.file?token=9dacfc85
How do I get the correct Url contained in the file= query?
I am using the following [to accomplish the said work universally] :
Uri.decode(urlString.getQueryParameter("file"));
Is this the correct way to do it?
UPDATE
I have decided to first encode the whole URL regardless of its value and then get the query parameter. Theoretically, it should work.
If you are uncertain about the type of URL you would get then I would suggest you to decode every URL you get from the parameter. And when you need to use it then you can encode it.
As per my knowledge, you are doing it right.

How to redirect users using HTTP response

I have a scenario where the user clicks on a 'restaurant' link (for searching restaurants in a particular locality). I have to check whether the location is set or not. If it is not set, I want to redirect him to a page that allows him to set the location, and, then, go back to search results filtered by the set location. I'm using response.sendRedirect(url) to redirect the user to the setting location page. But, how can I send the redirect back URL (i.e., the URL where I want to send the user after the location is set)?
I tried this:
response.sendRedirect("/location/set.html?action=asklocation&redirectUrl="+
request.getRequestUri()+request.getQueryString());
but this isn't working and 404 error is shown; also, the url formed in the browser doesn't look good.
Please, if anyone could solve the problem ...
Looks like you're missing at least a "?" between request.getRequestUri() and request.getQueryString(). You should url-encode the parameter as well, which you can use java.net.URLEncoder for.
Also, when doing redirects you need to prepend the context path: request.getContextPath().
Something like
String secondRedirectUrl = request.getRequestUri()+"?"+request.getQueryString();
String encodedSecondRedirectUrl = URLEncoder.encode(secondRedirectUrl, serverUrlEncodingPreferablyUTF8);
String firstRedirectUrl = request.getContextPath()+"/location/set.html?action=asklocation&redirectUrl="+encodedSecondRedirectUrl;
response.sendRedirect(firstRedirectUrl);
Personally, i'd rather solve the problem by storing a RequestDispatcher in the session and forwarding to it after the location has been set.
My first response will be to remove the / on your URL, something of this effect (to your code):
response.sendRedirect("location/set.html?action=asklocation&redirectUrl="+
request.getRequestUri()+request.getQueryString());
If that doesn't work, add request.getContextPath() at the beginning of your url string, like so:
response.sendRedirect(request.getContextPath() + "/location/set.html?action=asklocation&redirectUrl="+request.getRequestUri()+request.getQueryString());
The Javadoc states:
If the location is relative without a
leading '/' the container interprets
it as relative to the current request
URI. If the location is relative with
a leading '/' the container interprets
it as relative to the servlet
container root.

Categories