Java Web App: Passing form parameters across multiple pages - java

what is the best practice or best way of passing form parameters from page to page in a flow? If I have a flow where a user enters data in a form and hits next and repeats this process until they get to an approval page, what ways could I approach this problem to make the retention of data as simple as possible over the flow?
I guess you could put all the information as you go in the session but could you get into memory issues if a lot of people are using your app and going through the flow at the same time?

You can store data into Cookies or store them into Session and access them between different web pages.

HttpSession is your best bet if you want to track a "wizard" style data entry.
Just seconding #Rachel's openion.
The server side component that handles your page submits ( such as Servlets) would have some code like:
public void doPost (HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
HttpSession session = req.getSession();
session.setAttribute("Variable1", request.getParameter("input1"));
//and so on..
HttpSession Provides a way to identify a user across more than one page request or visit to a Web site and to store information about that user.

You may also put attributes in the request scope. They are accessed the same way from EL in your JSPs, but do not require a session. Depending on your situation, you may not wish to start sessions for every user.

Related

Managing session and request attributes in Servlet

I have a very simple JSP page where it has one search box and based off the input, in the search box, it will return a response with a submit button to get the following response.
I noticed that whenever I use request.getattribute("foo") in my servlet to retrieve some request it returns null due to the request ending so I looked at the answers on here and started using session.getattribute("foo") instead. However, now I am stuck having session variables responses being set and it is causing my view to have old session data that isn't suppose to be there so now I have to use session.removeAttribute("foo"), whenever, I don't want that particular response data to be shown.
Is there a better way to go about managing this instead of having to use session.getattribute("foo"), session.removeAttribute("foo") and session.setattribute("foo")?
You should work with request.getSession()
Returns the current session associated with this request, or if the request does not have a session, creates one.
Set an attribute:
request.getSession().setAttribute("foo")
And get attribute using:
request.getSession().getAttribute("foo")
It will be used in the context of the request and not effect other requests, so you don't need to remove attribute.
Read more in Servlets tutorial
Servlets provide an outstanding technical solution: the HttpSession API. This is a high-level interface that allows the server to "remember" a set of information relevant to a particular user's on-going transaction, so that it can retrieve this information to handle any future requests from the same user.
You can go for request.getparameter("foo") or request.setparameter("foo", obj)
This can be used for every request, and it will not add to your session variables and basically will not make your "session object heavy".
Java doc:
Request parameters are extra information sent with the request. For HTTP servlets, parameters are contained in the query string or posted form data.

Passing parameter form jsp to servlet to jsp and then to another servlet

Is there a way to pass a parameter to a servlet going through another jsp and then to another servlet
like
jsp---parameter--->servlet(using getParameter())---parameter--->jsp---parameter--->servlet(is there a way to get the parameter here)
The program that am working on is to pass the username.
Looks like you want to use HTTPsession.
Provides a way to identify a user across more than one page request or visit to a Web site and to store information about that user.
The servlet container uses this interface to create a session between an HTTP client and an HTTP server. The session persists for a specified time period, across more than one connection or page request from the user. A session usually corresponds to one user, who may visit a site many times. The server can maintain a session in many ways such as using cookies or rewriting URLs.
Setting
Session session = request.getSession();
session.setAttribute("username", username);
getting it back
String username = (String)session.getAttribute("username");

Java : How to deal with multiple sessions in the servlet [duplicate]

This question already has answers here:
How do servlets work? Instantiation, sessions, shared variables and multithreading
(8 answers)
Closed 7 years ago.
I am new to Java EE. I have a site which requires a user to log in, and after the user logs in I would like the user to see his/her own item (e.g: shopping cart).
So that means I have to use a session to accomplish that. But how do I deal with multiple sessions?
For example multiple users login to the system as well as to the same servlet? However, can I keep multiple sessions in one servlet? Do I keep a record of each of them? How does it work?
Can someone give an example please ?
In servlet you have access to HttpServletRequest which provides you with a getSession() method. This methods returns session object (essentialy a key-value map), different for each user.
If you put something into that map (like shopping cart), you can retrieve it later - but only when the same user accesses the application again (not necessarily the same servlet).
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
HttpSession session = request.getSession();
session.getAttribute("cart");
//...
session.setAttribute("cart", whateverYouWant);
Sessions are maintained in the servlet container and looked up by session id (typically a cookie). You don't have to implement anything yourself.
Yes you can. The servlet container will keep track of them for you, so you shouldn't have to do that bookkeeping yourself. The Session object can be obtained from the HttpServletRequest in your servlet code. Since your code only has to concern itself with a single request at a time, there's generally not much pain in dealing with multiple sessions.
To deal with multiple users login in Servlets, create a session for each login as
HttpSession session = request.getSession();
public HttpSession getSession()
returns the current session associated with this request, or if the request does not have a session, creates one.
Each session will identify the users uniquely.
Now if user wants to change some data that is in database then after creating session, set attribute with that session with the information which can uniquely identify the user in database, for e.g. email_id as:
session.setAttribute("id",email_id of user);
This attribute can be retrieved later in another Servlet/JSP as:
String email_id = session.getAttribute("id");
This attribute will help in identifying the user who has sent request to server to update data in database or to do something else.
For more methods related to the session, refer the link:
http://www.javatpoint.com/http-session-in-session-tracking

Best strategy to handle page navigation in JSP

I am exploring JSP to implement dynamic web pages. One issue to solve is navigation between pages. Users have the possibility to go back and forward in their browsers.
This has to be handled. If someone logs out (for example), we don't want someone else to retrieve the session or data by clicking 'go back'. Another example is that we don't want to resubmit forms twice.
I am looking for tips and advices to solve page navigation issues. I would like to create a list of issues one has to take care of + possible solutions:
Issues:
Making sure sessions cannot be retrieved/hijacked with go back/forward clicks
Making sure forms and not submitted twice
Making sure users cannot fiddle cookies or URL data or hidden fields to break control flow and security
Solutions:
Implement a stack of visited pages
When a page is invoked, register the moment it is displayed to differentiate new requests from 'go back'
Control current session
P.S.: I have seen this question, but there is no real answer to it.
Making sure sessions cannot be retrieved/hijacked with go back/forward clicks
Just disable browser cache of those pages. See also Prevent user from seeing previously visited secured page after logout.
Making sure forms and not submitted twice
Generate a long, unique and impossible-to-guess string, store it in both the session ..
String token = UUID.randomUUID().toString();
((Set<String>) session.getAttribute("tokens")).add(token);
request.setAttribute("token", token);
request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);
.. and as a hidden input field of the form.
<input type="hidden" name="token" value="${token}" />
Upon submit, compare and remove the key in the session. If it was in the session, then proceed with submit.
if (((Set<String>) session.getAttribute("tokens")).remove(request.getParameter("token")) {
// Valid token. Proceed with submit.
} else {
// Invalid token. Possible double submit.
}
Making sure users cannot fiddle cookies or URL data or hidden fields to break control flow and security
Just write robust code yourself or use an existing and robust MVC framework like JSF2, Spring-MVC, Struts2, etc.
Solutions:
Implement a stack of visited pages
When a page is invoked, register the moment it is displayed to differentiate new requests from 'go back'
Control current session
Cumbersome.
To prevent double submission, I will use an example Apache Struts 1 used by using HttpSession.
What Struts did was to generate a random token that is stored in a session and added in a form page in a presentation layer (JSP). When a user submit a form, it checks from the session to see if the token given by the form is exactly the same session found in the session. If it's true, then process the request else it's a double submission.
Example:
public class AuthenticationAction extends Action {
public void displayLogout(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
saveToken(request);
return mapping.findForward("displayLogout");
}
public ActionForward doLogout(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
if (isValidToken(request)) {
//It wasn't yet a double submission, delete token generated by Struts
resetToken(request);
//logout.
...
//return back home
return mapping.findForward("home");
} else {
//Double submission..
throw new Exception("double submission");
}
}
}
A better tutorial is found here.
Hmm, you can also use the Spring Webflow framework if you want, but the use of the back and refresh not submitting your forms twice can easely be solved by defining your controller right. I think the use of REST can also help solve some problems.
The hiddenfield manipulation is another thing since a hiddenfield can always be viewed in the source of your page. And if the field can be viewed then it is open to manipulation.
To avoid re-inventing the wheel, using an existing framework seems to be the best solution. Struts looks like a good candidate. A simple introduction tutorial is available.

Java web app security: adding tokens to requests

I'm looking for a method or current API that allows you to add on tokens to web app requests.
Maybe within the session but not persisted.
Or if you could help me by outlining an efficient method for doing this
E.g.
1. GET request => Servlet generates a token and prints it in the view
2. returns a view with a hidden token
<input type="hidden" name="token" value="UA37jdjs9UDJS3">
<input type="submit" name="deleteEmail" value="Delete">
3. POST request => form is submitted and checks if the token is the same.
Few things to note, If there are Ajax requests then some other tokens would have to be alive for a number of requests.
If the user decides to close the browser, the token would have to die when the session
is timed-out.
If the user fails to complete the form, goes off to do something else on the site,
those tokens would have to be deleted as they go unused.
But what is the best way of implementing a system like this,
Does Spring Security 3 have a system that i can use?
within the Java,Grails,Spring MVC, Spring Security 3 and Hibernate area
Have a look at the HDIV project at http://www.hdiv.org/. They do exactly this. Even if you don't use the HDIV project's code then the information there may give you an option how to do it yourself. It was a good primer for me to learn about handling tokens for things like CSRF and other uses like double submit controls.
Did you take a look at "Synchronizer Token Pattern" in the Grails documentation at http://grails.org/doc/1.2.0/guide/single.html ?
First thought was that you might just use the already generated session id. But if you are trying to fork state I would suggest to use something like seams conversation model
Why don't just uses the session_id that the Web container generates for you when you call request.getSession()?
If you want to create your own "token" you might want to check Cookies.
A Cookie is a key-value pair sent as an HTTP header by a web server to a web browser and then sent back unchanged by the browser each time it accesses that server.
To create a cookie in a Servlet you can uses:
public void doGet ( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException {
// Create a cookie
Cookie c1 = new Cookie("yourdomain.token","the value");
response.addCookie(c1);
//build your response
}
The cookie will be automatically included in the next http request. You can read it back with:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
//build your response
}
I recently encountered a use case for this.
If an old application window was present in the browser, and a login link was clicked from another browser window, the login action first created a new session, and then redirected to the application window. This triggered the old window's onunload method method, which resulted in a logout request to the server logging out the new user.
Relying on a javascript onunload event for logging out seems kind of crappy to me, but this could not be changed, so we chose to do as the OP suggested and added a token in each rendered view, checking it for each request. This stops the onunload logout request from terminating the new session.
As to the best way, I would say this is pretty straightforward. You can for instance use http://java.sun.com/j2se/1.5.0/docs/api/java/util/UUID.html to generate unique keys. If you are using a component-based framework like Tapestry, JSF or Wicket there might be a more high-level way of handling this.
Is this similar to your usecase? Or are you trying to achieve something completely different?

Categories

Resources