Bloki deklaracyjne w JSP

21 sierpnia 2009 | 0 komentarze

Bloki deklaracyjne nie należą do często używanych elementów JSP. Wynika to po pierwsze z wąskiego zakresu zastosowania, po drugie ze znanych zaleceń i tendencji używania tagów/EL a unikania Scriptlets (czytelny kod, łatwe utrzymanie, mniej błędów, itd.). Mimo tego, deweloper JSP powinien mieć przynajmniej świadomość istnienia tego mechanizmu. ;-)

Kod JSP każdej strony/tagu użytkownika jest w pierwszej fazie tłumaczony na kod źródłowy (servlet) a w następnej kompilowany do bytecode. Deklaracje pozwalają na tworzenie metod i pól będących członkami klasy wynikowej strony JSP (class members). W fazie tłumaczenia treść tagów JSP i Scriptlets zostaną wrzucone do jednej metody. Ale nie deklaracje.

Podstawowym ograniczeniem bloków deklaracyjnych jest dostępność pól i metod tylko w Scriptlets - nie są widoczne w Expression Language. EL operuje przecież na elementach zawartych w kontekście.

Przykład deklaracji JSP - tabliczka mnożenia w tabeli HTML. Mnożenie wykonywane w metodzie multiply(), zdefiniowanej w bloku deklaracyjnym. Metodę można wywoływać wielokrotnie z dowolnego miejsca na stronie.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<body>
  <h1>Test</h1>
  <%!
    int multiply(int a, int b){
    return a*b;
  }
  %>
  <p>
    <table>
    <% for(int x=1; x<=10; x++){%>
    <tr>
      <% for(int y=1; y<=10; y++){%>
        <td><%= multiply(x, y) %></td>
      <% } %>
    </tr>
    <% } %>
    </table>
  </p>
</body>

W taki sam sposób można deklarować pola. Trzeba tylko pamiętać, że przechowywanie w ten sposób stanu w JSP nie jest bezpieczne - dostęp do pól ma wiele wątków jednocześnie i w zasadzie nie ma gwarancji operowania na konkretnej instancji klasy. Z kolei użycie słowa kluczowego synchronized na pewno zabije wydajność.

Istnieją dwie metody specjalne, uwzględnione w cyklu życia strony JSP: jspInit wywoływana podczas inicjalizacji, jspDestroy przy niszczeniu servlet'a. Deklaracje oferują możliwość przeciążenia obu metod.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%! public void jspInit() { System.out.println("* witaj!"); } %>
<%! public void jspDestroy() { System.out.println("* bye bye!"); } %>

W blokach deklaracyjnych działają słowa kluczowe i kwalifikatory dostępu, pola i metody mogą być oznaczone jako static, final, synchronized. Deklaracje pozwalają na tworzenie bloków inicjacyjnych, w tym statycznych. Więcej - choć specyfikacja o tym milczy, dopuszczone jest deklarowanie klas zagnieżdżonych, np.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<body>
  <h1>Test 2</h1>
  <%!
  public static class InnerClass {
    public static void testIt(String str){
      System.out.println("testIt:"+str);
    }
  }
  %>
  <p>
  <%
    InnerClass.testIt("ok!");
  %>
  </p>
</body>

Na koniec ciekawostka, a raczej wpis z działu Tips & Tricks. ;-) Na stronie JSP, mimo że Eclipse informuje o błędzie, można napisać działający konstruktor. :-)


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%! public myjsp_jsp() { System.out.println("* Dzień Dobry!"); } %>

Linki:
The Java EE 5 Tutorial, JSP Declarations
JavaServer Pages (JSP) v2.0 Syntax Reference

0 komentarze: