Anna Zatwarnicka

Bazy danych
IV rok informatyki studia dzienne




JSP (Java Server Pages) - wprowadzenie

Wprowadzenie ma formę opowiadania. Zrezygnowałam z wielu formalnych określeń, stosuję potoczne wyrażenia i mam nadzieję, że z niej Państwo skorzystacie.

I.    Co to jest JSP.
II.   Przykładowy skrypt JSP łączący się z bazą danych.
II a. Dołączane pakiety.
II b. Zapytania do bazy.
III. JSP i HTML
IV. Uwagi końcowe

Materiały pomocnicze

Odnośnik do pliku z przykładem:
Książki, które są w moim posiadaniu:


I. Co to jest JSP.

Opis
JSP - Java  Server Pages to rozwiązanie SUN'a do tworzenia dynamicznych stron webowych.

Jest niejako rozszeżeniem serwletów Javy. Aplikacje JSP mają postać stron w kodzie HTML, rozszeżonych o klasy i metody Javy.
Znaczy to, że strona webowa, jej zawartość, jest tworzona za pomocą mechanizmu JSP, przy użyciu odpowiednich poleceń. W wielkim skrócie: "piszemy" stronę webową
(znaczniki HTML i całą resztę) prawie tak, jakbyśmy mieli wypisywać treść strony na ekran w aplikacji konsolowej Javy.
JSP umożliwia również "mieszanie" kodu: JSP oraz "czystego" HTML'a. Podobnie jak w PHP. Zainteresowanych odsyłam do literatury (podana na początku opracowania i nie tylko).

Tak sytuacja wygląda z punku widzenia piszącego kod, natomiast tak naprawdę jest konwertowana do tzw. serwletu JSP za pomocą statycznego kodu HTML, "wpisanego" do obiektu serwletu HttpResponse. Strony JSP mają taką samą funkcjonalność, jak serwlety - mogą robić to samo, ale inaczej się to pisze. Strona JSP jest "tłumaczona" na serwlet za pierwszym razem, kiedy jest pobierana z serwera. Następne żądania do tej strony używają już serwletu. Ten fakt, że translacja nie jest tłumaczona przy okazji każdego żądania znacznie przyspiesza wykonywanie stron JSP (podobno..., ale i tak JSP jest uznawane za dość wolne).

Struktura konfiguracyjna Tomcat'a do JSP jest opisana w siecie i np. w książce B.Lakshman "Oracle i..." str. 418.

JSP
Strony JSP składają się z różnych elementów, które muszą być zgodne ze specyfikacją JSP1.1 opisaną przez firmę Sun.
Dynamiczna część kodu (czyli ta JSP) ujęta jest w specjane znaczniki. Jest ich kilka, a nie jeden - tak jak było w PHP.

Znaczniki JSP
By zamieścić tzw. dyrektywę (informacje dla JSP dotyczące całej strony, używana do tłumaczenia lub wykonywania całej strony JSP, np. takiej dołączonej, może to być page, include), należy umieścić ją za pomocą znaczników:
<%@ ...... %>

Deklaracje (deklarujące i ew. tworzące obiekty) określane są przez znaczniki:
<%! .... %>
Uwaga! tylko zmienne składowe! Nie zmienne metod! Deklaracja wykonywana jest tylko raz!

Wyrażenia - czyli takie małe (lub większe) fragmenty kodu Javy, które będą obliczane a następnie konwertowane do łańcucha znaków i wyświetlane w części HTML-owej otoczone są znacznikami, wykonywane za każdym pobraniem strony! Muszą być ujęte w znacznik:
<%= ....... %>

Skryplety - są fragmentami kodu Javy, połączonego z kodem HTML, wykonywane zawsze wtedy, gdy jest żądanie o tę stronę (za każdym razem!). To ten "dynamiczny kawałek kodu". To Państwa najbardziej dotyczy. Odpowiedni znacznik to:
<% ..... %>

Komentarze - ich używanie może okazać się szczególnie opłacalne przy zaliczeniu projektu! Proszę pisać komentarze do kodu i ujmowaz je w znaczniki:
<%-- ..... %>

Każda linijka kodu JSP kończy się średnikiem!
Średnik ma być wewnątrz znacznika!

II. Przykładowy skrypt JSP łączący się z bazą danych.

II a. Oto część kodu, która dołącza odpowiednie pakiety (w nich są odpowiednie klasy wykorzystywane w skrypcie JSP).

<%@ page import="java.sql.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.lang.*" %>

Poniżej znajduje się rozpisany na części fragment odpowiedzialny za połączenie z ba
zą danych.
Deklarujemy obiekt klasy Connection, który będzie odpowiedzialny za połączenie z bazą:
Connection conn = null;

Deklaracja sterownika do bazy danych oracle'a:
Class.forName("oracle.jdbc.driver.OracleDriver");

Nawiązanie połączenia:
conn = DriverManager.getConnection("jdbc:oracle:thin:@10.0.4.4:1521:ora1","klient_oracle","haslo_oracle");

gdzie podany jest: ......... a po nim: adres serwera, numer portu oraz instancja bazy danych, kolejny prarametr to: nazwa użytkownika (Państwa klienta Oracle'a), ostatni parametr to hasło (hasło do Państwa klienta Oracle'a). Używamy thin, ponieważ obsługuje przypadek, gdzie serwer Oracle znajduje się na innej maszynie (fizycznie na innym komputerze) niż serwer webowy, do kotrego będą trafiały żądania użytkowników (klientów).

Bardzo istotne jest polecenie utworzenia obiektu klasy Statement, w którym przechowywać będziemy wyrażenia, wykonywane następnie na serwerze bazodanowym. Obiekt ten tworzymy niejako "na połączeniu".
Statement stmt = conn.createStatement();

Kolejny obiekt klasy ResultSet słuzy do przechowywania informacji "zwróconej" przez serwer, czyli tego, co zrobił serwer Oracle'a w wyniku wykonania wyrażenia. Przykładowo: wyrażenie to prosty select, wynik działania tego wyrażenia to pewien fragment tabeli.
ResultSet rs;

Wszystkie powyższe razem:
<%
    Connection conn = null;
    Class.forName("oracle.jdbc.driver.OracleDriver");
    conn = DriverManager.getConnection("jdbc:oracle:thin:@10.0.4.4:1521:ora1","vd16347","DD832");
    Statement stmt = conn.createStatement();
    ResultSet rs;
%>

Ten fragment NA PEWNO będzie Państwu potrzebny.

II b. Zapytania do bazy.
Co dalej? Trzeba spreparować zapytanie do bazy, np. w postaci:
rs = stmt.executeQuery("select * from osoba");

Mamy zapytanie (stmt - obiekt klasy Statement utworzony wcześniej) i na nim wykonujemy metodę executeQuery. Treść SQL-owego zapytania jest parametrem, jest to zwyczajny łańcuch znaków. NIE JEST ZAKOŃCZONY ŚREDNIKIEM!!!! Równie dobrze można zadeklarować zmienną typu string, i potem jako parametr metody executeQuery użyć właśnie tej zmiennej.
Realizowanym zapytaniem może być dowolne zapytanie SQL-owe:
To, co zwróci zrealizowane zapytanie znajduje się w obiekcie rs typu ResultSet. Trzeba to jakoś wydobyć.
Jeżeli realizowanym zapytaniem było np. zapytanie select, wynik tego zapytania najłatwiej przedstawić w postacie tabelki, lub takiego "wypełnionego danymi" formularza. Tutaj zajmiemy się tabelką.

Początek tabelki tworzymy np. w kodzie HTML. Tutaj mamy jeszcze nagłowki poszczególnych kolumn.
<table border="0" width="100%" cellpadding="0" cellspacing="0">
<tr>
    <td>Imie</td>
    <td>Nazwisko</td>
    <td>E-mail</td>
    <td>Telefon</td>
</tr>


Teraz przechodzimy do kodu JSP i realizujemy zapytanie SQL. Potrzebne fragmenty kodu HTML będą tworzone dynamicznie przez JSP.
Wynik zapytania przechowywany jest w rs.
rs = stmt.executeQuery("select * from osoba");

Można powiedziec, że wynikiem działania select jest tabelka, gdzie wierszami są kolejne rekordy (u nas są to przechowywane w tabeli dane dotyczące jednej osoby), kolumnami są zaś pola tabeli, np. nazwisko, imię.
Obiekt rs ma na szczęscie kilka przydatnych metod, jedna z nich to next(), która pobiera kolejne rekordy, po pobraniu rekordu przechodzi do nastepnego rekordu. Aby wydobyć wszystkie rekordy trzeba użyć pętli. Dane wydobyć można za pomocą kolejnej przydatnej metody getString(), jako parametr metoda ta potrzebuje nazwy pola. Oto przykładowa linijka kodu:
out.println("<td>"+rs.getString("imie")+"</td>");

Omawiany powyżej fragment kodu w całości:
<table border="0" width="100%" cellpadding="0" cellspacing="0">
<tr>
    <td>Imie</td>
    <td>Nazwisko</td>
    <td>E-mail</td>
    <td>Telefon</td>
</tr>
<%
    rs = stmt.executeQuery("select * from osoba");
    while (rs.next())
    {
        out.println("<tr>");
        out.println("<td>"+rs.getString("imie")+"</td>");
        out.println("<td>"+rs.getString("nazwisko")+"</td>");
        out.println("<td>"+rs.getString("email")+"</td>");
        out.println("<td>"+rs.getString("telefon")+"</td>");
        out.println("</tr>");
    }
    rs.close();
    stmt.close();
    conn.close();
%>
</table>


III. JSP i HTML
Te fragmenty kodu należy "poskładać" i uzupełnić kodem HTML-owym w wersji wybranej przez Państwa: HTML i JSP "na przekładkę" lub kod HTML-owy dynamicznie tworzony przez JSP. Poniżej znajduje się odnośnik do pełnej wersji pliku z opracowaniem (do tego samego, co powyżej):
IV. Uwagi końcowe:

Można w ramach jednego skryptu JSP utworzyć kilka połączeń, np. do kilku baz danych, na każdym połączeniu może być realizowanych kilka wyrażeń (kilka obiektów typu Connection, i kilka obiektów typu Statement do jednego połącenia Connection).

Przypominam, że pliki na Linux'ie mają pewne atrybuty, np. wykonania. I że nie Państwo będziecie je wykonywać, tylko aplikacja!
Oto podpowiedź:

-rwxr-xr-x  1 uzytkownik grupa      1564 Nov  2 21:31 przyklad1.jsp*

Kilka przydatnych wyjaśnień co do przykładu JSP:

Jak zapewne Państwo zauważyliście, zapytanie wysyłane do serwera bazodanowego jest postaci "select * from osoby" - nie ma tam średnika!

Wynikiem działania tego polecenia jest cała tabela: wszystkie pola (kolumny) i rekordy, u mnie jest 5 (słownie: pięć) kolumn. I to wszystko dostajemy jako odpowiedź na polecenie "select...". W przykładowym skrypcie JSP zawartość tabeli wyświetlana jest dla użytkownika w tabeli, która ma nagłówek (to pierwszy wiersz tabeli) składający się z czterech kolumn (imie, nazwisko, email i telefon). To jest akurat najmniej ważne, bo to co napisane w czystym HTML-u można traktować jako "narysowane". Ale odrobinkę niżej w skrypcie jest fragment kodu JSP, który pobiera kolejne linijki (wiersze) odpowiedzi na zapytanie - czyli kolejne rekordy i wyswietla w tabeli. Wyświetlać mamy takie kolumny, jak w nagłówku, czyli: imie, nazwisko, email i telefon. I teraz pytanie: co się wyświetla? Odpowiedź: wszystkie pola z bazy, nie tylko te, które każemy. Dlaczego? Ano przecież "kazaliśmy" przesłać do bazy danych zapytanie o całą tabelę. Proszę to zapamiętać! I żądać od bazy i następnie wyświetlać takie informacje, które naprawdę chcecie uzyskać!. Przypominam, że select można używać z klauzulą where, order by, group by, można wypisywać nazwy kolumn "imiennie" itp. - patrz: poprzedni semestr zajęć z baz danych.

Jeszcze jedna informacja, co do wypisywania danych pobranych z tabeli. W linii kodu gdzie jest pobieranie zawartości kolumny, przykładowo:
.....rs.getString("IMIE")....
nazwy kolumn muszą być pisane wielkimi literami! Nasz Oracle, gdy poprosicie go o predstawienie opisu tabeli, wyświetli nazwy kolumn dużymi literami.

Być może dociekliwi zauważyli, że nazwa jednej kolumny brzmi: "TELEFOFON". Czemu ma to służyć? Przecież powinno być telefon... Otórz, jeśli popełnicie Państwo
chociażby błąd-literówkę w skrypcie JSP (odwołujecie się do pola TELEFON, a w bazie macie TELEFOFON) - raczej nie będzie efektów pracy Państwa skryptu... Podobnie rzecz ma się ze średnikami na końcu każdej linijki kodu JSP, znacznikami HTML i JSP: te wszystkie < i > oraz <% i %> muszą być wszystkie potrzebne, ale również kolejność znaczników: żeby nie zamykać ich "na krzyż".


opracowała: AZatwarnicka