Aller au menu - Aller au contenu

Icône Cycle de vie d'une JSP

Mise à jour : 24/07/2009
Difficulté : Difficile Difficile Creative Commons BY-NC-SA
10 160 visites depuis 7 jours, dont 284 sur ce chapitre classé 25/786
Dans ce chapitre, vous allez apprendre comment cela se passe chez notre ami le conteneur.
Vous en saurez un peu plus sur la vie de ces pages web dynamiques que l'on appelle communément JSP.

Certains vieux conteneurs, dont vous avez peut-être déjà entendu parler, ne supportent pas l'un des deux éléments de base de la plate-forme JEE. Cet élément est-il une servlet ou une JSP ?

Beaucoup pensent qu'il s'agit des servlets. Eh bien ils ont tort !
Ce sont les JSP qui ne sont pas supportées !
Pourquoi ?

Tout simplement parce que les JSP ont un cycle de vie un peu plus compliqué que nos servlets...

Cependant, aussi complexe soit ce cycle de vie, toutes nos JSP sortiront de leurs chrysalides afin de se transformer en servlets et être utilisées par le conteneur !
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire

Que savons-nous ?

Avant de vous narrer la vie d'une JSP, faisons un peu le point sur ce que nous savons. ^^

Tout d'abord, vous avez appris qu'une JSP est une page web dans laquelle du code Java a été inséré, ceci, via les balises <% %> ou par <%= %>.
Vous savez aussi que c'est à l'intérieur de ces balises que vous insérez votre code Java.

Tout code présent entre ces balises s'appelle un scriptlet !

Lorsque, dans vos JSP, vous utilisez des objets nécessitant un import, vous avez le choix de faire cet import ou d'utiliser le nom complet de l'objet (avec le nom de package) afin de pouvoir l'instancier et l'utiliser. Donc, faire ceci :

Code : JSP
1
2
3
<%@ page import="java.util.Date" %>
<!-- Code HTML -->
<p> <%= new Date() %> </p>


Ou ceci :

Code : JSP
1
2
<!-- Code HTML -->
<p> <%= new java.util.Date() %> </p>


Nous approfondirons la balise d'import d'ici peu de temps, mais pas tout de suite...

Vous n'ignorez pas qu'il existe des objets dont l'import n'est pas nécessaire. Vous en connaissez déjà trois :
  • (PrintWriter) out ;
  • (HttpServletRequest) request ;
  • (HttpServletResponse) response.


Mais il y en a d'autres, nous y viendrons bientôt, je vous rassure...

Bon, vous voyez d'autres choses ?
Euh... Non... :euh:

Ah oui ! C'est tout !
Je pensais vous en avoir dit plus que ça... ^^
Le moment est venu d'en apprendre davantage sur nos chères JSP !

De JSP à servlet

Je vous l'ai déjà dit dans l'introduction mais nos JSP se transforment en servlets ! :waw:
Non, vous ne rêvez pas et vous m'avez bien compris. D'ailleurs, afin d'appuyer mes dires, je vous invite à créer une simple JSP sans code spécial. Nous l'appellerons index.jsp et nous la mettrons à la racine de notre projet, nouveau projet que nous allons appeler "CONTENEUR". Voici le code de cette dernière :

Code : JSP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Titre de notre JSP</title>
</head>
<body>

</body>
</html>


Il s'agit tout bonnement du code généré par Eclipse lorsque vous faites "file/new/web/jsp".
Je vous invite à aller, dans votre navigateur, voir notre page à l'adresse http://localhost:8080/CONTENEUR/index.jsp.
Celle-ci n'affiche rien du tout ; par contre, quelque part dans votre projet, cette page JSP toute simple est devenue une servlet.

Où ça ?


Allez faire un tour dans le dossier "work" de votre projet, vous pouvez d'ailleurs y accéder depuis Eclipse :

Image utilisateur


Déjà, vous aurez remarqué qu'il y a un package nommé org.apache.jsp et que dans celui-ci, il y a une classe Java qui a un nom étrangement familier : index_jsp.java. :-°
C'est un nom qui ressemble énormément à index.jsp, n'est-ce pas ? Voici son contenu :

Code : Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.List _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.AnnotationProcessor _jsp_annotationprocessor;

  public Object getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }

  public void _jspDestroy() {
  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html; charset=ISO-8859-1");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\r\n");
      out.write("<title>Titre de notre JSP</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}


Mais ce n'est pas une servlet ! Cette classe hérite de HttpJspBase


Eh bien si, justement parce que cette classe hérite directement de HttpServlet, classe que je ne vous présente plus. :)
Ceci signifie bien que cette classe est une pure servlet. D'ailleurs, vous pouvez constater que le nom des méthodes présentes ici ressemble beaucoup à celles qu'on trouve dans nos servlets :
  • - _jspService(HttpServletRequest request, HttpServletResponse response) ressemble beaucoup à la méthode service(HttpServletRequest request, HttpServletResponse response) de nos servlets ;
  • - _jspInit() ressemble à la méthode init() ;
  • - _jspDestroy() ressemble à la méthode destroy().


Intéressons-nous plus particulièrement au contenu de la méthode _jspService(HttpServletRequest request, HttpServletResponse response). Vous aurez sans doute constaté que nous retrouvons le contenu de notre JSP, écrit comme nous aurions pu le faire dans une servlet et, en plus, nous savons maintenant pourquoi certains objets n'ont pas besoin d'être importés, comme le montre la figure ci-dessous :

Image utilisateur


Vous pouvez voir, dans l'encadré du dessus, qu'un certain nombre d'objets sont initialisés et sont donc utilisables directement . ensuite, vous pouvez voir l'écriture du code HTML de notre JSP. En fait, c'est pourquoi les objets du premier encadré n'ont pas besoin d'être importéS : ils sont initialisés automatiquement par le conteneur. :)

Ce sont les objets suivants :

  • HttpServletRequest request : permet de récupérer les paramètres de la requête HTTP ;
  • HttpServletResponse response : permet de récupérer la réponse renvoyée avec les informations générées par le traitement de la requête. Nous avons déjà utilisé ceci précédemment...
  • JspWriter out : permet d'écrire dans le flux de sortie et ainsi ajouter du contenu à votre page web ;
  • Object page : peu utilisée, cette variable permet de faire référence à la servlet créée depuis la page JSP, ça revient à utiliser this ;
  • ServletConfig config : joue le même rôle que l'objet ServletConfig ;
  • ServletContext application : joue le même rôle que l'objet ServletContext ;
  • - PageContext pageContext : permet de centraliser et d'obtenir les attributs de la page JSP ;
  • - HttpSession session : permet d'accéder aux informations mises en session.


Et comment se fait-il que ces objets soient utilisables sans import ni déclaration ?

Tout simplement car le code Java que vous mettez dans vos JSP se retrouve dans la méthode _jspService(), écrit comme si vous l'aviez fait vous-même. Le mieux est de voir ce que nous donne une JSP avec des imports, du code Java, etc.
Modifiez le fichier index.jsp pour qu'il corresponde au code suivant :

Code : JSP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
 <%@ page import=" 
 	java.text.SimpleDateFormat, 
 	java.util.Date" %>
 
 <%! int global = 10; %>
 
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Cycle de vie d'une JSP</title>
</head>
<body>
<% out.println("<h1>Nous sommes le : " + 
		new SimpleDateFormat("dd/MM/yyyy").format(new Date()) + "</h1>"); %>
<h1>il est : <%=new SimpleDateFormat("HH:mm:ss").format(new Date()) %></h1>

<% 
	out.println("<p>Nous allons voir comment notre conteneur gère nos JSP.</p>"); 

 	String[] list = new String[]{"Et d'un", "Et de deux", "Et de trois"};
   	out.println("<ul>");

   	for(String str : list)
     	out.println("<li>" + str + "</li>");
	
   	out.println("</ul>");

%>
</body>
</html>


Et la servlet correspondant à cette JSP est :

Code : Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.text.SimpleDateFormat;
import java.util.Date;

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

 int global = 10; 
  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html; charset=ISO-8859-1");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write(" \r\n");
      out.write(" \r\n");
      out.write(" ");
      out.write("\r\n");
      out.write(" \r\n");
      out.write("<html>\r\n");
      out.write("\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\r\n");
      out.write("<title>Cycle de vie d'une JSP</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.println("<h1>Nous sommes le : " + 
		new SimpleDateFormat("dd/MM/yyyy").format(new Date()) + "</h1>"); 
      out.write("\r\n");
      out.write("<h1>il est : ");
      out.print(new SimpleDateFormat("HH:mm:ss").format(new Date()) );
      out.write("</h1>\r\n");
      out.write("\r\n");
 
	out.println("<p>Nous allons voir comment notre conteneur gère nos JSP.</p>"); 

 	String[] list = new String[]{"Et d'un", "Et de deux", "Et de trois"};
   	out.println("<ul>");

   	for(String str : list)
     	out.println("<li>" + str + "</li>");
	
   	out.println("</ul>");


      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}


Comparatif entre notre JSP et la servlet associée :

Image utilisateur


Vous comprenez mieux comment les pages JSP fonctionnent, à présent, et vous savez pourquoi il existe des objets utilisables sans import.
Explicitons tout de même le schéma ci-dessus. Vous pouvez voir que les imports sont automatiquement ajoutés au-dessus de la déclaration de la servlet associée à notre JSP. Le code Java, lui, est concaténé dans la méthode _jspService(). Ainsi, ledit code est interprété et effectif lorsque le conteneur invoque ladite méthode. Ensuite, vous avez vu une nouvelle instruction : <%! int global = 10; %>. Celle-ci permet de déclarer une variable d'instance de notre servlet : celle-ci sera donc commune à tous les threads utilisant notre JSP sans la réinitialiser.

En résumé

En fait, vu que je vous ai habitué à des schémas, je pense qu'il serait de bon ton de vous en fournir un pour le cycle de vie d'une JSP :

Image utilisateur


Vous pouvez mieux vous représenter ce qu'il se passe dans Tomcat, maintenant. Il en fait des choses, notre petit matou… ;)
Allez, examinons un peu ce schéma.
  • Quelqu'un appelle une page JSP, via une URL ou en cliquant sur un lien.
  • La requête est dirigée vers le serveur de notre application.
  • Tomcat prend en charge la requête et s'aperçoit qu'une page JSP est demandée.
  • Il trouve ladite page et la convertit en fichier source java, en servlet pour être exact.
  • Ladite servlet est compilée et mise en mémoire, enfin prête à l'utilisation.
  • La méthode _jspInit() est invoquée.
  • Tomcat crée un nouveau thread pour traiter la demande et invoque dans ce thread la méthode _jspService().
  • Le résultat, une page entièrement constituée de code HTML, est retournée par Tomcat au demandeur de départ, le client.

Vous pouvez voir que ce cycle ressemble très fortement à celui de la vie d'une servlet standard, à quelques différences mineures près, mais l'essentiel est là. :)
Bon : avant d'aborder une nouvelle notion, elle aussi gérée par notre conteneur favori, je vous propose un QCM.

Q.C.M.

Quelle instruction permet d'importer une classe java dans une page JSP ?
Quel objet peut être utilisé sans procéder à un import particulier ?
Grâce à quelle instruction pouvons-nous déclarer une variable qui ne se réinitialise pas à chaque fois dans une JSP ?
Dans quel dossier de votre application se génèrent les servlets correspondant à vos pages JSP ?

Statistiques de réponses au QCM

Je sens que vous êtes un peu frustré parce que ça fait deux chapitres que nous n'avons pas vraiment codé...
Cependant, dites-vous bien que tout ceci vous permettra une meilleurs compréhension des choses et donc, vous permettra de mieux appréhender la programmation avec JEE.

Allez, nous allons retourner vers des choses plus concrètes... ^^
Chapitre précédent Sommaire

Partager

1 commentaire pour "Cycle de vie d'une JSP"
Note moyenne : 3.17 / 4 (294 votes)
Pseudo Commentaire
Hors ligne softdounia # Posté le 04/06/2011 à 16:44:16
A
Avatar

Ville : Alger
Pays : Algérie
Études : ETS Montréal

A quand la suite ? (se devine urgant)

Les 40e rugissants et les 50e hurlants. o_O --> Brainstorming --> CamelCase
Image utilisateur

-------------
"je crois qu'on ne peut mieux vivre qu'en chercant à devenir meilleur, ni plus agréablement qu'en ayant pleine conscience de son amélioration"
Socrate >_<
-------------
les meilleurs peintres se sont fait dire qu’ils n’étaient pas bon, aujourd’hui ce sont des Dieux!
-------------
RTFM :-° l'expression anglaise d'argot Internet Read the fucking manual (« Lis le foutu manuel ») ;
-------------
Mon CV en ligne ici
 

Voir tous les commentaires