JSP - Kolos
Transkrypt
JSP - Kolos
Marcin Paszkowski
Przegląd technologii JSP
Czego potrzebujemy?
Do obsługi serwletów oraz JSP – używamy kontenera. Czym on jest? Zapewnia on prosty
mechanizm komunikacji pomiędzy serwletami a serwerem www. Zadania które
wykonuje za nas kontener to m.in.:
1. buduje gniazda serwera
2. nasłuchuje komunikacje na odpowiednim porcie
3. zapewnia interfejs API pomiędzy serwerem www a kodem naszej aplikacji
internetowej
4. zapewnia on wczytywanie odpowiednich klas, ich inicjalizacje, wywołanie
odpowiednich metod
5. obsługuje wielowątkowość (wciąż jednak programista musi zadbać o ich
bezpieczeństwo, Np. ich synchronizacja)
6. wymusza na nas stosowanie deskryptora rozmieszczeń - w pliku XML – w
których konfigurujemy mechanizmy zabezpieczeń – bez ingerencji w kodzie Javy.
7. Uruchamia strony JSP.
Tomcat – to przykład takiego kontenera. Kiedy serwer www otrzymuje żądanie
dotyczące serwletu – serwer nie przekazuje tego żądania do serwletu – ale właśnie do
kontenera, w którym to serwlet jest umieszczony.
Czym jest deskryptor rozmieszczenia?
Określa on w jaki sposób należy wykonać serwlety tudzież strony JSP. Deskryptor
rozmieszczenia to nic innego jak prosty dokument XML – określający odwzorowanie
adresów URL na serwlety. Przykład deskryptora – zostanie zaprezentowany w
przykładzie prostej aplikacji internetowej.
Przykład wykorzystania modelu MVC – dla serwletów i stron JSP
MVC – czyli model – widok - kontroler to przykład wzorca projektowego. Główna idea
tegoż – to oddzielenie warstwy biznesowej od warstwy prezentacji.
W przypadku tworzenia aplikacji internetowej – z wykorzystaniem szeroko rozumianej
technologii Javy ( czyli m.in. JSP, serwletów ) model MVC mógłby wyglądać tak:
serwlet
KONTROLER
Kod
Javy
JSP
WIDOK
MODEL
1
Kontroler – Pobiera z żądania dane wejściowe użytkownika. Nakazuje modelowi
samoaktualizację i sprawia że stan zmienionego modelu jest dostępny dla widoku.
Model – Przechowuje logikę biznesową, stan aplikacji. Model może np. współpracować z
bazą danych.
Widok – To warstwa prezentacji. Otrzymuje od kontrolera stan modelu.
Przykład prostej aplikacji internetowej
Poniższy przykład oparty jest na aplikacji opisanej w książce Bahama, Sierra i Batesa –
„Head First Servlets and JSP”.
W niniejszym przykładzie – korzystamy z kontenera Tomcat. Oto struktura katalogów
naszej aplikacji:
TOMCAT
webapps
projekt
WEB-INF
classes
form.html
wynik.jsp
web.xml
com
example
web
model
WyborPiwa.class
EkspertPiwny.class
TOMCAT – katalog domowy Tomcata ( Np. jakarta-tomcat-5.0.19 )
Webapps – katalog wymagany przez kontener odgórnie
Projekt – nazwa naszej aplikacji ( każdy projekt w Tomcat musi mieć swój katalog )
Web.xml – nasz deskryptor rozmieszczenia – znajduje się w katalogu: WEB-INF. Jest to
wymagane!
1. Tworzymy kod formularza w HTML (form.html):
<html><body>
<h1 align="center">strona wyboru piwa</h1>
<fomr method="POST" action="WybierzPiwo.do">
Wybierz właściwości piwa <p>
Kolor:
<select name="kolor">
<option>jasny
2
<option>żółty
<option>brązowy
<option>ciemny
</select>
<br><br>
<center>
<input type="SUBMIT">
</center>
</body></html>
Wyjaśnienie:
„WybierzPiwo.do” – jest to nazwa, którą wykorzystujemy do wywołania
odpowiedniego serwletu. Jest to nazwa logiczna, która nie ma swojego
odzwierciedlenia w strukturze plików. Jest ona znana klientom aplikacji.
„kolor” – w nim przykazujemy informacje z formularza do konkretnego skryptu.
2. Tworzymy deskryptor rozmieszczenia (web.xml):
<web-app 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/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>R3 Piwo</servlet-name>
<servlet-class>com.example.web.WyborPiwa</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>R3 Piwo</servlet-name>
<servlet-class>/WybierzPiwo.do</servlet-class>
</servlet-mapping>
</web-app>
Wyjaśnienie:
„R3 Piwo” – sztuczna nazwa wykorzystywana w ramach tego samego pliku – w
tym przypadku Web.xml.
„com.example.web.WyborPiwa” – nazwa pliku klasy serwletu. ( umieszczona ona
jest w pakiecie ).
„WybierzPiwo.do” – klient w ten sposób odwołuje się do naszego serwletu.
( końcówka do nie jest obowiązkowa – jednak przyjęło się ją nieformalnie
stosować ).
3. Budowa klasy modelu ( EkspertPiwny.java ) – czyli Java w „czystej” postaci:
package com.example.model;
import java.util.*;
public class ExpertPiwny
{
public ArrayList getMarki( String kolor )
{
ArrayList<String> marki = new ArrayList<String>();
if( kolor.equals( "bursztynowy" ) )
3
{
marki.add( "Jack Amber" );
marki.add( "Red Moode" );
}
else
{
}
marki.add( "Jail Pale Ale" );
marki.add( "Gout Stout" );
return (marki);
}
}
4. Budowanie klasy serwletu – tworzenie kontrolera ( WyborPiwa.java ):
package com.example.web;
import
import
import
import
java.io.*;
java.util.*;
javax.servlet.*;
javax.servlet.http.*;
import model.ExpertPiwny;
public class WyborPiwa extends HttpServlet
{
public void doPost( HttpServletRequest request,
HttpServletResponse response )
throws IOException, ServletException
{
String c = request.getParameter( "kolor" );
ExpertPiwny be = new ExpertPiwny();
List wynik = be.getMarki( c );
request.setAttribute( "styles", wynik );
requestDispatcher view = request.getRequestDispatcher(
"wynik.jsp" );
view.forward( Request, response );
}
}
Wyjaśnienie:
„doPost” – skoro formularz wysyła żądanie używając atrybutu method=”POST”,
analogicznie korzystamy z odpowiednika POST-a w serwecie – czyli metody
doPost.
„String c = Request.getParameter( ”kolor” )” – argument tej metody – kolor –
odpowiada użytej przy tworzeniu formularza wartości atrybutu name znacznika
<select>.
„package”.
„Request.setAttribute( „styles”, wynik )” - dodajemy do obiektu żądania, który
będzie wykorzystywany przez stronę JSP. Będzie ona wykorzystywała atrybut
styles.
„requestDispatcher view = Request.getRequestDispatcher( ”Wynik.jsp” )” –
tworzony jest egzemplarz klasy, przekazujący żądanie do właściwej strony JSP.
4
„view.foraward( Request, response )” – wymuszamy na kontenerze zaangażowania
wskazanej strony JSP.
5. Budowanie widoku JSP (wynik.jsp)
<%@ page import="java.util.*" %>
<html>
<body>
<h1 align="center">JSP z rekomendacjami dotyczącymi piwa</h1>
<p>
<%
List styles = (List)request.getAttribute("styles");
Iterator it = styles.iterator();
while( it.hasNext() )
{
out.print( "<br>Sprobuj: " + it.next() );
}
%>
</body>
</html>
Wyjaśnienie:
„List styles = (List)Request.getAttribute(”styles”)” – w tym miejscu pobieramy
atrybut z obiektu żądania.
Uruchamianie serwletów i JSP ( na przykładzie naszej aplikacji )
1. Kompilacja pliku – „EkspertPiwny.java”:
javac -classpath C:\jakarta-tomcat-5.0.19\common\lib\servlet-api.jar:classes:.-d
src\com\example\model\EkspertPiwny.java
Utworzony plik: EkspertPiwny.class – załadowany jest dzięki parametrowi –d do
folderu classes.
2. Kompilacja pliku – „WyborPiwa.java”:
javac -classpath C:\jakarta-tomcat-5.0.19\common\lib\servlet-api.jar:classes:.-d
src\com\example\web\WyborPiwa.java
Utworzony plik: WyborPiwa.class – załadowany jest dzięki parametrowi –d do
folderu classes.
3. Uruchamiamy Tomcata poleceniem – startup.bat
4. Plik JSP – automatycznie jest kompilowany przez kontener po otrzymaniu
pierwszego żadania dotyczącego naszej aplikacji.
Zrzuty działającej aplikacji
Po wpisaniu w okno przeglądarki polecenia:
http://localhost:8080/projekt/form.html - odpalimy nasz program:
5
Widok po otwarciu pliku fomr.html
Po wybraniu koloru – aplikacja powinna na zarekomendować konkretne piwo
Więcej o technologii JSP
Strona JSP jest tłumaczona na serwlet. Wykonuje to za nas kontener WWW. Na
początku więc – kod strony JSP tłumaczony jest na postać kodu źródłowego klasy
Java ( *.java ), po czym następuje kompilacja na postać serwletu.
Dyrektywa page służy do importowania niezbędnych pakietów używanych na
stronie JSP:
Np.
package pakiet;
public class licznik
{
//ciało klasy
public static int getLiczba()
{
//ciało metody
}
}
Aby teraz wykorzystać klasę Javy w naszym pliku JSP, wykonujemy:
<%@ page import="pakiet.*”%>
<html><body>
<%
out.println( licznik.getLiczba() );
%>
</body></html>
Aby zaimportować wiele pakietów piszemy: <%@ page import="pakiet.*,
java.util.*”%>.
Znaczek <%@ - oznacza dyrektywę.
W powyższym przykładowym kodzie JSP – zbędne jest użycie metody println:
wystarczy napisać:
<%= licznik.getLiczba() %> - a wynik i tak będzie wyświetlony na stronie. Są to
tzw. wyrażenia – tłumaczone one są na argumenty wywołań out.print().
Skryptlet: <% %>
6
Dyrektywa <%@ %>
Wyrażenie <%= %>
Pomiędzy <%! i %> możemy deklarować w kodzie JSP zmienne jaki i metody
które są umieszczane w wygenerowanej klasie serwletu.
Np.
<html><body>
<%!
int podwojenie()
{
liczba = liczba * 2;
return liczba;
}
%>
<%!
int liczba = 1;
%>
Liczba wynosi:
<%=
podwojenie()
%>
</body></html>
W kodzie JSP można umieszczać dwa rodzaje komentarzy:
< !--komentarz HTML-- > i <%-- komentarz JSP --%>
Krótki przegląd standardowej biblioteki znaczników (JSTL)
JSTL – to stworzona przez kogoś i upakowana biblioteka znaczników, z których możemy
w prosty sposób korzystać w naszych stronach JSP. Okazuje się że można również
definiować swoje znaczniki.
Przykład:
Kod serwletu:
...
String[] listaFilmow = { "Solaris", "Kroll", "Psy" };
request.setAttribute( "listaFilmow", listaFilmow );
...
Kod JSP:
<table>
<% String[] elementy = (String[])request.getAttribute( "listaFilmow" );
String zmienna = null;
for( int i=0 ; i<elementy.length ; i++ )
{
zmienna = elementy[ i ];
%>
<tr><td><%= zmienna %></td></tr>
<% } %>
</table>
Wykorzystując jednak bibliotekę znaczników nasz kod może wyglądać tak:
Kod JSP z wykorzystaniem JSTL:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html><body>
<strong>Lista filmów</strong>
<br>
<table>
7
<c:forEach var="film" items="${listaFilmow}"
<tr>
<td>${film}</td>
</tr>
</c:forEach>
</table>
</body></html>
Opis niektórych znaczników z biblioteki JSTL:
<c:forEach>
Jest on jakby odpowiednikiem pętli for. Powtarza on się dla każdego elementu czy
to tablicy, odpowiedniej kolekcji tudzież łańcucha w postaci separatora. Znacznik
ten możemy zagnieżdżać.
<c:if>
Odpowiednik kluczowego słowa if – dostępnego w większości języków
programowania.
Znacznik <c:choose> oraz <c:when> i <c:otherwise>
Jest to jakby odpowiednik instrukcji swich, z tym że wybór może być tylko jeden.
Np.
<c:choose>
<c:when test=”${preferencje == ‘bialy’}”>
Lubisz kolor biały!
</c:when>
<c:when test=”${preferencje == ‘czerwony’}”>
Lubisz kolor biały!
</c:when>
<c:otherwise>
Nie lubisz czerwonego i białego?
</c:otherwise>
</c:choose>
<c:set>
Znacznik ten służy np. do dodania nowego elementu dla klasy Map. (Nie możemy
dodać elementów do list lub tablic).
<c:import>
Np. <c:import url=”http://www.buldog.pl/index.html”> - czyli dodaje do
bieżącej strony zawartość pliku wskazanego za pomocą atrybutu url. Przy czym
mammy możliwość dołączania zasobów spoza obszaru kontenera.
Podsumowanie
Referat ten nie miał na celu dokładnego opisania technologii JSP – jak i związanych z
nim technologii pokrewnych. Ma on jedynie na celu zarysowanie – krótki i szybki wgląd
na możliwości programowania serwletów i stron JSP. W niniejszym referacie oparłem się
na książce „Head First Serwlet and JSP” i wszystkich zainteresowanych odsyłam do tej
pozycji, zaznaczając jednak – że trzeba znać choćby podstawy języka Java – by
przystąpić do lektury tegoż. W tejże pozycji możemy poznać szczegóły programowania
serwletów, JSP, związaną z nimi podstawą języka EL, dokładnie zapoznać się z
biblioteka JSTL oraz nauczyć się tworzyć własne znaczniki i wiele innych rzeczy.
8