Java wybrane technologie spotkanie nr 5 Java Server Pages 1
Składnia dowolny HTML (template) <%@ dyrektywa %> <%! deklaracja %> <% skryptlet %> <%= wyrażenie %> <jsp:nazwaakcji /> <%-- komentarz --%> 2
Przykład <?xml version="1.0" encoding="utf8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf8" /> <title>witaj świecie</title> </head> <body> <%@ page language="java" contenttype="text/html; charset=utf8" pageencoding="utf8" %> <%! int licznik = 0; %> <% licznik++; %> Witaj świecie (liczba wejść <%= licznik %>) <%-- To jest komentarz --%> </body> </html> 3
Fragment wygenerowanego serwletu Opracował public final class WitajSwiecie_jsp extends org.apache.jasper.runtime.httpjspbase implements org.apache.jasper.runtime.jspsourcedependent { int licznik = 0; public void _jspservice(httpservletrequest request, HttpServletResponse response) throws java.io.ioexception, ServletException { PageContext pagecontext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this;... 4
Fragment wygenerowanego serwletu c.d. Opracował... try { response.setcontenttype("text/html; charset=utf8"); pagecontext = _jspxfactory.getpagecontext(this, request, response, null, true, 8192, true); application = pagecontext.getservletcontext(); config = pagecontext.getservletconfig(); session = pagecontext.getsession(); out = pagecontext.getout(); } }... out.write("<html xmlns=\"http://www.w3.org/1999/xhtml\">\n");... licznik++; out.write("witaj świecie (liczba wejść "); out.print( licznik ); out.write(")\n"); out.write("</body>\n"); out.write("</html>"); } catch (Throwable t) {... } finally {... } 5
Dyrektywy <%@ dyrektywa lista-atrybutów %> możliwe dyrektywy to page, include, taglib lista atrybutów istotna jest wielkość znaków wartości muszą być otoczone parą " lub ' przed i po = nie może być spacji przykłady <%@ page language="java" %> <%@ include file="plki.html" %> <%@ taglib prefix="test" uri="taglib.tld" %> 6
Deklaracje mogą zawierać dowolne Javowe deklaracje włącznie z klasami wewnętrznymi i blokami inicjalizacji statycznej. kilka deklaracji w jednym bloku <%! String[] wykłady = {"Wprowadzenie", "JavaMail", "Serwlety", "Serwlety c.d.", "JSP"}; String getwykład(int i) { return wykłady[i-1]; } %> deklaracje w oddzielnych blokach <%! String[] wykłady = {"Wprowadzenie", "JavaMail", "Serwlety", "Serwlety c.d.", "JSP"}; %> <%! String getwykład(int i) { return wykłady[i-1]; } %> 7
Skryptlety zawierają kod umieszczany w metodzie service() silnik JSP sam deklaruje dla nas kilka zmiennych, np. response i out <%! int i = 0; %> <% response.setcontenttype("text/html;charset=utf8"); %> out.println("<html>"); out.println("<head>"); out.println("</head>"); out.println("<body>"); out.println("<h3>liczniknaatrybucie</h3>"); out.println("aktualna wartość: " + i++); out.println("</body>"); out.println("</html>"); 8
Wyrażenia wypisuję wartość zmiennej typu podstawowego lub napisu reprezentującego obiekt (nie kończą się średnikiem) <%! int wartośćcałkowita = 7; boolean wartośćlogiczna = true; char getlitera() { return 'A'; } //nie może być void Float obiektfloat = new Float(12.6f); String napis = "jakiś napis"; StringBuilder bufor = new StringBuilder("początek"); %> <ul> <li>123=<%= 123 %></li> <li>wartośćcałkowita=<%= wartośćcałkowita %></li> <li>wartośćlogiczna=<%= wartośćlogiczna %></li> <li>true=<%= true %></li> <li>!true=<%=!true %></li> <li>getlitera()=<%= getlitera() %></li> <li>math.random()=<%= Math.random() %></li> <li>obiektfloat=<%= obiektfloat %></li> <li>obiektfloat.floatvalue()=<%= obiektfloat.floatvalue() %></li> <li>obiektfloat.tostring()=<%= obiektfloat.tostring() %></li> <li>napis=<%= napis %></li> <li>bufor=<%= bufor %></li> </ul> 9
Akcje jsp:include i jsp:forward poprzez RequestDispatcher jsp:usebean, jsp:setproperty i jsp:getproperty jsp:plugin definiowane przez użytkownika (custom tags) 10
Komentarze <%-- komentarz JSP --%> <% //komentarz Javy %> <!-- komentarz HTML --> 11
Cykl życia tłumaczenie strony (dla całej translation unit) strona może być składana z kawałków przy pomocy dyrektywy include również walidacja składni kompilacja można wymusić kompilację nie wykonując żądania url?jsp_precompile=true lub url?jsp_precompile samemu nie należy stosować parametrów z przedrostkiem jsp załadowanie klasy 12
Cykl życia c.d. utworzenie egzemplarza serwlet implementuje javax.servlet.jsp.httpjsppage wywołanie jspinit() można zadeklarować przy pomocy deklaracji <%! %> wywołanie _jspservice() wywołanie jspdestroy() można zadeklarować przy pomocy deklaracji <%! %> 13
Dyrektywa page import rozdzielona przecinkiem lista klas i pakietów, które chcemy zaimportować zawsze są importowane javax.servlet.*, javax.sevlet.jsp.*, javax.servlet.http.* przykład <%@ page import="java.util.*, java.io.*" %> session true lub false w zależności od tego czy strona bierze udział w sesji czy nie (zmienna session) errorpage względny adres URL, która ma być użyta do obsługi błędów powstałych w tej stronie razem z iserrorpage pozwala wielokrotnie zastosować ten sam kod obsługi błędów dobrą praktyką jest używać tego atrybutu we wszystkich stronach iserrorpage true lub false w zależności od tego czy dana strona może być użyta jako strona obsługi błędów 14
Przykład Wyjatek.jsp <%@ page errorpage="obslugawyjatku.jsp" %> <% if (true) throw new Exception("nasz komunikat"); %> ObslugaWyjatku.jsp <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>obsługa wyjątku</title> </head> <body> <%-- jeżeli chcemy używać zmiennej exception --%> <%@ page iserrorpage="true" %> <h1>złapano: <%= exception.getmessage() %></h1> <%-- ta strona mogła by być statyczna --%> </body> </html> 15
Dyrektywa page c.d. language jedyna możliwa wartość to java (można nie podawać) extends wskazuje klasę, którą będzie rozszerzał serwlet domyślna klasa zależy od implementacji i zazwyczaj się jej nie zmienia buffer wielkość bufora przechowującego wyjście specyfikacja wymusza przynajmniej 8kb autoflush jak true dane z bufora są wysyłane do klienta w momencie przepełnienia, jak false zgłaszany jest wyjątek info wartość zwracana przez getservletinfo() contenttype domyślnie text/html;iso-8859-1 pageencoding domyślnie ISO-8859-1 16
Niuanse kolejność deklaracji zadeklarowaniem <body> <%= powitanie %> <%! String powitanie = "Witaj świecie"; %> </body> kolejność skryptletów <body> <% String x = a+b; %> <%-- b jest niezdefiniowane--%> <%! String a = "a"; %> <% String b = "b"; %> </body> inicjalizacja zmiennych <%! int i; %> Atrybut i posiada wartość <%= i %> <br/> <% int j; %> <%-- zmienne w javie nie mają wartości domyślnych --%> Zmienna j posiada wartość <%= j %> atrybuty zachowują wartość między wywołaniami 17
Instrukcje Javy <% %> if (true) out.println("<code>true</code>"); else out.println("<code>false</code>"); <%-- zazwyczaj nawiasy klamrowe są potrzebne --%> <% if (true) { %> <code>true</code> <% } else { %> <code>false</code> <% } %> 18
Atrybuty wyliczane w chwili wywołania <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>akcje</title> </head> <body> <jsp:include page="naglowek.html" /> <h3>treść</h3> <p>to jest treść</p> <% String adresstopki="stopka.html"; %> <jsp:include page="<%= adresstopki %>" /> </body> </html> 19
Implict variables & objects application javax.servlet.servletcontext np. application.log() lub getrealpath("/web-inf/licznik.txt") session javax.servlet.http.httpsession tylko jak <%@ page session="true" %> request javax.servlet.http.httpservletrequest response javax.servlet.http.httpservletresponse out javax.servlet.jsp.jspwriter page java.lang.object nieprzydatne, bo trzeba rzutować; lepiej używać this pagecontext javax.servet.jsp.pagecontext pozwala uzyskać session, application, config i out metody pozwalające pobierać i ustawiać atrybuty w różnych zasięgach przechowuje atrybuty dla zasięgu "page" (to samo żądanie i translation unit) forward() i include() exception java.lang.throwable tylko jak <%@ page iserrorpage="true" %> 20
Implict variables & objects config javax.servlet.servletconfig strony JSP też mogą mieć parametry Nazwa serwletu = <%= config.getservletname() %> <br/> Wartość parametru x = <%= config.getinitparameter("x") %> <servlet> <servlet-name>parametry</servlet-name> <jsp-file>/config.jsp</jsp-file> <init-param> <param-name>x</param-name> <param-value>ala</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>parametry</servlet-name> <url-pattern>/config.jsp</url-pattern> <!-- jak by nie było tego mapowania, byłyby dwa egzemplarze serwletu --> </servlet-mapping> 21
Deklaracja z Tomcata public void _jspservice(httpservletrequest request HttpServletResponse response) throws java.io.ioexception, ServletException { PageContext pagecontext = null; HttpSession session = null; Throwable exception = org.apache.jasper.runtime. JspRuntimeLibrary.getThrowable(request); if (exception!= null) { response.setstatus(httpservletresponse.sc_internal_server_error); } ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; try { response.setcontenttype("text/html; charset=utf-8"); pagecontext = JspFactory.getDefaultFactory().getPageContext (this, request, response, null, true, 8192, true); application = pagecontext.getservletcontext(); config = pagecontext.getservletconfig(); session = pagecontext.getsession(); out = pagecontext.getout();... 22
Składnia XML <?xml version="1.0" encoding="utf-8"?> <jsp:root xmlns:jsp="http://java.sun.com/jsp/page" version="2.0"> <jsp:directive.page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8" /> <jsp:text> <![CDATA[ <?xml version="1.0" encoding="utf-8"?> ]]> </jsp:text> <jsp:text> <![CDATA[ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/dtd/xhtml1- transitional.dtd"> ]]> </jsp:text> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>składnia XML</title> </head> <body> <jsp:declaration> String kto="ala"; </jsp:declaration> <jsp:scriptlet> String pozdr="witaj "+kto+"!"; </jsp:scriptlet> <jsp:expression> pozdr </jsp:expression> </body> </html> </jsp:root> 23
Statyczna inkluzja wartość atrybutu nie może być wyliczana <%@ include file="<%= wyr %>" %> nie odbywa się żadne żądanie, więc nie ma sensu przekazywać parametrów <%@ include file="inna.jsp?fiubździu=trelemorele" %> strony nie muszą się kompilować niezależnie - mogą dzielić zmienne (chociaż lepiej używać w tym celu pagecontext) 24
odpowiada RequestDispatcher.include() można dodać parametr flush="true" (czy przed przekazaniem sterowania opróżnić bufor) 25
odpowiada RequestDispatcher.forward() nie można użyć parametru flush 26
Przekazywanie parametrów <jsp:include page="..."> <jsp:param name="nazwa1" value="wartość1"/> <jsp:param name="nazwa2" value="<%= wyr %>"/> </jsp:include> 27