Skip to content

7. MVC [personne] web uygulaması – sürüm 3


[ref1]'te önerilen okumalar: 9. bölüm


7.1. Introduction

Tarayıcıya gönderilen HTML sayfalarına JavaScript kodu eklemeyi öneriyoruz. Tarayıcı, görüntülediği sayfaya gömülü olan JavaScript kodunu çalıştırır. Bu teknoloji, web sunucusunun HTML belgesini oluşturmak için kullandığı teknolojiden bağımsızdır (Java/servletler/JSP, ASP.NET, ASP, PHP, Perl, Python, ...).

[formulaire.jsp]

Bu sayfadan elde edilen görünüm şu şekilde olacaktır:

Image

Metni çerçeveli düğmeler, HTML sayfasında yer alan JavaScript kodunu kullanır:

Etiket
Tür HTML
İşlev
Submit
<submit>
önceki sürümlerdeki [Envoyer] düğmesinin işlevini yerine getirir: girilen değerleri denetleyiciye gönderir
[Envoyer]
<button>
yeni düğme – girilen verilerin geçerliliğini denetleyiciye göndermeden önce yerel olarak kontrol eder
Rétablir
<reset>
Formu, tarayıcı tarafından ilk alındığı duruma geri yükler
[Effacer]
<button>
iki giriş alanının içeriğini siler

Aşağıda, [Envoyer] ve [Effacer] düğmelerinin kullanımına ilişkin bir örnek verilmiştir:

Ayrıca, [erreurs] ve [réponse] görünümlerinin [Retour au formulaire] bağlantısını yönetmek için JavaScript kodu kullanacağız. [réponse] görünümünü örnek olarak alalım:

1

Aradaki fark, [1]'te görüntülenen URL'dedir. Önceki sürümde bu URL şöyleydi:

[http://localhost:8080/personne2/main?action=retourFormulaire]

Burada, eylem artık URL'nin bir parçası değildir çünkü GET yerine POST ile gönderilecektir. Bu değişiklik, talep edilen eylem ne olursa olsun tarayıcıda görüntülenen tek URL'nin [http://localhost:8080/personne3/main] olması sonucunu doğuracaktır.

7.2. Eclipse Projesi

[/personne3] web uygulamasının Eclipse projesi [mvc-personne-03]'i oluşturmak için, sayfa 78'deki 6.2 numaralı paragrafta açıklanan prosedürü izleyerek [mvc-personne-02] projesini kopyalayacağız.

7.3. [personne3] web uygulamasının yapılandırılması

/personne3 uygulamasının web.xml dosyası şu şekildedir:


<?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-03</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>
        <init-param>
            <param-name>lienRetourFormulaire</param-name>
            <param-value>
                Retour au formulaire
            </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 dosya, birkaç ayrıntı dışında önceki sürümdekiyle aynıdır:

  • 6. satır: Web uygulamasının görüntüleme adı [mvc-personne-03] olarak değiştirilmiştir

[urlControleur] parametresi kaldırılmıştır. Önceki sürümde bu parametre, [formulaire] görünümünün POST hedefini belirlemek için kullanılıyordu. Bu yeni sürümde hedef, boş dize olan c.a.d olacaktır. Tarayıcı tarafından görüntülenen URL. Bunun her zaman [http://localhost:8080/personne3/main] olacağını açıklamıştık; bu, [formulaire] görünümündeki POST için ihtiyacımız olan URL’dir.

[index.jsp] ana sayfası değişir:


<%@ 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("/personne3/main");
%>
  • 5. satır: [index.jsp] sayfası, istemciyi [/personne3] uygulamasının [ServletPersonne] denetleyicisinin URL’sine yönlendirir.

7.4. Görünüm kodları

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

Bu görünüm şu şekilde değiştirilmiştir:

Image

Aşağıdaki JSP ve [formulaire.jsp] sayfaları tarafından oluşturulur:


<%@ 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) session.getAttribute("nom");
            String age = (String) session.getAttribute("age");
%>


<html>
  <head>
    <title>Personne - formulaire</title>
    <script language="javascript">
        // -------------------------------
        function effacer(){
          // giriş alanları siliniyor
          with(document.frmPersonne){
            txtNom.value="";
            txtAge.value="";
          }//ile
        }//silme
        // -------------------------------      
        function envoyer(){
          // göndermeden önce parametrelerin doğrulanması
          with(document.frmPersonne){
            // ad alanı boş olmamalıdır
            champs=/^\s*$/.exec(txtNom.value);
            if(champs!=null){
              // ad alanı boş
              alert("Vous devez indiquer un nom");
              txtNom.value="";
              txtNom.focus();
              // görsel arayüze geri dön
              return;
            }//if
             // yaş pozitif bir tamsayı olmalıdır
            champs=/^\s*\d+\s*$/.exec(txtAge.value);
            if(champs==null){
              // yaş yanlış
              alert("Age incorrect");
              txtAge.focus();
              // görsel arayüze geri dön
              return;
            }//if
             // parametreler doğru - sunucuya gönderiliyor
            submit();
          }//with
        }//gönder
      </script>
  </head>
  <body>
    <center>
      <h2>Personne - formulaire</h2>
      <hr>
      <form name="frmPersonne" 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="Submit"></td>
            <td><input type="button" value="[Envoyer]" onclick="envoyer()"></td>
            <td><input type="reset" value="Rétablir"></td>
            <td><input type="button" value="[Effacer]" onclick="effacer()"></td>
          </tr>
        </table>
        <input type="hidden" name="action" value="validationFormulaire">
      </form>
    </center>
  </body>
</html>


Yenilikler:

  • 56. satır: Formun adı [frmPersonne]'tir. Bu ad, JavaScript kodunda kullanılacaktır. [action] özniteliğinin bulunmadığına dikkat edilmelidir; bu durum, [frmPersonne] formunun tarayıcıda görüntülenen URL'ye gönderilmesine neden olur.
  • 70. satır: [Submit] düğmesi, önceki sürümlerdeki [Envoyer] düğmesinin işlevini yerine getirir
  • 71. satır: [Button] türündeki [Envoyer] düğmesine tıklandığında, 24. satırda tanımlanan [envoyer] JavaScript işlevi çalıştırılır
  • 72. satır: [Rétablir] düğmesinin işlevi değişmemiştir
  • 73. satır: [Button] türündeki [Effacer] düğmesine tıklandığında, 16. satırda tanımlanan [effacer] JavaScript işlevi çalıştırılır

Javascript kodunu yorumlamadan önce, birkaç notu hatırlatalım:

Javascript, görüntülenen sayfayı ve içeriğini, kökü [document] nesnesi olan bir nesne ağacı olarak yönetir. Bu belgede bir veya daha fazla form bulunabilir. [document.frmPersonne], 56. satırda tanımlanan [frmPersonne] adlı formu belirtir. Bu form da nesneler içerir. Giriş alanları da bunlara dahildir. Dolayısıyla [document.frmPersonne.txtNom], 60. satırda tanımlanan HTML giriş alanının resim nesnesini belirtir. [txtNom] nesnesinin çeşitli özellikleri vardır; bunlardan [value] özelliği, giriş alanının içeriğini belirtir. Dolayısıyla [document.frmPersonne.txtNom.value], [txtNom] giriş alanının içeriğini belirtir.

  • 16-22. satırlar: [effacer] adlı JavaScript işlevi, [txtNom, txtAge] giriş alanlarına boş bir dize yerleştirir.
  • 24-49. satırlar: [envoyer] adlı JavaScript işlevi, [txtNom, txtAge] giriş alanlarındaki değerlerin geçerliliğini, verileri göndermeden önce kontrol eder. Bunun için düzenli ifadeler kullanır.
  • 28. satır: [txtNom] giriş alanının değerinin, 0 veya daha fazla boşluk anlamına gelen /s* şablonuna uyup uymadığını kontrol eder. Cevap evet ise, bu durum kullanıcının bir ad belirtmediği anlamına gelir. Desenle eşleşme varsa, champs değişkeni, null işaretçisinden farklı bir değere sahip olur; aksi takdirde null değerini alır.
  • 29. satır: şablonla eşleşme varsa
  • 30. satır: kullanıcıya bir mesaj görüntülenir
  • satır 32: [txtNom] alanına boş dize yazılır (bir dizi boşluk olabilir)
  • satır 33: yanıp sönen imleci [txtNom] alanına getirilir
  • satır 34: işlev sonlandırılır. Böylece, girilen değerler sunucusuna POST gönderilmez.
  • 38-45. satırlar: [txtAge] alanı için de benzer bir işlem yapılır
  • 47. satır: Buraya gelindiğinde, girilen değerler doğrudur. Ardından [frmPersonne] formunu web sunucusuna göndeririz. Bu noktada, sanki [Submit] etiketli düğmeye basılmış gibi işlem devam eder.

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

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

Önceki sürüme kıyasla, yenilik yalnızca [réponse] görünümündeki [Retour au formulaire] bağlantısı kullanıldığında görünür:

Fark, [1]'te görüntülenen URL'de yatmaktadır. Önceki sürümde bu URL şöyleydi:

[http://localhost:8080/personne2/main?action=retourFormulaire]

Burada, eylem artık URL'nin bir parçası değildir çünkü GET yerine POST ile gönderilecektir. Yeni sayfa JSP [reponse.jsp], lqqqaaaaaaaaaqqAAAaaa'tir

şöyle:


<%@ 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");
  String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>


<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>      
    <br>
    <form name="frmPersonne" method="post">
      <input type="hidden" name="action" value="retourFormulaire">
    </form>
    <a href="javascript:document.frmPersonne.submit();">
      <%= lienRetourFormulaire %>
    </a>
  </body>
</html>

Yenilikler:

  • 35-37. satırlar: [Retour au formulaire] bağlantısı JavaScript içerir. Bu bağlantıya tıklandığında, [href] özniteliğindeki JavaScript kodu çalıştırılır. [formulaire.jsp] incelemesinde gördüğümüz gibi, bu kodun [frmPersonne] formundaki <input>, <select> vb. türündeki alanların değerlerini gönderdiğini biliyoruz.
  • 32-34. satırlar: [frmPersonne] formunu tanımlar. Bu formda yalnızca <input type="hidden" ...> türünde bir alan, yani gizli bir alan bulunmaktadır. Bu [action] alanı, yürütülmesi gereken eylemin adını (burada [retourFormulaire]) denetleyiciye iletmek için kullanılır.

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

Bu görünüm, formdaki giriş hatalarını bildirir. Yapılan değişiklik, [réponse] görünümüyle aynıdır:

Aradaki fark, [1]'te görüntülenen URL'dedir. Önceki sürümde bu URL şöyleydi:

[http://localhost:8080/personne2/main?action=retourFormulaire]

Burada, eylem artık URL'nin bir parçası değildir çünkü GET yerine POST ile gönderilecektir. Yeni sayfa JSP [reponse.jsp] şö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"); 
  String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>


<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>
    <br>
    <form name="frmPersonne" method="post">
      <input type="hidden" name="action" value="retourFormulaire">
    </form>
    <a href="javascript:document.frmPersonne.submit();">
      <%= lienRetourFormulaire %>
    </a>
  </body>
</html>

Yenilikler:

  • 30-32. satırlar: Bağlantıya tıklama ile ilgili yeni yönetim. [réponse.jsp] incelemesinde bu konuyla ilgili verilen açıklamalar burada da geçerlidir.

7.5. Görünüm testleri

Önceki görünümlerin testlerini gerçekleştirmek için, Eclipse projesindeki /WebContent/JSP klasörüne JSP sayfalarını kopyalıyoruz:

Image

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

[formulaire.jsp]:


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

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

9-10. satırlarda sayfanın ihtiyaç duyduğu şablonu oluşturmak için 4-5. satırlar eklenmiştir.

[reponse.jsp]:


...
<%
  // -- test: sayfa şablonu oluşturuluyor
  request.setAttribute("nom","milou");
  request.setAttribute("age","10");
  request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>

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

4-6. satırlar, 11-13. 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);
  request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>

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

4-8. satırlar, 13-14. satırlardaki 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üntüleri elde ediyoruz.

7.6. [ServletPersonne] denetleyicisi

[/personne3] web uygulamasının [ServletPersonne] denetleyicisi aşağıdaki eylemleri işleyecektir:

No
istek
kaynak
işlem
1
[GET /personne3/main]
kullanıcı tarafından girilen URL
- boş [formulaire] görünümünü gönder
2
[POST /personne3/main]
parametrelerle [txtNom,
txtAge, action=validationFormulaire]
gönderildi
düğmeye tıklayarak
[Envoyer] düğmesine tıklayarak
[formulaire]
- [txtNom, txtAge] parametrelerinin değerlerini kontrol edin
- değerler 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
3
[POST /personne3/main]
parametrelerle birlikte
[action=retourFormulaire]
tıklayın
[Forma geri dön] bağlantısına tıklayın
formuna geri dön] bağlantısına tıklayın
[réponse] ve [erreurs].
- En son girilen değerlerle önceden doldurulmuş [formulaire] görünümünü gönderin

Böylece, eski [GET /personne3/main?action=retourFormulaire] eyleminin yerine, [action=retourFormulaire] parametresiyle birlikte [POST /personne3/main] adlı yeni bir eylem işlenmelidir.

7.6.1. Denetleyicinin iskeleti

[ServletPersonne] denetleyicisinin iskeleti, önceki sürümünkiyle aynıdır.

package istia.st.servlets.personne;

...
import javax.servlet.http.HttpSession;

@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","lienRetourFormulaire"};
    private Map params=new HashMap<String,String>();
    ...

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

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

     // boş formun görüntülenmesi
    void doInit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        ...
    }

     // önceden doldurulmuş formun görüntülenmesi
    void doRetourFormulaire(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        ...
    }

     // formun doğrulanması
    void doValidationFormulaire(HttpServletRequest request,
    ...
    }

     // gönderme
    public void doPost(HttpServletRequest request, HttpServletResponse response)
    ...
    }
}

Yenilikler:

  • 11. satırda, [paramètres] tablosu artık [web.xml] dosyasından kaldırılan [urlControleur] parametresini içermemektedir.

[init, doValidationFormulaire] yöntemleri eskisi gibi kalmıştır. [doGet, doInit, doRetourFormulaire] yöntemlerinde ise küçük değişiklikler yapılmıştır.

7.6.2. [doGet] yöntemi

[doGet] yöntemi, [POST /personne3/main] eylemini, [action=retourFormulaire] gönderilen parametresiyle işlemelidir:

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

...
        if(méthode.equals("post") && action.equals("retourFormulaire")){
             // giriş formuna geri dönüş
            doRetourFormulaire(request,response);
            return;
        }
         // diğer durumlar
        doInit(request,response);
    }
  • 6-9. satırlar: [POST /personne3/main] eyleminin, gönderilen [action=retourFormulaire] parametresiyle işlenmesi

7.6.3. [doInit] yöntemi

Bu yöntem, 1 numaralı istek olan [GET /personne3/main]'i işler. Kodu şöyledir:

             // boş formun görüntülenmesi
    void doInit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
         // kullanıcının oturumu alınır
        HttpSession session = request.getSession(true);        
         // boş formun gönderilmesi
        session.setAttribute("nom", "");
        session.setAttribute("age", "");
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }

Yenilik, 8. satırda görüntülenen [formulaire] görünümünün şablonunda artık [action] öğesinin bulunmamasıdır.

7.6.4. [doRetourFormulaire] yöntemi

Bu yöntem, gönderilen öğeler arasında [action=retourFormulaire] bulunan 1 numaralı [POST /personne3/main] isteğini işler. Kod şu şekildedir:

     // önceden doldurulmuş formun görüntülenmesi
    void doRetourFormulaire(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
         // kullanıcının oturumu alınır
        HttpSession session = request.getSession(true);        
         // oturumda isim var mı?
        String nom = (String) session.getAttribute("nom");
        if (nom == null)
            session.setAttribute("nom", "");
         // Oturumda yaş var mı?
        String age = (String) session.getAttribute("age");
        if (age == null)
            session.setAttribute("age", "");
         // form görüntüleniyor
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }

Yenilik, 14. satırda görüntülenen [formulaire] görünümünün şablonunda artık [action] öğesinin bulunmamasıdır.

7.7. Tests

Eclipse projesini [personne-mvc-03] entegre ettikten sonra Tomcat'i başlatın veya yeniden başlatın. [http://localhost:8080/personne3] URL'sini çağırın ve ardından 7.1. paragrafında örnek olarak gösterilen testleri tekrarlayın.