Gestionarea sesiunilor utilizand servlet-uri

Protocolul HTTP este un protocol fara stare. Aceasta inseamna ca pentru fiecare cerere facuta catre serverul web, clientul deschide o conexiune, realizeaza operatia si apoi inchide conexiune. Serverul trateaza fiecare conexiune ca si un client nou, ne existand o modalitate directa de asociere dintre mai multe cereri succesive ce vin de la acelasi client (utilizator). Exista situatii in care dorim sa pastram un istoric al actiunilor utilizatorului - de exemplu in cadrul unui magazin online dorim sa pastram cosul de comanda.

Putem defini sesiunea ca fiind o stare conversationala dintre un server si un client din momentul in care clientul face prima cerere pana in momentul in care conversatia este finalizata. Avand in vedere ca atat serverul cat si clientul sunt fara stare, singura modalitate de a pastra aceasta stare este prin transmitere unor informatii unice intre server si client la fiecare cerere/raspuns.

Cateva dintre mecanismele prin care putem sa gestionam sesiunile sunt:

Autorizare utilizator Aceasta metoda presupune autentificarea utilizatorului prin nume de utilizator si parola, dupa care aceste informatii de autentificare sunt transmise la fiecare cerere/raspuns.

Rescrierea URL-urilor Aceasta metoda presupune atasarea unui identificator de sesiune pentru fiecare cerere\raspuns.

Cookies Cookie-urile sunt bucati de informatie pe care serverul web le poate trimite (in headre-ul mesajului de raspuns) catre client . In urmatoarele cereri clientul poate atasa aceasta informatie, putandu-se urmari astfel sesiunea unui utilizator. Acest mecanism poate fi dezactivat de catre utilizator (din setarile browser-ului de internet), facand astfel imposibila gestionarea sesiunilor prin acest mecanism.

Servlet Session Management API Este un API ce incorporeaza mecanismele anterior enumerate si ofera o interfata unitara de gestionare a sesiunilor prin intermediul servlet-urilor.

Exista doua tipuri de cookie-uri:

  • persistente - un astfel de cookie este sters atunci cand browserul este inchis;
  • ne-persistente - un astfel de cookie isi pastreaza starea si dupa repornirea browser-ului.

In cadrul Servlet API, clasa javax.servlet.http.Cookie ofera functionalitatile necesare pentru gestionarea cookie-urilor.

Creare cookie

Cookie ck=new Cookie("user","alin dan");//construire obiect cookie
response.addCookie(ck);//adaugare cookie in raspuns 

Stergere cookie

Cookie ck=new Cookie("user","");//stergere valoare cookie
ck.setMaxAge(0);  
response.addCookie(ck);//adaugare cookie in raspuns 

Citire cookie

Cookie ck[]=request.getCookies();  
for(int i=0;i<ck.length;i++){  
 out.print("<br>"+ck[i].getName()+" "+ck[i].getValue());//afisare nume si valoare cookie
}  

Gestionarea sesiunilor folosind HTTPSession

Servlet API pune la dispozita programatorlui clasa HTTPSession prin intermediul careia utilizatorul poate gestiona sesiunile. Prin intermediul acestei clase programatorul poate stoca la nivelul sesiunii clientului atribute (atribute de sesiune). Un atribut de sesiune este un obiect java care este atasat la o sesiune.

Crearea sesiunii

 //Citeste o sesiune (daca aceasta exista) iar daca nu exista este construita.
 HttpSession session = request.getSession(true);

Adaugare informatii in sesiune

 session.setAttribute("username", username);
 session.setAttribute("password", password);

Citire obiect sesiune

//citeste obiectul de sesiune daca acesta exista
 HttpSession session = request.getSession(false);

Citire continut sesiune

 Enumeration names = session.getAttributeNames();
 while (names.hasMoreElements()) {
  String name = (String) names.nextElement();
  String value = (String)session.getAttribute(name);
  //...
 }

Invalidare sesiune

HttpSession sess = req.getSession(false);
  if (sess != null) {
    sess.invalidate();
  }

Exemplu complet

Servletul Login.java citeste numele de utilizator si parola, construieste obiectul sesiune, dupa care tirmite catre client un link catre servlet-ul GetSession.java ce afiseaza informatiile de sesiune.

@WebServlet(name = "Login", urlPatterns = {"/Login"})
public class Login extends HttpServlet {
 
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // Get the session - if no session exists create one
        HttpSession session = request.getSession(true);
    // Set some attribute values to the session
        // In this case user and password from the request and client
        session.setAttribute("username", username);
        session.setAttribute("password", password);
 
        try {
            response.setContentType("text/html");
            PrintWriter writer = response.getWriter();
            writer.println("<html><body>");
            writer.println("Thank you, " + username
                    + ". You are now logged into the system");
      // Encodes the specified URL by including the session ID in it,
            // or, if encoding is not needed, returns the URL unchanged
            String newURL = response.encodeURL("/WebLoginSession/GetSession");
            // Return a <a> tag with the new url
            writer.println("Click <a href=\"" + newURL
                    + "\">here</a> for another servlet");
            writer.println("</body></html>");
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Form-ul HTML de login.

   <html>
    <head>
        <title>Login with HttpSession example</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <div>
        Please enter your user name and password:
         <form action="Login" method="POST">
             <p><input type="text" name="username">
             <p><input type="password" name="password">
             <p><input type="submit" value="Submit">
        </form>
        </div>
    </body>
</html>

Servlet-ul GetSession citeste obiectul sesiune, impreuna cu atributele adaugate in sesiune.

@WebServlet(name = "GestSession", urlPatterns = {"/GetSession"})
public class GetSession extends HttpServlet {
 
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
 
        HttpSession session = request.getSession(false);
        try {
            response.setContentType("text/html");
            PrintWriter writer = response.getWriter();
            writer.println("<html><body>");
            // If you are not in a session - you are not logged in
            if (session == null) {
                writer.println("<p>You are not logged in</p>");
            } else {
                writer.println("Thank you, you are already logged in");
                writer.println("Here is the data in your session");
                Enumeration names = session.getAttributeNames();
                while (names.hasMoreElements()) {
                    String name = (String) names.nextElement();
                    Object value = session.getAttribute(name);
                    writer.println("<p>name=" + name + " value=" + value + "</p>");
                }
            }
            // Write html for a new login 
            writer.println("<p><a href=\"/WebLoginSession/login.html\">Return"
                    + "</a> to login page</p>");
            writer.println("</body></html>");
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
}