How to redirect users using HTTP response - java

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.

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.

How to run a jsp file by different url pattern other than filename.jsp?

I want to create a blogging like CMS in jsp.
So I have a "post.jsp" which will dynamically display the content.
I have a database which stores some url pattern and their content.
For example database stores:
url: www.example.com/abc
content: hello
url: www.example.com/xyz
content: world
I want to do that when a user will enter "www.example.com/abc" it will run "post.jsp" and check in database whether the url is present or not. If present then it will display "hello" else 404 error/
Similarly if user will enter "www.example.com/xyz" it will again run "post.jsp" and if the url present then it will display "world" else 404 error.
Every time the url should run "post.jsp" if no extension like html or jsp is present in the url pattern. If a url "www.example.com/contact.jsp" is entered by user then it should run contact.jsp without entering "post.jsp" because the url pattern contains a .jsp extension.
Hope you understand my requirement. How to do this?
I would create a mapping for 404 in my web.xml and define a JSP / servlet to be called whenever a URL is called that is not found. In that Java code I would do something similar to this (pseudo code !):
String request = getRequestUrl();
if( !request.endsWithIgnoreCase( ".jsp" ) && !request.endsWithIgnoreCase( ".htm") {
String tagToSearch = request.getEverythingAfterSlash();
String content = Db.searchFor( tagToSearch );
Response.write( content );
}
And please make sure that no-one is able to inject dangerous SQL by using this mechanism !
How this needs to be implemented depends quite a bit on which environment you use (Java version, Servlet version, Framework, Application server)

JSP/Servlet rewrite URL

I'd like to change the URL of some pages in my website in the same way as foursquare is doing:
from www.foursquare.com/v/anystring/venueid
to www.foursquare.com/v/venue-name/venueid
For example central park in new york:
https://foursquare.com/v/writeherewhatyouwant/412d2800f964a520df0c1fe3
becomes
https://foursquare.com/v/central-park/412d2800f964a520df0c1fe3
I'm developing a pure JSP/Servlet app, no frameworks, in a Tomcat container.
I'm thought of using tuckey's urlrewritefilter, but I don't see how can I use dynamic values coming from the servlet itself there (the venue name)
How can I accomplish this?
Off the top of my head, here's something you could try:
1) Create a servlet with a servlet-mapping matching the common (prefix) part of the URL (e.g. for foursquare the pattern would be /v/*).
2) In your servlet, retrieve the remaining part of the URL path using request.getPathInfo(). You can then parse it using regular string utilities and convert it to the new path you'd like.
3) Assuming your updated path is in a variable called newUrl, call response.sendRedirect(newUrl) to tell the browser to update its URL. This will also call your servlet again with the new path, so it needs to handle both cases.
See the javadoc for HttpServletResponse.sendRedirect() for more info about how it handles relative vs absolute paths, etc.

Search for redirected website path

I have two websites, A and B. When I open website A, I am redirected to website B automatically.
What is the function with which I can check what was the full path of website A from which was the redirect?
I was trying to start with:
logger.info(request.getPathInfo());
logger.info(request.getPathTranslated());
logger.info(request.getServletPath());
logger.info(request.getLocalName());
logger.info(request.getRemoteAddr());
logger.info(request.getRemoteHost());
logger.info(request.getRequestURI());
logger.info(request.getServerName());
but none of them is correct.
For redirecting I use response.sendRedirect inside Controller.
Thanks for help.
You can try using the optional referer header:
request.getHeader("referer");
But it is important to note that this may not always be populated (specifically IE).
A better solution, if you are in control of both of the websites, is to pass the value somehow when you are doing the redirect. For example, as a GET or POST parameter.
Edit:
As suggested above, you can append query strings to your redirect URL. For example, you might try something like this:
String redirectUrl = "http://my.redirect.com/";
redirectUrl += "?referer=";
redirectUrl += URLEncoder.encode(request.getRequestURL().toString(), "UTF-8");
Then you can just pull this out of the request on the other side.
Use this as a starting point. You may need to manually append other query parameters that may not be part of the getRequestURL() output.
None of these would get you the page that redirected you to the current page. What you can try is:
String refererPage = request.getHeader("referer");
However keep in mind that this is also browser dependent and may not always be present.
Try this
request.getHeader("referer");
Please try
request.getHeader("referer");

JSR168 portlet request cuts param value after # symbol

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).

Categories