#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2002
    Posts
    29
    Rep Power
    0

    Question session.removeAttribute("name") problems


    Hi,

    I am working on an online vehicle quoting system. I have written a servlet which takes all the variables from forms, DB, sessions, performs the calculation and then stores the result into a string array and place that in a session.

    Each time this servlet is called, I need to clear the previous session and then proceed with the new quote. I have the following code taking care of this:

    HttpSession session = request.getSession(false);

    System.out.println("1. "+session.getAttribute("quoteVariables"));
    if ( session.getAttribute("quoteVariables") != null ) session.removeAttribute("quoteVariables");
    System.out.println("2. "+session.getAttribute("quoteVariables"));
    session.setAttribute("quoteVariables",quoteVariables);
    System.out.println("3. "+session.getAttribute("quoteVariables"));

    The 1st line prints a null for the 1st quotation and subsequently prints the session id. Second line always prints a null, so it succeeds in clearing the session and 3rd print is always the session id.

    However, despite this it keeps some of the varibales from the previous quote, those which do not change and fills the others with the new values.

    For example, if a do a quote for an audi with three extras and then goto to do a second quote for a BMW with no extras it will keep the initial extras (from the audi) - however in the screen where i select extras it has no extras selected.

    I can not use session.invalidate() as I still have to keep other session information (loginID, corporateID etc).

    Can anyone help me with this. I have seen a number of questions on this in the Java forums and the only solution being sesssion.invalidate(). May I further add that I successfull clear up the login details of the session using session.removeAttribute in a JSP page (not in a servlet).

    Your help will be most appreciated as I can not see what I am doing wrong.

    Regards

    FK.
  2. #2
  3. No Profile Picture
    Moderator =(8^(|)
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2002
    Location
    Sacramento, CA
    Posts
    1,710
    Rep Power
    14
    Are you sure that quoteVariables is being changed between session calls? It looks like you might be putting the old values back into the session again.
  4. #3
  5. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2002
    Posts
    29
    Rep Power
    0
    Thanks for that reply.

    I think I have discovered the problem, but not sure of the solution. I have a servlet, which in body of the class creates 40 private variables (private String vehicleSec = ""; etc...). Then the doPost method decided which method to hand the control over to: When it goes into method calculate(), it assigns values to those 40 odd variables, some from the form, others from session vars, some from DB etc.. Then calls the createReport() method, which stores all the variables into an array and sticks the array into a session (dont know if that is a good practice).

    After I login, for the 1st quote this works fine because all the variables start empty and then appropriate values are assigned to them but for subsequent calls to this servlet it seems to keep the values from the previous call and the vars which have new values assigns them, otherwise keeps the previous ones.

    I thought the fact that I am doing the following:

    public class QuotationServlet extends HttpServlet {

    private ArrayList optionsList = new ArrayList();
    private String vehicleDesc = null;
    private String capID = null;
    private String GAPName = null;
    ....

    }

    would ensure that the varibales are all reset at the start. How would I sort this out?

    Kind Regards

    FK
  6. #4
  7. No Profile Picture
    Moderator =(8^(|)
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2002
    Location
    Sacramento, CA
    Posts
    1,710
    Rep Power
    14
    In your doPost method, right off the bat (before anything else), make all your variables null again. That should take care of it.
  8. #5
  9. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2002
    Posts
    29
    Rep Power
    0
    The only problem with that would be that I need to repeat that nulling of variables in the doGet aswell, as this servlet will be called by post and get.

    I have at the moment declared all the variables at the top of the class to make them available to all the methods. I have added a public void init() method which null all the variables but still no luck.

    Is there really no other way than repeating the nulling of these variables in both doGet and doPost?

    Regards

    FK
  10. #6
  11. No Profile Picture
    Moderator =(8^(|)
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2002
    Location
    Sacramento, CA
    Posts
    1,710
    Rep Power
    14
    Do you treat get and post differently? If you don't, you could use the service() method.

    Another option would be to use a Hashtable to store your values. Then you only have to null one variable.
  12. #7
  13. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2002
    Posts
    29
    Rep Power
    0
    The doGet() and doPost() methods will need to do different things, so I guess I will need to use hash tables. Why can't life be simpler.

    Thanks for your help.

    FK
  14. #8
  15. No Profile Picture
    Moderator =(8^(|)
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2002
    Location
    Sacramento, CA
    Posts
    1,710
    Rep Power
    14
    Good luck
  16. #9
  17. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2002
    Posts
    29
    Rep Power
    0
    In case someone falls into the same error as me, I thought I'll make a few points about a valuable lesson I learnt from this error in my approach.

    I fundamentally failed to understand the lifecycle of a servlet - namely the fact that a servlet is created once and all subsequent calls are made to its threads. Therefore the class level variables and the init() method are only ever called once.

    In order to get over this I could have over-ridden the service() method (which is a bad habit for number of reasons discussed in "Core Servlets and JavaServer Pages") alternatively I could have reset all 40 of my variables inside the doGet method but then I handle the doGet and doPost methods differently so I need to repeat the code in both places.

    In the end I guess as bricker42 kindly suggested the only option left was to use a hash table or something similar. In my case i chucked all the variables from init() into a mthod called resetVariables() and then simply call that method at the start of the doGet() and doPost().

    I just wanted to point out an obvious matter which someone like me may easily miss.

    Regards

    FK
  18. #10
  19. No Profile Picture
    Moderator =(8^(|)
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2002
    Location
    Sacramento, CA
    Posts
    1,710
    Rep Power
    14
    Another thing you might want to check (and this gets sticky), is how your servlet responds in a multithreaded environment. You might need to synchronize all your variables to keep data from being overwritten by concurrent connections.

    I haven't tested this, but I've read warnings about it.

    Here's a good discussion about it:
    http://saloon.javaranch.com/cgi-bin/...c&f=7&t=001185
  20. #11
  21. No Profile Picture
    Moderator =(8^(|)
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2002
    Location
    Sacramento, CA
    Posts
    1,710
    Rep Power
    14
  22. #12
  23. No Profile Picture
    Clueless llama
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Feb 2001
    Location
    Lincoln, NE. USA
    Posts
    2,353
    Rep Power
    117
    Bricker touched upon another problem you are going to have, namely that you keep the variables as member variables of the servlet and this is a multi-threaded environment. In essence you have one set of variables and n number of users calling servlets potentially at the same time all fighting to use those variables. At 12:00:00 someone will call the servlet and set those variables to a value, but at 12:00:30 someone else will use the servlet and set them to something else. Then when user one gets his quote, it is with the options that user two set them to. I hope that makes sense.

    A better way would be to make something like a "quote" bean that a user gets when looking for a quote. It could contain everything needed for a quote, such as vehicle make, year, options, whatever and you merely have to invalidate that one bean in the session when someone starts a new quote. Hope that helps.
  24. #13
  25. No Profile Picture
    Moderator =(8^(|)
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2002
    Location
    Sacramento, CA
    Posts
    1,710
    Rep Power
    14
    Ya, that's probably a much better idea. Put the calculate() and createReport() methods into the bean as well. That's probably better coding practice anyway . It seperates your logic a bit more clearly (assuming you like the whole MVC thing).
    -james
  26. #14
  27. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2002
    Posts
    29
    Rep Power
    0
    I am as you guys may have guessed fairly new to this environment, come from a PHP and Cold Fusion background. Have learnt and developed this new app in Java through learning on the job. I am beginining to appreciate the importance of MVC but still stumble on many aspects. Initially I wrote the whole thing in JSP MVC Model 1 and now implementing the app in MVC Model 2.

    Could you please clarify, how I would use a bean, I have a bean quote which takes care of saving, updating, deleting quotes.

    The servlet is simply there to calculate (1st time generation), re-calculate (after changing the residual value), re-validate (if the quote is over 7 days old) and recall (pull out of DB and display) a quote.

    I have tested the servlet with two different users simultaneously performring a quote and it seems to be fine. Would the problem show in a more intense environment. I replicated the scenario that Nemi described.

    Kind Regards

    FK
  28. #15
  29. No Profile Picture
    Moderator =(8^(|)
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2002
    Location
    Sacramento, CA
    Posts
    1,710
    Rep Power
    14
    Basically, take your 40 variables, and all the functions that are solely for operating on those variables, and throw them into a new class. You can then store an instance of this class in your session, and save yourself a big headache.

    Have you servlet create a new instance of the class, store it in the session, and call some of the methods (calclulate(), etc.).
    -james

IMN logo majestic logo threadwatch logo seochat tools logo