Skip to content

5. MVC [personne] web uygulaması – sürüm 1

5.1. Uygulamanın görünümleri

Uygulama, önceki örneklerde kullanılan formu kullanır. Uygulamanın ilk sayfası şöyledir:

Image

Bu görünüme [formulaire] adı vereceğiz. Doğru girişler yapıldığında, bunlar [réponse] adı verilen bir görünümde görüntülenir:

Image

Girişler yanlışsa, hatalar [erreurs] adlı bir görünümde bildirilir:

Image

5.2. Uygulamanın mimarisi

[personne1] web uygulaması aşağıdaki mimariye sahip olacaktır:

Image

Bu mimari tek katmanlı bir mimaridir: [métier] veya [dao] katmanları yoktur, yalnızca bir [web] katmanı vardır. [ServletPersonne], istemcilerin tüm isteklerini işleyen uygulama denetleyicisidir. Bu isteklere yanıt vermek için üç [formulaire, réponse, erreurs] görünümünden birini kullanır.

[ServletPersonne] denetleyicisinin, bir kullanıcıdan gelen isteği aldığında ne yapması gerektiğini nasıl belirlediğini anlamamız gerekiyor. Bir istemci isteği, HTTP akışıdır ve bu akış, GET veya POST komutuyla yapıldığına göre farklılık gösterir.

GET İsteği

Bu durumda, HTTP akışı aşağıdaki gibidir:

GET /URL HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0,5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
[ligne vide]
  1. satır, istenen URL'yi belirtir; örneğin:
GET /personne1/ HTTP/1.1

Bu URL, gerçekleştirilecek eylemi belirtmek için kullanılabilir. Çeşitli yöntemler kullanılabilir:

  1. URL'deki bir parametre eylemi belirtir; örneğin, [/appli?action=ajouter&id=4]. Burada [action] parametresi, denetleyiciye talep edilen eylemi bildirir.
  2. URL'nin son öğesi eylemi belirtir; örneğin, [/appli/ajouter?id=4]. Burada, URL'nin son öğesi olan [/ajouter], denetleyici tarafından gerçekleştirilmesi gereken eylemi belirlemek için kullanılır.

Başka çözümler de mümkündür. Yukarıdaki iki örnek yaygın olarak kullanılmaktadır.

POST isteği

Bu durumda, HTTP akışı aşağıdaki gibi görünür:

POST /URL HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://localhost:8080/personne1/main
Cookie: JSESSIONID=9F5E5BFA29643FC6B1601EEED907E1F9
Content-Type: application/x-www-form-urlencoded
Content-Length: 43
[ligne vide]
txtNom=&txtAge=&action=validationFormulaire
  1. satır, istenen URL'yi belirtir; örneğin:
POST /personne1/main HTTP/1.1

Bu URL, GET örneğinde olduğu gibi gerçekleştirilecek eylemi belirtmek için kullanılabilir. GET örneğinde, [action] parametresi URL'e dahil edilmişti. Bu durum, aşağıdaki örnekte olduğu gibi burada da geçerli olabilir:

POST /appli?action=ajouter&id=4 HTTP/1.1

Ancak [action] parametresi, aşağıdaki örnekte olduğu gibi gönderilen parametrelere (yukarıdaki 15. satır) de dahil edilebilir:

POST /appli HTTP/1.1
...
[ligne vide]
action=ajouter&id=4

Aşağıda, denetleyiciye ne yapması gerektiğini belirtmek için bu farklı teknikleri kullanacağız:

  • istenen URL'ye action parametresini eklemek:
POST /appli?action=ajouter&id=4 HTTP/1.1
  • action parametresini göndermek:
POST /appli HTTP/1.1
...
[ligne vide]
action=ajouter&id=4
  • URL'nin son öğesini eylem adı olarak kullanın:
POST /appli/ajouter?id=4 HTTP/1.1

5.3. Eclipse Projesi

[personne1] web uygulamasının Eclipse projesi [mvc-personne-01]'i oluşturmak için, 3.1. paragrafında açıklanan adımları izleyin.

Image

Varsayılan olarak önerilen [mvc-personne-01] bağlamını kullanmayacağız. Aşağıda gösterildiği gibi [personne1]'i seçeceğiz:

Image

Elde edilen sonuç şöyledir:

Image

Eğer web uygulamasının bağlamını değiştirmek istersek, [clic droit sur projet -> Properties -> J2EE] seçeneğini kullanacağız:

Image

[1] ile yeni bağlam belirtilecektir.

[WEB-INF] klasörünün içine [vues] adlı bir alt klasör oluşturacağız: [clic droit sur WEB-INF -> New -> Folder]:

Yeni proje artık şudur:

Image

Tamamlandığında proje şu şekilde olacak:

Image

  • [ServletPersonne] denetleyicisi, [src] klasöründedir
  • [formulaire, réponse, erreurs] görünümlerine ait JSP sayfaları, [WEB-INF/vues] klasöründe yer almaktadır; bu da, aşağıdaki örnekte gösterildiği gibi, kullanıcının bu sayfaları doğrudan çağırmasını engellemektedir:

Image

Şimdi [/personne1] web uygulamasının çeşitli bileşenlerini açıklayacağız. Okuyucunun, okuma sürecinde bu bileşenleri oluşturması önerilir.

5.4. [personne1] web uygulamasının yapılandırılması

/personne1 uygulamasının web.xml dosyası aşağıdaki gibi olacaktır:


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
  <display-name>mvc-personne-01</display-name>
    <!--  ServletPersonne -->
    <servlet>
        <servlet-name>personne</servlet-name>
        <servlet-class>
            istia.st.servlets.personne.ServletPersonne
        </servlet-class>
        <init-param>
            <param-name>urlReponse</param-name>
            <param-value>
                /WEB-INF/vues/reponse.jsp
            </param-value>
        </init-param>
        <init-param>
            <param-name>urlErreurs</param-name>
            <param-value>
                /WEB-INF/vues/erreurs.jsp
            </param-value>
        </init-param>
        <init-param>
            <param-name>urlFormulaire</param-name>
            <param-value>
                /WEB-INF/vues/formulaire.jsp
            </param-value>
        </init-param>
    </servlet>
    <!--  Eşleme ServletPersonne-->
    <servlet-mapping>
        <servlet-name>personne</servlet-name>
        <url-pattern>/main</url-pattern>
    </servlet-mapping>
    <!--  ana sayfalar -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Bu yapılandırma dosyası ne anlatıyor?

  • 34-37. satırlar: /main URL, “person” adlı servlet tarafından işlenir
  • 10-13. satırlar: "person" adlı servlet, [ServletPersonne] sınıfının bir örneğidir
  • 14-19. satırlar: [urlReponse] adlı bir yapılandırma parametresini tanımlar. Bu, [réponse] görünümünün URL'sidir.
  • 20-25. satırlar: [urlErreurs] adlı bir yapılandırma parametresini tanımlar. Bu, [erreurs] görünümünün URL'sidir.
  • 26-31. satırlar: [urlFormulaire] adlı bir yapılandırma parametresini tanımlar. Bu, [formulaire] görünümünün URL'sidir.
  • 40. satır: [index.jsp], uygulamanın ana sayfası olacaktır.

[formulaire, réponse, erreurs] görünümlerinin JSP sayfalarının URL'leri, her biri ayrı bir yapılandırma parametresine sahiptir. Bu sayede, uygulamayı yeniden derlemeye gerek kalmadan bu sayfaları taşıyabilirsiniz.

Kullanıcı [/personne1] URL’sini talep ettiğinde, yanıtı [index.jsp] dosyası gönderecektir (ana sayfa dosyası, 40. satır). Bu dosya, [WebContent] klasörünün kök dizininde bulunur:

Image

İçeriği şu şekildedir:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
  response.sendRedirect("/personne1/main");
%>

[index.jsp] sayfası, istemciyi [/personne1/main] URL'sine yönlendirmekle yetinir. Böylece, tarayıcı [/personne1] URL'sini talep ettiğinde, [index.jsp] ona şu HTTP yanıtını gönderir:

1
2
3
4
5
6
7
HTTP/1.x 302 Déplacé Temporairement
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=9F5E5BFA29643FC6B1601EEED907E1F9; Path=/personne1
Location: http://localhost:8080/personne1/main
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Thu, 18 May 2006 15:45:23 GMT
  • 1. satır: Sunucuya başka bir URL adresine yönlendirilmesi gerektiğini belirten HTTP/1.1 yanıtı
  • 4. satır: Tarayıcının yönlendirilmesi gereken URL adresi

Bu yanıtın ardından tarayıcı, kendisine istenen şekilde (4. satır) [/personne1/main] URL'sini isteyecektir. [/personne1] uygulamasının [web.xml] dosyası, bu isteğin [ServletPersonne] denetleyicisi tarafından işleneceğini belirtir (satır 35-36).

5.5. Görünüm kodları

Web uygulamasını yazmaya, görünümlerini yazarak başlıyoruz. Bu görünümler, kullanıcının grafik arayüz açısından ihtiyaçlarını belirlemeye olanak tanır ve denetleyici olmadan da test edilebilir.

5.5.1. [formulaire] görünümü

Bu görünüm, isim ve yaş giriş formuna aittir:

Image

türü HTML
ad
rol
1
<input type="text">
txtNom
ad girişi
2
<input type="text">
txtAge
yaş girişi
3
<input type= "submit ">
 
girilen değerlerin /personne1/main URL'sine sunucuya gönderilmesi
4
<input type= "reset ">
 
Sayfayı tarayıcı tarafından ilk alındığı duruma geri döndürmek için
5
<input type= "button ">
 
[1] ve [2] giriş alanlarının içeriğini silmek için

Bu, JSP [formulaire.jsp] sayfası tarafından oluşturulur. Şablonu aşağıdaki öğelerden oluşur:

  • [nom]: "nom" anahtarıyla ilişkili oturum özniteliklerinde bulunan bir ad (String)
  • [age]: "age" anahtarıyla ilişkili oturum özniteliklerinde bulunan bir yaş (String)

Kullanıcı [/personne1/main], c.a.d URL'lerini talep ettiğinde [formulaire] görünümü elde edilir. [ServletPersonne] denetleyicisinin URL'si. [formulaire] görünümünü oluşturan JSP ve [formulaire.jsp] sayfalarının kodu şöyledir:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
    // şablondaki veriler alınır
  String nom=(String)request.getAttribute("nom");
  String age=(String)request.getAttribute("age");
%>
    
<html>
    <head>
      <title>Personne - formulaire</title>
  </head>
  <body>
      <center>
        <h2>Personne - formulaire</h2>
      <hr>
      <form method="post">
          <table>
            <tr>
              <td>Nom</td>
            <td><input name="txtNom" value="<%= nom %>" type="text" size="20"></td>
          </tr>
          <tr>
              <td>Age</td>
            <td><input name="txtAge" value="<%= age %>" type="text" size="3"></td>
          </tr>
            <tr>
        </table>
        <table>
            <tr>
              <td><input type="submit" value="Envoyer"></td>
            <td><input type="reset" value="Rétablir"></td>
            <td><input type="button" value="Effacer"></td>
          </tr>
        </table>
        <input type="hidden" name="action" value="validationFormulaire"> 
      </form>
    </center>
  </body>
</html>

  • 6-7. satırlar: JSP sayfası, [request] isteğinden modelindeki [nom, age] öğelerini alarak başlar. Uygulamanın normal çalışması sırasında, bu şablonu oluşturan [ServletPersonne] denetleyicisi olacaktır.
  • 18-38. satırlar: JSP sayfası, bir HTML formu (<form> etiketi) oluşturacaktır.
  • 18. satır: <form> etiketinde, submit türündeki [Envoyer] düğmesi tarafından gönderilen değerleri işleyecek URL'yi belirtmek için action özniteliği bulunmamaktadır (32. satır). Bu durumda, formdaki değerler, formun alındığı URL'ye, yani [ServletPersonne] denetleyicisinin URL'sine gönderilecektir. Böylece bu denetleyici, hem başlangıçta bir GET tarafından istenen boş formu oluşturmak hem de [Envoyer] düğmesi ile kendisine gönderilecek girilen verileri işlemek için kullanılır.
  • Gönderilen değerler, HTML, [txtNom] (22. satır), [txtAge] (26. satır) ve [action] (37. satır) alanlarına aittir. Bu son parametre, denetleyicinin ne yapması gerektiğini bilmesini sağlayacaktır.
  • Formun ilk görüntülendiği anda, [txtNom, txtAge] giriş alanları sırasıyla [nom] (satır 22) ve [age] (satır 26) değişkenleriyle başlatılır. Bu değişkenler, değerlerini istekten (satır 6-7) alır; bu değerlerin servlet tarafından başlatıldığı bilinmektedir. Dolayısıyla, formun giriş alanlarının başlangıç içeriğini belirleyen servlettir.
  • 33. satır: [reset] türündeki [Rétablir] düğmesi, formu tarayıcının aldığı andaki durumuna geri getirir.
  • 34. satır: [reset] türündeki [Effacer] düğmesinin şu anda herhangi bir işlevi yoktur.

Bundan sonra, hem görünümün adını hem de şablonunu belirtmek istediğimizde bu görünüme [formulaire(nom, age)] görünümü diyeceğiz. Ayrıca, kullanıcı [Envoyer] düğmesine tıkladığında, [txtNom, txtAge] parametrelerinin [/personne1/main] URL'sine gönderildiğini hatırlayalım.

5.5.2. [reponse] görünümü

Bu görünüm, formda girilen değerler geçerli olduğunda bunları görüntüler:

Image

Bu görünüm, JSP ve [reponse.jsp] sayfaları tarafından oluşturulur. Şablonu aşağıdaki öğelerden oluşur:

  • [nom]: "nom" anahtarıyla ilişkilendirilmiş, oturum özniteliklerinde bulunacak bir ad (String)
  • [age]: oturum özniteliklerinde "age" anahtarıyla ilişkilendirilmiş bir yaş (String)

JSP [reponse.jsp] sayfasının kodu şöyledir:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
    // modelden veriler alınır
  String nom=(String)request.getAttribute("nom");
  String age=(String)request.getAttribute("age");
%>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Personne - réponse</h2>
    <hr>
    <table>
        <tr>
          <td>Nom</td>
        <td><%= nom %>
      </tr>
        <tr>
          <td>Age</td>
        <td><%= age %>
      </tr>
    </table>      
  </body>
</html>

  • 6-7. satırlar: JSP sayfası, [request] isteğinden modelindeki [nom, age] öğelerini alarak başlar. Uygulamanın normal çalışması sırasında, bu şablonu oluşturan [ServletPersonne] denetleyicisi olacaktır.
  • Modeldeki [nom, age] öğeleri daha sonra 20. ve 24. satırlarda görüntülenir

Bundan sonra bu görünüme [réponse(nom, age)] görünümü adını veriyoruz.

5.5.3. [erreurs] görünümü

Bu görünüm, formdaki giriş hatalarını bildirir:

Image

Bu görünüm, JSP ve [erreurs.jsp] sayfaları tarafından oluşturulur. Şablonu aşağıdaki öğelerden oluşur:

  • [erreurs]: istek özniteliklerinde "hatalar" anahtarıyla ilişkilendirilmiş bir hata mesajları listesi (ArrayList)

JSP [erreurs.jsp] sayfasının kodu şöyledir:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page import="java.util.ArrayList" %>

<%
// modelden veriler alınır
  ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");  
%>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
    <ul>
        <%
          for(int i=0;i<erreurs.size();i++){
            out.println("<li>" + (String) erreurs.get(i) + "</li>\n");
        }//for
      %>
    </ul>
  </body>
</html>

  • 8. satır: JSP sayfası, [request] isteğinden şablonundaki [erreurs] öğesini alarak başlar. Bu öğe, ArrayList türünde bir nesneyi temsil eder ve bu nesne, String türündeki öğelerden oluşur. Bu öğeler hata mesajlarıdır. Uygulamanın normal çalışması sırasında, bu şablonu oluşturan [ServletPersonne] denetleyicisi olacaktır.
  • 18-22. satırlar: hata mesajlarının listesini görüntüler. Bunun için, sayfanın HTML gövdesine Java kodu yazmak gerekir. HTML kodunu gereksiz yere karmaşıklaştırmamak için bu kodu her zaman en aza indirgemeyi hedeflemeliyiz. Daha sonra, JSP sayfalarındaki Java kod miktarını azaltmaya olanak tanıyan çözümlerin olduğunu göreceğiz.
  • 4. satır: JSP sayfası için gerekli paketlerin içe aktarılma etiketine dikkat edin

Bundan sonra bu görünüme [erreurs(erreurs)] görünümü adını vereceğiz.

5.6. Görünümlerin test edilmesi

Denetleyiciyi yazmadan JSP sayfalarının geçerliliğini test etmek mümkündür. Bunun için iki koşul vardır:

  • kontrolörden geçmeden bu sayfaları doğrudan uygulamadan çağırabilmeliyiz
  • JSP sayfasının, normalde denetleyici tarafından oluşturulacak olan modeli kendi başına başlatması gerekir

Bu testleri gerçekleştirmek için, Eclipse projesindeki [/WebContent/JSP] klasörüne JSP sayfalarının kopyalarını ekliyoruz:

Image

Ardından, JSP klasöründeki sayfalar şu şekilde değiştirilir:

[formulaire.jsp]:


...

<%
  // -- test: sayfa şablonu oluşturuluyor
  request.setAttribute("nom","tintin");
  request.setAttribute("age","30");
%>

<%
    // şablondaki veriler alınır
  String nom=(String)request.getAttribute("nom");
  String age=(String)request.getAttribute("age");
%>
    
<html>
    <head>
...

Sayfa 11-12'nin ihtiyaç duyduğu şablonu oluşturmak için 3-7. satırlar eklenmiştir.

[reponse.jsp]:


...

<%
  // -- test: sayfa şablonu oluşturulur
  request.setAttribute("nom","milou");
  request.setAttribute("age","10");
%>

<%
    // şablondan verileri alıyoruz
  String nom=(String)request.getAttribute("nom");
  String age=(String)request.getAttribute("age");
%>

    
<html>
    <head>
...

3-7. satırlar, 11-12. satırlardaki sayfanın ihtiyaç duyduğu şablonu oluşturmak için eklenmiştir.

[erreurs.jsp] :


...

<%
  // -- test: sayfa şablonu oluşturuluyor
  ArrayList<String> erreurs1=new ArrayList<String>();
  erreurs1.add("erreur1");
  erreurs1.add("erreur2");
  request.setAttribute("erreurs",erreurs1);
%>

<%
// şablondan veriler alınır
  ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");  
%>

    
<html>
    <head>
...

3-9. satırlar, 13. satırdaki sayfanın ihtiyaç duyduğu şablonu oluşturmak için eklenmiştir.

Henüz yapmadıysanız Tomcat'i başlatın ve ardından aşağıdaki URL'leri isteyin:

 

Beklediğimiz görünümleri elde ediyoruz. Artık uygulamanın JSP sayfalarına makul ölçüde güven duyduğumuza göre, [ServletPersonne] denetleyicisini yazmaya geçebiliriz.

5.7. [ServletPersonne] denetleyicisi

Web uygulamamızın kalbini oluşturan denetleyiciyi yazmamız gerekiyor. Denetleyicinin görevi şunlardır:

  • istemciden gelen isteği almak,
  • müşterinin talep ettiği eylemi işlemek,
  • yanıt olarak uygun görünümü göndermek.

[ServletPersonne] denetleyicisi aşağıdaki eylemleri işleyecektir:

No
istek
kaynak
işlem
1
[GET /personne1/main]
kullanıcı tarafından girilen URL
- boş [formulaire] görünümünü gönder
2
[POST /personne1/main]
[txtNom,
txtAge, eylem] gönderildi
düğmeye tıklama
[Envoyer] düğmesine tıklayın
[formulaire]
- [txtNom, txtAge] parametrelerinin değerlerini kontrol edin
- yanlışsa, [erreurs(erreurs)] görünümünü gönderin
- değerler doğruysa, [reponse(nom,age)] görünümünü gönderin

Uygulama, kullanıcı [/personne1/main] URL'sini talep ettiğinde başlar. Uygulamanın [web.xml] dosyasına göre (bkz. paragraf 5.4), bu talep, şimdi açıklayacağımız ServletPersonne türünde bir örnek tarafından işlenir.

5.7.1. Denetleyicinin iskeleti

[ServletPersonne] denetleyicisinin kodu şöyledir:

package istia.st.servlets.personne;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ServletPersonne extends HttpServlet {
...

     // başlatma
    @SuppressWarnings("unchecked")
    public void init() throws ServletException {
...
    }

    @SuppressWarnings("unchecked")
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
...
    }

     // ilk görünümün görüntülenmesi
    void doInit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
...
    }

     // formun doğrulanması
    void doValidationFormulaire(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException{
...
    }

     // gönderme
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
         // kontrol GET'e devrediliyor
        doGet(request, response);
    }
}
  • 20-22. satırlar: Servletin ilk yüklenmesi sırasında yürütülen [init] yöntemi
  • 25-28. satırlar: Uygulamaya GET türünde bir istek yapıldığında web sunucusu tarafından çağrılan [doGet] yöntemi
  • satır 42-46: uygulamaya POST türünde bir istek yapıldığında web sunucusu tarafından çağrılan [doPost] yöntemi. Görüldüğü gibi, bu istek de [doGet] yöntemi tarafından işlenecektir (satır 45).
  • 31-33. satırlar: [doInit] yöntemi, 1 numaralı eylem olan [GET /personne1/main]'i işler
  • 36-39. satırlar: [doValidationFormulaire] yöntemi, [POST /personne1/main] numaralı eylemi, [txtNom, txtAge, action] ile gönderilen parametrelerle işler.

Şimdi denetleyicinin farklı yöntemlerini açıklayacağız

5.7.2. Denetleyicinin başlatılması

Denetleyici sınıfı servlet kapsayıcısı tarafından yüklendiğinde, [init] yöntemi yürütülür. Bu işlem yalnızca bir kez gerçekleşir. Belleğe yüklendikten sonra denetleyici bellekte kalır ve farklı istemcilerin isteklerini işler. Her istemci bir yürütme iş parçacığına konu olur ve böylece denetleyicinin yöntemleri farklı iş parçacıkları tarafından eşzamanlı olarak yürütülür. Bu nedenle, denetleyicinin yöntemleri tarafından değiştirilebilecek alanlara sahip olmaması gerektiğini hatırlatmak isteriz. Alanları salt okunur olmalıdır. Bu alanlar, temel görevi bu olan [init] yöntemi tarafından başlatılır. Bu yöntemin özelliği, tek bir iş parçacığı tarafından yalnızca bir kez yürütülmesidir. Dolayısıyla bu yöntemde denetleyicinin alanlarına eşzamanlı erişim sorunu yaşanmaz. [init] yöntemi, web uygulaması için gerekli olan ve tüm istemci iş parçacıkları tarafından salt okunur olarak paylaşılacak nesneleri başlatmayı amaçlar. Bu paylaşılan nesneler iki yere yerleştirilebilir:

  • denetleyicinin özel alanları
  • uygulamanın yürütme bağlamı (ServletContext)

[ServletPersonne] denetleyicisinin [init] yönteminin kodu şöyledir:

package istia.st.servlets.personne;

...
@SuppressWarnings("serial")
public class ServletPersonne extends HttpServlet {
     // örnek parametreleri
    private String urlErreurs = null;
    private ArrayList erreursInitialisation = new ArrayList<String>();
    private String[] paramètres={"urlFormulaire","urlReponse"};
    private Map params=new HashMap<String,String>();

     // başlatma
    @SuppressWarnings("unchecked")
    public void init() throws ServletException {
         // servletin başlatma parametreleri alınır
        ServletConfig config = getServletConfig();
         // diğer başlatma parametrelerini işliyoruz
        String valeur=null;
        for(int i=0;i<paramètres.length;i++){
             // parametre değeri
            valeur=config.getInitParameter(paramètres[i]);
             // parametre mevcut mu?
            if(valeur==null){
                 // hata kaydedilir
                erreursInitialisation.add("Le paramètre ["+paramètres[i]+"] n'a pas été initialisé");
            }else{
                 // parametrenin değeri kaydedilir
                params.put(paramètres[i],valeur);
            }
             // [erreurs] görünümünün URL'si özel bir işleme tabi tutulur
            urlErreurs = config.getInitParameter("urlErreurs");
            if (urlErreurs == null)
                throw new ServletException(
                        "Le paramètre [urlErreurs] n'a pas été initialisé");
        }
    }
...
}
  • 16. satır: c.a.d adlı web uygulamasının yapılandırması alınır. [web.xml] dosyasının içeriği
  • 19-29. satırlar: 9. satırdaki [paramètres] tablosunda tanımlanan adlara sahip servlet'in başlatma parametreleri alınır
  • 21. satır: parametrenin değeri alınır
  • 25. satır: Parametre yoksa, hata başlangıçta boş olan [erreursInitialisation] hata listesine eklenir (8. satır).
  • 28. satır: Parametre mevcutsa, değeri ile birlikte başlangıçta boş olan [params] sözlüğüne kaydedilir (10. satır).
  • satır 31-35: [urlErreurs] parametresi, olası başlatma hatalarını görüntüleyebilen [erreurs] görünümünün URL'sini belirlediği için mutlaka mevcut olmalıdır. Bu parametre mevcut değilse, [ServletException] çalıştırılarak uygulama durdurulur (satır 33).

5.7.3. [doGet] yöntemi

[doGet] yöntemi, GET ve POST isteklerini servlette işler; çünkü [doPost] yöntemi, [doGet] yöntemine yönlendirir. Kod şöyledir:

package istia.st.servlets.personne;

...
@SuppressWarnings("serial")
public class ServletPersonne extends HttpServlet {
     // örnek parametreleri
    private String urlErreurs = null;
    private ArrayList erreursInitialisation = new ArrayList<String>();
    private String[] paramètres={"urlFormulaire","urlReponse"};
    private Map params=new HashMap<String,String>();

...
    @SuppressWarnings("unchecked")
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

         // servletin başlatılma süreci kontrol edilir
        if (erreursInitialisation.size() != 0) {
             // kontrol, hata sayfasına devredilir
            request.setAttribute("erreurs", erreursInitialisation);
            getServletContext().getRequestDispatcher(urlErreurs).forward(
                    request, response);
             // son
            return;
        }

         // isteğin gönderilme yöntemi alınır
        String méthode=request.getMethod().toLowerCase();
         // yürütülecek eylemi alıyoruz
        String action=request.getParameter("action");
         // eylem?
        if(action==null){
            action="init";
        }
         // eylemin yürütülmesi
        if(méthode.equals("get") && action.equals("init")){
             // uygulamanın başlatılması
            doInit(request,response);
            return;
        }
        if(méthode.equals("post") && action.equals("validationFormulaire")){
             // giriş formunun doğrulanması
            doValidationFormulaire(request,response);
            return;
        }
         // diğer durumlar
        doInit(request,response);
    }

     // gönderme
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
         // kontrol GET'e devredilir
        doGet(request, response);
    }
}
  • 18-25. satırlar: Başlatma hataları listesinin boş olup olmadığı kontrol edilir. Boş değilse, hatayı veya hataları bildirecek olan [erreurs(erreursInitialisation)] görünümünü görüntülemek için işlem yapılır.

Bu kodu anlamak için [erreurs] görünümünün şablonunu hatırlamak gerekir:

<%
// modelden veriler alınır
  ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");  
%>

[erreurs] görünümü, istekte "hatalar" anahtar öğesini bekler. Denetleyici, bu öğeyi 20. satırda oluşturur.

  • 28. satır: İstemcinin isteğini oluşturmak için kullandığı [get] veya [post] yöntemini alırız
  • 30. satır: İsteğin [action] parametresinin değeri alınır. Uygulamamızda yalnızca 2 numaralı [POST /personne1/main] isteğinin [action] parametresine sahip olduğunu hatırlayalım. Bu istekte, bu parametrenin değeri [validationFormulaire]'tir.
  • 31-34. satırlar: [action] parametresi mevcut değilse, ona "init" değeri atanır. Bu durum, 1 numaralı ilk istek olan [GET /personne1/main]'te geçerli olacaktır.
  • satır 36-40: 1 numaralı istek [GET /personne1/main] işlenir.
  • 41-45. satırlar: 2 numaralı istek [POST /personne1/main]'in işlenmesi.
  • 47. satır: Yukarıdaki iki durumdan hiçbirinde değilsek, 1 numaralı durumdaymışız gibi işlem yapılır

5.7.4. [doInit] yöntemi

Bu yöntem, 1 numaralı [GET /personne1/main] isteğini işler. Bu istekte, [formulaire(nom,age)] görünümünü boş olarak göndermelidir. Kod şöyledir:

package istia.st.servlets.personne;
...

@SuppressWarnings("serial")
public class ServletPersonne extends HttpServlet {
     // örnek parametreleri
    private String urlErreurs = null;
    private ArrayList erreursInitialisation = new ArrayList<String>();
    private String[] paramètres={"urlFormulaire","urlReponse"};
    private Map params=new HashMap<String,String>();

...    
     // ilk görünümün görüntülenmesi
    void doInit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
         // boş form gönderiliyor
        request.setAttribute("nom", "");
        request.setAttribute("age", "");
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }
...
}
  • 18-19. satırlar: [formulaire] görünümü görüntülenir. Bu görünümün beklediği şablonu hatırlayalım:

<%
    // modelden veriler alınır
  String nom=(String)request.getAttribute("nom");
  String age=(String)request.getAttribute("age");
%>
  • satır 16-17: [formulaire] görünümünün [nom,age] şablonu boş dizelerle başlatılır.

5.7.5. [doValidationFormulaire] yöntemi

Bu yöntem, gönderilen parametrelerin [action, txtNom, txtAge] olduğu 2 numaralı [POST /personne1/main] isteğini işler. Kod şu şekildedir:

package istia.st.servlets.personne;

...
@SuppressWarnings("serial")
public class ServletPersonne extends HttpServlet {
     // örnek parametreleri
    private String urlErreurs = null;
    private ArrayList erreursInitialisation = new ArrayList<String>();
    private String[] paramètres={"urlFormulaire","urlReponse"};
    private Map params=new HashMap<String,String>();
...
     // formun doğrulanması
    void doValidationFormulaire(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException{
         // parametreler alınır
        String nom = request.getParameter("txtNom");
        String age = request.getParameter("txtAge");
         // parametrelerin doğrulanması
        ArrayList<String> erreursAppel = new ArrayList<String>();
         // ad alanı boş olmamalıdır
        nom = nom.trim();
        if (nom.equals(""))
            erreursAppel.add("Le champ [nom] n'a pas été rempli");
         // yaş, 0'dan büyük bir tamsayı olmalı
        if (!age.matches("^\\s*\\d+\\s*$"))
            erreursAppel.add("Le champ [age] est erroné");
         // parametrelerde hata mı var?
        if (erreursAppel.size() != 0) {
             // hata sayfası gönderiliyor
            request.setAttribute("erreurs", erreursAppel);
            getServletContext().getRequestDispatcher(urlErreurs).forward(request, response);
            return;
        }
         // parametreler doğru - yanıt sayfası gönderiliyor
        request.setAttribute("nom", nom);
        request.setAttribute("age", age);
        getServletContext().getRequestDispatcher((String)params.get("urlReponse")).forward(request,
                response);
        return;
    }
...
}
  • 16-17. satırlar: İstemcinin isteğinden "txtNom" ve "txtAge" parametrelerinin değerleri alınır.
  • 19-26. satırlar: Bu iki parametrenin geçerliliği kontrol edilir
  • 28-33. satırlar: Parametrelardan biri hatalıysa, [erreurs(erreursAppel)] görünümü görüntülenir. Bu görünümün şablonunu hatırlayalım:

<%
// şablondan veriler alınıyor
  ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");  
%>
  • 35-38. satırlar: Alınan "txtNom" ve "txtAge" parametrelerinin her ikisinin de geçerli değerleri varsa, [reponse(nom,age)] görünümü görüntülenir. [reponse] görünümünün şablonunu hatırlamak gerekir:

<%
    // modelden veriler alınıyor
  String nom=(String)request.getAttribute("nom");
  String age=(String)request.getAttribute("age");
%>

5.8. Tests

3.3. paragrafında açıklanan prosedürü izleyerek [mvc-personne-01] projesini Tomcat uygulamalarına ekleyelim:

Image

Tomcat'i başlatın. Bu işlem tamamlandıktan sonra, 5.1. paragrafında örnek olarak gösterilen testlere devam edilebilir. Yeni testler de eklenebilir. Örneğin, web.xml'teki urlXXX yapılandırma parametrelerinden birini kaldırıp sonucu görebiliriz. Aşağıdaki örnekte olduğu gibi, [web.xml]'te parametrelerden biri yorum satırına alınmıştır:


        <!-- 
            <init-param>
              <param-name>urlFormulaire</param-name>
              <param-value>
                /WEB-INF/vues/formulaire.jsp
              </param-value>
            </init-param>
        -->

Tomcat'i başlatıp yeniden başlatıyoruz ve [http://localhost:8080/personne1/main] URL'sini sorguluyoruz. Aşağıdaki yanıtı alıyoruz:

Image