spring mvc tracing the referrer page - java

In annotation based spring controller. if a user was on url.com/first/page and clicked a link or submitted a form pointing to say url.com/second/page .
How to make the second/page know the url of /first/page so that the second/page can
1) redirect the user to the first/page again when the form values are processed.
2) or show a back button link to the /first/page?
Edit 1 --
request.getHeader('Referer') is another but those I think are browser based on the mercy of browser. If the browser dont do it, we cant know. I wanted a way which is application wide. some how passing the url from one page to another
Edit 1 end --

you can use two below methods:
request.getAttribute("javax.servlet.forward.request_uri")
or
request.getHeader("Referer");
In above methods you are trusting the browser behavior and also the container which make the request object available to you. I don't know why you don't want to use this method.
Or
you can get the current page/serlvet url save it in the session and use it in the second page.
String requestUrl=request.getRequestURL();
session.setAttribute("pervious_page",requestUrl);
Then in the second page:
session.getAttribute("pervious_page");

Related

Securely passing parameters in JSP/Servlet (No Frameworks)

We have a JSP page and a Servlet page, where we pass the parameters via URL from JSP to Servlet. Below is the JSP link
Allergies
In our servlet, we do some process like below.
int id = Integer.parseInt(request.getParameter("idClient"));
//Do the work
RequestDispatcher d = request.getRequestDispatcher("view.jsp");
d.forward(request,response);
Unfortunately this makes the idClient 100% visible and it is also editable. We have noticed that the user can simply edit the idClient from the URL and access other client information too! Not only that, any one can access anyones info, whether the client is belong to them or not!
How can we stop this?
Get the logged-in user.
Check whether that user is supposed to be able to access this client's details.
If not, return an error page instead of the client details page.
I can't be more specific without knowing the details of your existing code and database structure.

Establish Connection First, Redirect User Second

I have an idea to make something pretty sweet but I'm not sure if it's possible. Here is an example of a very basic ajax function that I might use to establish a connection a server...
function getFakePage(userId)
{
var ajaxObject, path, params;
ajaxObject = getAjaxObject();
params = "?userId=" + userId
path = getInternalPath() + "someServlet" + params;
ajaxObject.open("GET", path, true);
ajaxObject.send();
// On ready state change stuff here
}
So let's say I have a URL like this...
https://localhost:8443/Instride/user/1/admin
And I wanted to use javascript to redirect the user to this this URL. Normally I would just do this...
window.location = "https://localhost:8443/Instride/user/1/admin";
But my idea is to create a javascript (no js frameworks please) function that could combine the ajax code with the window.location code. Basically what I would like to accomplish is to create a connection with the server via ajax, send a servlet on that server the url I would like the user to be redirected to, and then redirect the user to that URL. So that for however long it takes the user to connect to my server from wherever they are in the world they see a loading icon instead of a blank white page.
So to clarify exactly what I am trying to accomplish; I do not want to put window.location within the success of my ajax function (because that would be encompass two round trips), and I do not want to return a huge chunk of HTML for the requested resource and add it to the page. I want to establish a connection to the server with ajax, send a servlet the URL the user wants to go to, and then somehow override the ajax function to redirect that user. Is this possible?
And I know some of you might think this is stupid but it's not when you're talking about overseas users with slow dial up connections staring at white pages. If it's possible, I'd love to hear some insight. Thank you very much!
First, let me say that the best solution is finding what is causing the slowness and fixing it.
Now as to your question, yes you could do it. You could even shoehorn it onto an existing application. But it wouldn't be pretty. And it comes with it's own set of problems. But here are the steps:
Browser calls ajax cache service requesting "somepage.html"
Browser loads loading icon
Server creates somepage.html and caches it in a temporary cache, (ehcache or other library would be good, probably with file backing for the cache depending on size)
Server responds to ajax request with ID for cached page
Browser now redirects to "somepage.html?cacheId={cacheId}" where the id is from the ajax call.
Server uses a filter to see if any cache can be served up for the page instead of the actual page, thus speeding up the request.
Having said that, it would be better to just have the new page load quickly with a loading icon while it did any of the heavy lifting through ajax.
You can't do an AJAX request and a location change in one. If you want to do only one request you have to choose one of those methods. ie. return some data and replace content on your current page, or load a completely new page.
It doesn't make any sense to want to want to do both. What you could want is stateful URLs; where your URL matches the content displayed, even if that content comes from an AJAX request. In that case an easy solution is the use the # part of the URL which you can change freely (window.location.hash). Some modern browsers support changing the whole URL without causing the page to reload. I've used # with great success myself.

Java Servlets, how to keep request attribute alive across several forwards?

I have a home-grown MVC implementation. A ControllerServlet like so:
/controller?cmd=EditUser&userid=55
From this URL, the controller creates a EditUserCommand.class instance and calls an execute() method which returns the result page (ex. user.jsp) to display.
The controller servlet then does a ...
getRequestDispatcher(resultPage).forward(request, response);
... and the resulting page is shown.
One of the things the controller does is set messages (error, info, and so on) as request attribtues. For example:
request.setAttribute("infoMessage", "User was edited successfully.");
And that message gets pulled out of the request in the user.jsp page and displayed.
Works fine.
Now here comes my problem.
Sometimes my commands don't return a page like user.jsp but return a URL like cmd=ShowUser&userid=55 for the result. This is because there might be things I want to check before displaying the final page, like permission to view the user and so on.
When I do this the "infoMessage" I placed in the request never appears because the result is a URL that makes a new call to the servlet, which is a new request. The new request doesn't maintain the request attributes from the first request; which makes sense, I just didn't forsee this happening.
How can I make my request variable "stay alive" until it's actually displayed on the final page that results from the original request?
Any suggestions or advice are appreciated. Just FYI, I can't re-write the entire app to go to something like Struts, Spring MVC, of JSF. It's not an option.
Thanks!
Rob
redirect generally looses request data because of brand new request from browser. One possible approach may be append your message to url string as attribute and read it when you need.
Based on your EDIT: After your edit also, my answer make sense. But, only one correction is, it is not brand new request because forward happens on server side.
Have you tried using a RequestDispatcher instead of a Redirect?
RequestDispatcher dispatcher = request.getRequestDispatcher("/myNextPage.jsp");
dispatcher.forward(request, response);
You may be giving a simple example, but your control flow causes the "Resend" Error, perhaps? Basically, after making any change to the data, the controller must immediately do a "Get" via a redirect and the screen should be displayed completely stateless.
Please take a look:
http://en.wikipedia.org/wiki/Post/Redirect/Get
As such, Attributes are not a great help. What you may want to consider is, maintaining a Bean/Object for every login user, and persist this object in a LRU cache (JCache or MemcacheD), and retrieve it on every entry to the application. Once you have that, you can maintain a pseudo-state such as previous results in that object.
In any case, using Attributes to retain state will severely constrain your options. You need to have a more generic flexible routing-independent mechanism.

how do i know whether my html link is clicked or not from Servlet?

My Servlet response type is html and my response contains a hyperlink to another web site.So, now i want to capture the information about whether the user clicked the link or not? and also calculate the total clicks? i am using Tomcat 7 as a server.
Is this possible in setting response header (302 or 404)?...
Please Guide me to get out of this issue?
Yes, you can use a 302: instead of providing the link to the other website, you provide a link to your own servlet, do your accounting and then send back a redirection (301/302) http status with the other web-site URL in the response Location header.
This maybe a bit simplistic though, since the user will leave your original page (is this what you want ?) and search engines may not like this if your web app is public.
I think right now you are redirecting the request(link for another website) at client side.In this approach your server cannot get the information about the click.
What you can do create a servlet and call this servlet on click now this servlet is responsible to redirect the request to another website. Add an static integer counter and increment this when servlet call each time.
Use the method setStatus():-
setStatus(HttpServletResponse.SC_FOUND);
or
setStatus(HttpServletResponse.SC_NOT_FOUND);

Simple example of JQuery Address to manage application state

I'm using the jQuery Address library to re-write my URL depending on what the user is doing in the page. The intention is to allow users to bookmark pages and come back later. The page never refreshes as all server interaction is done via ajax.
jQuery Address is writing URLs like this:
http://localhost:9000/#/u/scott_tiger
I need a to set up a route in Play to be able to route that request through to the appropriate controller. So I set this up:
GET /#/u/{username} Controller.showUser
This doesn't work though, the route definition gets ignored. I've tried loads of things such as trying to escape the "#" and replacing it with a variable that I've populated with Character.toString(35). None of this works.
Does anyone know how I can either define the route properly or get jQuery Address not to write the "#".
EDIT: The "#" doesn't get sent to the server does it. Doh! OK, question is revised.
No. The # and the part of the URL after that is not sent to the server. So your play app on the server will never see such URLs.
HTML5 solution
You need to handle these URLs on the client side using JavaScript. In modern browsers with good HTML5 support, you can modify the address without reloading the page. See Manipulating the browser history on how to do it for these browsers. And see When can I use... for browser support.
#-URLs
On Internet Explorer and older versions of other browsers you need to use # URLs and use JavaScript to load the state (e.g. get the user page /u/scott_tiger in your example). See How to run a JavaScript function when the user is visiting an hash link (#something) using JQuery? for how to do this in JavaScript. Also if a user bookmarks a page with a #-URL you need to reload the state.
See also: What's the shebang/hashbang (#!) in Facebook and new Twitter URLs for?
JavaScript libraries
You may use JavaScript libraries to handle this for you history.js is an example. Also bigger frameworks like Backbone.js handle this.
Does anyone know how I can get jQuery Address not to write the "#".
If you don't write the #-part of the URL, the state can not be linked. So you can not get back to e.g. Scott Tigers profile page if you bookmark the page, because the URL is only http://localhost:9000/ and you will arrive on the front page, while the user though he would arrive on the profile page.
Armed with my new understanding of URLs (thanks #Jonas) I realised that I'd missed half of the story.
I'm using JQuery Address to change the URL depending on what you click in the application. This works great and on lots of browsers. What I was missing was using JQuery Address to watch for external address changes (bookmarks, history, back/forward) and respond accordingly. i.e. set the page up correctly by firing the appropriate Ajax calls and rendering that data appropriately.
Changing the address
$.address.title("new title describing application state");
$.address.parameter("q", "val1");
$.address.parameter("g", "val2");
$.address.update();
Restoring the state
$.address.externalChange(function(event) {
var val1 = event.parameters["q"];
var val2 = event.parameters["g"];
// do something with those values
});

Categories