Java wybrane technologie spotkanie nr 6 Java Server Pages c.d.
JavaBeans konwencja nazewnicza getxxx(), setxxx() i isxxx() publiczny, bezargumentowy konstruktor można serializować przy pomocy ObjectOutputStream package beany; public class Osoba { private String imię; private int wiek; private boolean królowabalu; public String getimię() { return imię; } public void setimię(string imię) { this.imię = imię; } public boolean iskrólowabalu() { return królowabalu; } public void setkrólowabalu(boolean królowabalu) { this.królowabalu = królowabalu; } public int getwiek() { return wiek; } } public void setwiek(int wiek) { this.wiek = wiek; } 2
Jak nie korzystać z JavaBeans w JSP formularz HTML <form action="osoba1.jsp"> Imię: <input type="text" name="imie" value="ala"/><br/> Wiek: <input type="text" name="wiek" value="24"/><br/> Królowa balu: <input type="checkbox" name="krolowabalu"/><br/> <input type="submit"/> </form> JSP (Osoba1.jsp) <%@ page import="beany.osoba" %> <% Osoba osoba = null; synchronized(session) { osoba = (Osoba) session.getattribute("osoba"); if (osoba == null) { osoba = new Osoba(); session.setattribute("osoba", osoba); } osoba.setimię(request.getparameter("imie")); osoba.setwiek(new Integer(request.getParameter("wiek"))); osoba.setkrólowabalu("on".equals(request.getparameter("krolowabalu"))); } %> Zapamiętano dane osoby! (<a href="pokazdaneosoby1.jsp">pokaż dane</a>) 3
Jak nie korzystać z JavaBeans w JSP c.d. JSP (PokażDaneOsoby1.jsp) <%@ page import="beany.osoba" %> <% Osoba osoba = null; synchronized(session) { osoba = (Osoba) session.getattribute("osoba"); if (osoba == null) { %> Nie było zapamiętanych osób! <% } else { %> Zapamiętano osobę <%= osoba.getimię()%>, o wieku <%= osoba.getwiek()%>, która <%= (osoba.iskrólowabalu()? "jest" : "nie jest") %> królową balu. <% } } %> 4
Korzystanie z JavaBeans przy pomocy akcji <jsp:usebean> atrybuty id obowiązkowa nazwa zmiennej scope domyślnie page class klasa beana (pełna nazwa) type typ zmiennej (pełna nazwa) beanname nazwa zserializowanego beana (np. beany.ala -> beany/ala.ser) lub nazwa klasy (w odróżnieniu od class może być wyliczana w trakcje żądania) możliwe kombinacje: class type jak nie istniał egzemplarz to zgłaszany jest InstantiationException class i type jeżeli egzemplarz nie istniał to jest tworzony beanname i type używa java.beans.beans.instantiate() 5
Przykład JSP <jsp:usebean id="osoba" type="osoba" scope="session" beanname="beany.ala"/> wygenerowany Serwlet Osoba osoba = null; synchronized (session) { osoba = (Osoba) session.getattribute("osoba"); if (osoba == null){ try { osoba = (Osoba) java.beans.beans.instantiate(getclass().getclassloader(), "beany.ala"); } catch (ClassNotFoundException exc) { throw new InstantiationException(exc.getMessage()); } catch (Exception exc) { throw new ServletException("Cannot create bean of class " + "beany.ala", exc); } session.setattribute("osoba", osoba); } } 6
Zawartość jsp:usebean zawartość elementu jsp:usebean jest wykonywana, jeżeli nie odnaleziono istniejącego egzemplarza zawartość nie musi być skryptletem <jsp:usebean id="osoba" class="beany.osoba" scope="session"> <% osoba.setimię("ala"); osoba.setwiek(24); osoba.setkrólowabalu(false); %> </jsp:usebean> wygenerowany serwlet: synchronized (session) { osoba = (beany.osoba) session.getattribute("osoba"); if (osoba == null){ osoba = new beany.osoba(); session.setattribute("osoba", osoba); } } osoba.setimię("ala"); osoba.setwiek(24); osoba.setkrólowabalu(false); 7
Korzystanie z JavaBeans przy pomocy akcji c.d. <jsp:setproperty> atrybuty name obowiązkowa nazwa zmiennej property obowiązkowa nazwa zmienianej właściwość value nowa wartość param parametr żądania możliwe kombinacje: value param jak nie ma takiego parametru żądania, to wartość nie ulega zmianie; jak ma kilka wartości, to brana jest pod uwagę tylko pierwsza ani value ani param param ma wartość property jako property można podać "*" <jsp:getproperty name="..." property="..."> 8
Jak korzystać z JavaBeans w JSP formularz HTML <form action="osoba2.jsp"> Imię: <input type="text" name="imie" value="ola"/><br/> Wiek: <input type="text" name="wiek" value="25"/><br/> <table> <td>królowa balu:</td> <td> <input type="radio" name="krolowabalu" value="true" checked="1"/>tak<br/> <input type="radio" name="krolowabalu" value="false" />Nie </td> </table> <input type="submit"/> </form> JSP (Osoba2.jsp) <%@ page import="beany.osoba" %> <jsp:usebean id="osoba" class="beany.osoba" scope="session"/> <jsp:setproperty name="osoba" property="*"/> <%-- uwaga na polskie litery --%> <jsp:setproperty name="osoba" property="imię" param="imie"/> Zapamiętano dane osoby! (<a href="pokazdaneosoby2.jsp">pokaż dane</a>) 9
Jak korzystać z JavaBeans w JSP c.d. JSP (PokażDaneOsoby2.jsp) <%@ page import="beany.osoba" %> <% boolean czybyłaosoba = true; %> <jsp:usebean id="osoba" class="beany.osoba" scope="session"> <% czybyłaosoba = false; %> </jsp:usebean> <% if (!czybyłaosoba) { %> Nie było zapamiętanych osób! <% } else { %> Zapamiętano osobę <jsp:getproperty name="osoba" property="imię"/>, o wieku <jsp:getproperty name="osoba" property="wiek"/>, która <%= (osoba.iskrólowabalu()? "jest" : "nie jest") %> królową balu. <% } %> 10
Konwersja typów Zazwyczaj silnik JSP jest za nas w stanie wykonać konwersję typów bean: public class Abecadło { private char[] litery; public char[] getlitery() { return litery; } public void setlitery(char[] litery) { this.litery = litery; } } link: IndeksowaneWlasciwosci.jsp?litery=Ala&litery=Ela&litery=Ola&litery=Ula strona: <%@ page import="beany.abecadło" %> <jsp:usebean id="abecadło" class="beany.abecadło"/> <jsp:setproperty name="abecadło" property="litery"/> <jsp:getproperty name="abecadło" property="litery"/> <%-- zazwyczaj będziemy jednak chcieli wypisać elementy tablicy --%> <br/> <% for (char c : abecadło.getlitery()) out.println(c); %> 11
Expression Language (EL) język programowania o własnej składni, zestawie operatorów, itp. opracowany przez twórców Java Standard Tag Library (JSTL) część standardu alternatywa dla skryptów Przykład wyrażenie Witaj <%= kto %> Przykład EL Witaj ${kto} 12
Dostęp do zmiennych Z EL nie ma dostępu do zmiennych Javy <%! String kto = "Ala"; %> Wyrażenie: Witaj <%= kto %> <br/> EL: Witaj ${kto} <br/> <%-- nic nie zwróci --%> Witaj ${ param.kto } EL implicit variables pagecontext dostęp do zwykłych implicite objects strony JSP pagescope, requestscope, sessionscope, applicationscope mapy z atrybutami z kolejnych zasięgów param, paramvalues mapy z parametrami żądania (String i String[]) header, headervalues mapy z nagłówkami (String i String[]) cookie mapa z ciasteczkami 13
Operatory a.b własność b obiektu a a[b] wartość związana z kluczem lub indeksem b można używać zamiennie jeżeli b jest napisem <%-- host to napis, więc można używać zamiennie--%> header["host"]=${ header["host"] } <br/> header['host']=${ header['host'] } <br/> <%-- header[host]=${ header[host] } <br/> --%> header.host=${ header.host } <br/> headervalues.host["0"]=${ headervalues.host["0"] } <br/> headervalues.host['0']=${ headervalues.host['0'] } <br/> headervalues.host[0]=${ headervalues.host[0] } <br/> <%-- headervalues.host.0=${ headervalues.host.0 } <br/> --%> <%-- headervalues.host."0"=${ headervalues.host."0" } <br/> --%> 14
Operatory arytmetyczne dodawanie: + odejmowanie: - mnożenie: * dzielenie: / oraz div modulo: % oraz mod można operować na dużych liczba BigInteger oraz BigDecimal 1.3e3/1000=1.3 "4"+3=7 x div 3=0.0 15
Operatory logiczne literały logiczne: true i false równość: == oraz eq nierówność:!= oraz ne mniejsze niż: < oraz lt większe niż: > oraz gt mniejsze lub równe: <= oraz le większe lub równe: >= oraz ge koniunkcja: && oraz and alternatywa: oraz or negacja:! oraz not nie ma if, for ani while, ale jest operator ternarny: X? Y : Z 16
Udostępnianie funkcji Javy Co potrzeba: klasy których metody będą wywoływane w EL tag library desciptor (tld) wskazać tld w web.xml 17
Udostępnianie funkcji: klasa Javy klasa musi być publiczna metody muszą być statyczne i publiczne argumenty i wartości zwrotne metod muszą mieć sens w EL klasa powinna się znajdować w /WEB-INF/classes (lub w jarze) package el; public class MetodyNaNapisach { public static String dużelitery( String x ) { return x.touppercase(); } } public static int długość( String x ) { return x.length(); } 18
Udostępnianie funkcji: tld zazwyczaj umieszczamy w /WEB-INF <?xml version="1.0" encoding="utf-8"?> <taglib 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-jsptaglibrary_2_0.wsd" version="2.0"> <tlib-version>1.0</tlib-version> <function> <name>nadużelitery</name> <function-class>el.metodynanapisach</function-class> <function-signature> java.lang.string nadużelitery(java.lang.string) </function-signature> </function> <function> <name>długość</name> <function-class>el.metodynanapisach</function-class> <function-signature> java.lang.string długość(java.lang.string) </function-signature> </function> </taglib> 19
Udostępnianie funkcji: przykład użycie funkcji w EL <%@ taglib prefix="mim1" uri="/web-inf/moje_funkcje.tld" %> nadużelitery("ala")=${ mim1:nadużelitery("ala") } <br/> dobrym pomysłem jest przypisanie bibliotece URI w web.xml <web-app>... <jsp-config> <taglib> <taglib-uri> http://mimuw.edu.pl/jsp2/el/funkcje <!--URI może być też względne (/...)--> </taglib-uri> <taglib-location> /WEB-INF/moje_funkcje.tld </taglib-location> </taglib> </jsp-config> </web-app> <%@ taglib prefix="mim2" uri="http://mimuw.edu.pl/jsp2/el/funkcje" %> długość("ala")=${ mim2:długość("ala") } <br/> 20
Custom tags tag handler klasa z kodem wykonywanym po napotkaniu znacznika Tag, IterationTag, BodyTag SimpleTag tag library zazwyczaj potrzebujemy więcej niż jeden znacznik tag library descriptor (TLD) trochę metainformacji mapowanie URI wygoda gdzie wskazywane http://jakarta.apache.org/taglibs JSP Standard Tag Library (JSTL) 21
JSTL core zastosowania ogólne xml parsowanie, wskazywanie i przekształcanie XML fmt i18n sql dostęp do relacyjnych baz danych functions manipulowanie napisami i kolekcjami w Tomcacie jest JSTL 1.1 trzeba skopiować jstl.jar i standard.jar z $CATALINA_HOME/webapps/jsp-examples/WEB-INF/lib do WEB- INF/lib w swojej aplikacji <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> 22
core ogólnego przeznaczenia <c:catch var="x">...</c:catch> ewentualny wyjątek zostanie przypisany na x, jak nie było wyjątku wartość x zostanie skasowana <c:out value="..."/> wypisuje wartość i zamienia na encję niektóre znaczki (<, >, ', ", &); można tez podać parametr default, który jest używany jak zmienna nie została zainicjalizowana obsługa zmiennych <c:set var="x" value="x"/> inaczej w EL nie można ustawiać zmiennych <c:set var="x">x</c:set> inny sposób <c:set target="bean/mapa" property="x" value="x"/> dla beanów i map <c:remove var="x" scope="session"/> jak nie ma scope to kolejno przeszukiwana jest strona, żądanie, sesja, aplikacja 23
core c.d. przepływ sterowania <c:if test="${x == '1'}"> ciapki są konieczne <c:choose> zawiera dowolną ilość <c:when test="...">...</c:when> i ewentualnie <c:otherwise>...</c:otherwise> <c:foreach var="x"...> ${x} </c:foreach> begin, end, step standardowy for items przeglądanie kolekcji <c:fortokens var="x" items="..." delims="..."> iteruje po podnapisach obsługa URL <c:url value="/index.html" var="url"> koduje sesję w url (url może być konstruowany przy pomocy parametrów przekazywanych w ciele) <c:import url="..." var="x"> na x przypisuje odpowiedź zdalnego zasobu (mogą nie należeć do aplikacji) (też może mieć parametry w ciele) <c:redirect> (też może mieć parametry w ciele) 24
Przykład <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> <c:catch var="wyjątek"> <c:out value="${10/0}" /><br/> <c:out value="${x}" /><br/> <c:out value="${x}" default="x"/><br/> <c:out value="${x+y}" /><br/> <c:out value="${requestscope.kto == \"Ala\"}" /><br/> <% if (true) throw new Exception(); %> </c:catch> <c:choose> <c:when test="${wyjątek!= null}"> Był wyjątek: <c:out value="${pagescope.wyjątek}"></c:out> </c:when> <c:otherwise> Nie było wyjątku. </c:otherwise> </c:choose> 25
Przykład <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> <c:set var="lista" value="ala,ola,ela,ula"/> <table border=1"> <c:fortokens var="x" items="${lista}" delims=","> <tr><td>${x}</td></tr> </c:fortokens> </table> <c:import url="pozdrawiak1.jsp" var="y"> <c:param name="kto" value="ala"/> </c:import> <h3>wartość y:</h3> ${ y } 26