Java Servlety
CGI programy jsou ponekud tezkopádné (zvlást v Jave). Proto pro Javu existuje lepsí zpusob - servlety. Jednoduchý servlet:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet
{
public void doGet
(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
PrintWriter out;
String title = "Simple Servlet Output";
response.setContentType("text/html");
out = response.getWriter();
out.println("<?xml version=\"1.0\" encoding=\"iso-8859-2\"?>");
out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"");
out.println(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
out.println("<head>");
out.println("<meta http-equiv=\"content-type\"");
out.println(" content=\"text/html; charset=iso-8859-2\" />");
out.println("<title>Sample Servlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
}
}
Nyní uz ovsem potrebujeme server, který si s Javou rozumí, napríklad Apache Tomcat. Potom stací zadat http://localhost:8080/HelloWorld a dostaneme patricný výstup.
Ocividne jsme se stále nevyhnuli kostrbaté produkci výstupu. Síla servletu tkví ale jinde. Trídy
HttpServletRequest, resp. HttpServletResponse, zapouzdrují data putující od klienta, resp. k
nemu. Metoda HttpServletRequest.getParameter vrátí hodnotu parametru (at uz slo o predání dat metodou GET
nebo POST). Pro rucnízpracování slouzí metody
HttpServletRequest.getQueryString (pro GET) a
HttpServletRequest.getReader (pro POST, pokud cekáme textová data) nebo
HttpServletRequest.getInputStream (pro POST, pokud cekáme binární data). Pro odeslání textových dat slouzí
HttpServletResponse.getWriter, pro odeslání binárních HttpServletResponse.getOutputStream.
Príklad: výpis HTTP hlavicek:
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
out.print("<tr><td>" + headerName + "</td>");
out.println("<td>" + request.getHeader(headerName) + "</td></tr>");
}
Príklad - výpis príchozích formulárových dat:
Enumeration paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = (String) paramNames.nextElement();
out.print("<tr>\n<td>" + paramName + "</td>\n<td>");
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length == 1) {
String paramValue = paramValues[0];
if (paramValue.length() == 0) out.print("<em>No Value</em>");
else out.print(paramValue);
}
else {
out.println("\n<ul>");
for(int i=0; i < paramValues.length; i++) {
out.println("<li>" + paramValues[i] + "</li>");
}
out.println("</ul>");
}
out.println("</td></tr>");
}
Samotný
zivotservletu má tri fáze: inicializace (metoda
init), zpracovávání klientských
pozadavku (metody doGet a doPost - ve skutecnosti jsou tyto metody automaticky volány pomocí
metody service, kterou muzeme, ale nemusíme, predefinovat) a úklid (metoda destroy). Metoda
init je vhodná pro cinnosti jako spojení s databází, otevrení souboru, v metode destroy se
obvykle delá opak.
Sessions
Protokol HTTP je bezstavový, tudíz kazdý klientský pozadavek je zcela samostatný a nijak nesouvisí s tím predchozím. Coz
je v mnoha prípadech velmi nepríjemné (napr. autentifikace). Resením jsou takzvané HTTP sesssions. Objekt trídy
HttpSession vytvoríme metodou HttpServletRequest.getSession, jako parametr jí predáme konstantu
true, která zajistí, ze pokud session spojená s tímto klientem neexistuje, bude vytvorena. Poté do promenné
typu HttpSession muzeme pomocí retezcového klíce ukládat hodnoty libovolné promenné metodou
putAttribute (napr. putAttribute("customer_details", custDetails)) nebo tyto hodnoty zase
vyzvedávat (typicky na dalsí stránce nasí webové aplikace) metodou getAttribute - je ovsem treba provést
explicitní pretypování: custDetails = (Customer) session.getAttribute("customer_details"). Ke zrusení session
(napr. pri odhlásení uzivatele) slouzí metoda invalidate.
Sessions jsou implementovány pomocí cookies. Ty nemusí prohlízec umet nebo je mohl uzivatel zakázat. Existuje i jiná
moznost, jak sessions implementovat - predáváním session ID v rámci URL. Pro pouzití tohoto mechanismu je potreba vsechny
odkazy
Bezpecnostním poznámka: session ID je relativne snadno ukradnutelné, pro zvýsení bezpecnosti je výhodnejsí obejít standardní prostredky a implementovat sessions vlastnorucne - speciální tabulkou pro sessions v databázi, kde bude ulozeno session ID, cas posledního prístupu (pro moznost autoexpirace, nekterí uzivatelé povazují tlacítko Logout za zbytecný pedantismus), IP adresu a prípadne dalsí informace; pro samotné predávání session ID lze zvolit bud cookies nebo prídavný parametr v URL (tím se sice nevyhneme moznosti ukradnutí session ID, ale útocník by musel falsovat i IP adresu, coz uz predstavuje výrazne vetsí problém).
prohnatmetodou
HttpServletResponse.encodeURL.
Bezpecnostním poznámka: session ID je relativne snadno ukradnutelné, pro zvýsení bezpecnosti je výhodnejsí obejít standardní prostredky a implementovat sessions vlastnorucne - speciální tabulkou pro sessions v databázi, kde bude ulozeno session ID, cas posledního prístupu (pro moznost autoexpirace, nekterí uzivatelé povazují tlacítko Logout za zbytecný pedantismus), IP adresu a prípadne dalsí informace; pro samotné predávání session ID lze zvolit bud cookies nebo prídavný parametr v URL (tím se sice nevyhneme moznosti ukradnutí session ID, ale útocník by musel falsovat i IP adresu, coz uz predstavuje výrazne vetsí problém).
Cookies
Trída
Cookie obsahuje konstruktor Cookie(String key, String value). Vytvorené cookie lze
nastavovat dalsí vlastnosti (casovou platnost, platnost pro konkrétní doménu, prípadne cestu v rámci ní, …). Pro
pridání nasí cookie do HTTP hlavicky je potreba zavolat metodu HttpServletResponse.addCookie(Cookie
cookie). Naopak k vyzvednutí cookies slouzí metoda HttpServletRequest.getCookies, která vrací
Cookies[].