1
JAVA – Servlety
Odczyt danych przesłanych
przez użytkownika
Analiza informacji dotyczących żądania
możliwości przeglądarki (wersja)
cookies
nazwa komputera, na którym działa program
Generowanie wyników
Wymiana informacji z bazą danych
Wywołanie procedury RMI lub CORBA
Formatowanie wyników
HTML
XML
Podanie parametrów odpowiedzi HTTP
Typ przesyłanego dokumentu
Podanie cookies
Parametry zarządzające przechowywaniem strony w pamięci podręcznej przeglądarki Wysłanie
dokumentu z odpowiedzią do
użytkownika
HTML
GIF
GZIP
Użytkownik
Servlet
Pracujący na serwerze WWW
2
JAVA – Uruchamianie Servletów
• Instalacja na serwerze WWW
Tomcat (http://jakarta.apache.org)
Java Web Server (J2EE)
• Java Server Development Kit
set CLASSPATH=. “ścieżka dostępu do “\servlet.jar
uruchomienie: servletrunner.exe
• Dokumentacja API
– http://java.sun.com/products/jsp/download.html – http://java.sun.com/products/servlet/2.2/javadoc – http ://java.sun.com/j2ee/j2sdkee/techdocs/api
3
JAVA – Implementacja Servletu
import java.io.*;
import javax.servlet.*; // HttpServlet
import javax.servlet.http.*; // interfejsy HttpServletRequest, HttpServletResponse
public class ServletSzablon extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// zmiennej "request” (żądanie) należy używać do odczytywania // nagłówków HTTP przekazanych przez przeglądarkę (na przykład // cookies) oraz danych podawanych w formularzach HTML (czyli // danych wpisanych i przesłanych przez użytkownika).
// zmiennej "response" (odpowiedź) należy używać do określania
// kodu statusu odpowiedzi HTTP oraz nagłówków odpowiedzi (na przykład // typu danych oraz cookies).
PrintWriter out = response.getWriter();
// strumień do przesyłania kodu HTML do przeglądarki
response.setContentType(”text/plain; charset=ISO-8859-2”);
out.println(” jestem sobie takim zwyklym servlecikiem”);
} }
4
JAVA – Struktura zapytania i odpowiedzi HTPP
POST /TheStockExchange/Trading/GetStockPrice.asp HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded Content-Length: 11
Symbol=MSFT
POST /TheStockExchange/Trading/GetStockPrice.asp HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded Content-Length: 11
Symbol=MSFT Pusta linia !Pusta linia !
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8 Content-Length: 75
<?xml version="1.0" encoding="utf-8"?>
<stock symbol="MSFT" Price="71.50" />
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8 Content-Length: 75
<?xml version="1.0" encoding="utf-8"?>
<stock symbol="MSFT" Price="71.50" />
Pusta linia ! Pusta linia !
•Zapytanie (Request)
•Odpowiedź(Response)
5
JAVA – Metoda GET i POST
GET /Trading/GetStockPrice.asp?Symbol=MSFT HTTP/1.1 Host: localhost
GET /Trading/GetStockPrice.asp?Symbol=MSFT HTTP/1.1 Host: localhost
POST /Trading/GetStockPrice.asp HTTP/1.1 Host: localhost
Content-Type: application/x-www-form-urlencoded Content-Length: 11
Symbol=MSFT
POST /Trading/GetStockPrice.asp HTTP/1.1 Host: localhost
Content-Type: application/x-www-form-urlencoded Content-Length: 11
Symbol=MSFT
•HTTP-GET
•HTTP-POST
6
JAVA – nagłówki zapytań i odpowiedzi HTTP
Accept
Accept-Charset Accept-Encoding Accept-Language Authorization Cache-Control Connection
Content-Length Content-Type Cookie
Except FromHost
If-Match
If-Modified-Since If-None-Match
If-Range
If-Unmodified-Since Pragma
Proxy-Authorization Range
Refer Upgrade
User-Agent ViaWarning
7
JAVA – podstawowe funkcje składowe servletów
• Obsługa żądania GET
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... }
•Obsługa żądania POST
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {…..}
• Inicjacja servletu
public void init() throws ServletException { ….}
public void init(ServletConfig config) {super.init(config); ….}
• obsługa żądań PUT, DELETE
public void doPut ...
public void doDelete ...
•Uniwersalna metoda service
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... }
8
JAVA – Servlety: rodzaje odpowiedzi
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class TextServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//nagłówek odpowiedzi
response.setContentType( "text/plain; charset=ISO-8859-2" ); // zwykły tekst z polskimi
// znakami
PrintWriter out = response.getWriter();
out.println( "Witaj Świecie!" );
} }
public class ServletWWW extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; encoding=ISO-8859-2");
PrintWriter out = response.getWriter();
// określenie specyfikacji HTML potrzebne przy testowaniu stron WWW ze względu na // błędy składni w kodzie HTML
// narzędzia sprawdzania kodu: http://validator.w3.org // www.htmlhelp.com/tools/validator
// metodą doGet odpowiedź jest dołączana do adresu URL, zatem można do serwisu // sprawdzającego przekazać adres URL servletu
String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 "
+"Transitional//EN\">\n";
out.println(docType +
"<HTML>\n" +
"<HEAD> <TITLE>Witaj WWW</TITLE> </HEAD>\n" + "<BODY>\n" +<H1>Witaj WWW</H1>\n" + "</BODY>
</HTML>");
}}}
9
JAVA – Servlety: rodzaje odpowiedzi – typy MIME
•"text/plain"
•"text/plain; charset=ISO-8859-2"
•"text/html "
•"text/html; charset= ISO-8859-2"
•"image/gif"
•"image/jpeg"
•"image/tiff"
•"image/png"
•"application/vnd.ms-excel"
10
JAVA – Servlety: parametry startowe
import java.io.*; import javax.servlet.*; import javax.servlet.http.*;
public class ShowServerParameter extends HttpServlet { private String messageString;
private String defaultMessage = "Brak komunikatu.";
private int repeats = 1;
public void init(ServletConfig config) throws ServletException { super.init(config);
messageString = getInitParameter("message");
if (message == null) { message = defaultMessage;}
try {
String repeatString = getInitParameter("repeats");
repeats = Integer.parseInt(repeatString);
} catch(NumberFormatException nfe) { }
}public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; encoding=ISO-8859-2");
PrintWriter out = response.getWriter();
String docType ="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +"Transitional//EN\">\n";
out.println(docType + "<HTML>\n" +"<HEAD><TITLE> Serwlet ShowMessage </TITLE></HEAD>\n"
+ "<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H1 ALIGN=CENTER>Serwlet ShowMessage</H1>");
for(int i=0; i<repeats; i++) {
out.println(messageString + "<BR>");
}out.println("</BODY></HTML>");
}}
11
JAVA – Servlety: Odczyt parametrów przesłanych z formularza
public class Parametry extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=ISO-8859-2");
PrintWriter out = response.getWriter();
String docType =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 „ +
"Transitional//EN\">\n";
out.println(docType +
"<HTML>\n" +
"<HEAD><TITLE>ODCZYT PARAMETRÓW</TITLE></HEAD>\n" +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<UL>\n" +
" <LI><B>param1</B>: "
+ request.getParameter("param1") + "\n" +
" <LI><B>param2</B>: "
+ request.getParameter("param2") + "\n" +
" <LI><B>param3</B>: "
+ request.getParameter("param3") + "\n" +
"</UL>\n" +
"</BODY></HTML>");
public void doPost(HttpServletRequest request, HttpServletResponse response) throws } ServletException, IOException {
doGet(request, response);
} }
12
JAVA – Servlety: kod formularza
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD> <TITLE>Pobieranie wartości trzech parametrów</TITLE> </HEAD>
<BODY BGCOLOR="#FDF5E6">
<H1 ALIGN="CENTER">Pobieranie wartości trzech parametrów</H1>
<FORM ACTION="http://localhost:8080/servlet/Parametry" METHOD =POST>
Parametr pierwszy: <INPUT TYPE="TEXT" NAME="param1"><BR>
Parametr drugi: <INPUT TYPE="TEXT" NAME="param2"><BR>
Parametr trzeci: <INPUT TYPE="TEXT" NAME="param3"><BR>
<CENTER><INPUT TYPE="SUBMIT" NAME="Przycisk"
VALUE="Prześlij"></CENTER>
</FORM>
</BODY> </HTML>
13
JAVA – Servlety: Odczyt dowolnej liczby przesyłanych parametrów
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*;
public class MultiParameter extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=ISO-8859-2");
PrintWriter out = response.getWriter();
String docInit ="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +"Transitional//EN\">\n";
// elementy inicjujace dokument html <BODY> <TITLE> itp
out.println(docInit +"<TABLE BORDER=1 ALIGN=CENTER>\n" +"<TR BGCOLOR=\"#FFAD00\">\n"
+ "<TH>Nazwa parametru<TH>Wartość/wartości parametru");
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String)paramNames.nextElement();
out.print("<TR><TD>" + paramName + "\n<TD>");
String[] paramValues =
request.getParameterValues(paramName); // kilka wartości parametru // np. adres, numer karty kredytowej
if (paramValues.length == 1) {
String paramValue = paramValues[0];
if (paramValue.length() == 0)
out.println("<I>Brak danych</I>");
else out.println(paramValue);
} else { out.println("<UL>");
for(int i=0; i<paramValues.length; i++) {
out.println("<LI>" + paramValues[i]);
}out.println("</UL>");
} }out.println("</TABLE>\n</BODY></HTML>");
}
14
JAVA – Servlety: Odczyt dowolnej liczby przesyłanych parametrów: kod formularza
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>Przykładowy formularz używający metody POST</TITLE>
</HEAD>
<BODY BGCOLOR="#FDF5E6">
<H2 ALIGN="CENTER">Przykładowy formularz używający metody POST</H2>
<FORM ACTION="http://localhost:8080/servlet/Wparametry"
METHOD="POST">
Numer towaru: <INPUT TYPE="TEXT" NAME="itemNum"><BR>
Ilość: <INPUT TYPE="TEXT" NAME="quantity"><BR>
Cena jednostkowa: <INPUT TYPE="TEXT" NAME="price" VALUE="
PLN"><BR>
<HR>
Imię: <INPUT TYPE="TEXT" NAME="firstName"><BR>
Nazwisko: <INPUT TYPE="TEXT" NAME="lastName"><BR>
Inicjał 2. imienia: <INPUT TYPE="TEXT" NAME="initial"><BR>
Adres wysyłkowy:
<TEXTAREA NAME="address" ROWS=3 COLS=40></TEXTAREA><BR>
Karta kredytowa:<BR>  
<INPUT TYPE="RADIO" NAME="cardType” VALUE="Visa">Visa<BR>
<INPUT TYPE="RADIO" NAME="cardType„ VALUE="Master Card">Master Card<BR>
<INPUT TYPE="RADIO" NAME="cardType„ VALUE="Amex">American Express<BR>
<INPUT TYPE="RADIO" NAME="cardType„ VALUE="Discover">Discover<BR>
Numer karty kredytowej:
<INPUT TYPE="PASSWORD" NAME="cardNum"><BR>
Powtórz numer karty kredytowej:
<INPUT TYPE="PASSWORD" NAME="cardNum"><BR><BR>
<CENTER><INPUT TYPE="SUBMIT" VALUE="Wyślij zamówienie"></CENTER>
</FORM> </BODY> </HTML>
15
JAVA – Servlety: Odczyt dowolnej liczby przesyłanych parametrów: Formularz
16
JAVA – Servlety: odczyt nagłówków HTTP
Odczyt nagłówków z obiektu request
•getHeader(”name”)
zwraca zawartość nagłówka ”name”
•getHeaderNames
zwraca obiekt Enumeration zawierający listę nazw nagłówków w danym żądaniu
•getHeaders(”name”)
zwraca obiekt Enumeration zawierający listę wartości nagłówka ”name” jeśli w żądaniu występuje on kilka razy np. nagłówek Accept-Language
Funkcje specjalizowane
• getCookies
zwraca tablicę obiektów Cookie
• getAuthType getRemoteUser
wyciągają z nagłówka Authorization elementy składowe tego nagłówka
•getContentLength
zwraca zawartość nagłówka Content-Length jako liczbę typu int
•getContentType
zwraca zawartość nagłówka Content-Type jako obiekt typu String
•getDateHeader(”name”) getIntHeader (”name”)
funkcje odczytują zadany nagłówek i zwracają jego wartość jako obiekt typu Date bądź liczbę typu int
•Funkcje dotyczące głównego wiersza żądania
• getMethod
zwraca nazwę zastosowanej metody żądania PUT POST GET itp.
•getRequestURI
zwarac fragment adresu URL (za nazwą serwera)
•getProtocol
zwraca trzecią część wiersza żądania określającą stosowany protokół np. HTTP /1.0 HTTP /1.1
17
JAVA – Servlety: Odczyt nagłówków żądań HTTP
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
public class ShowHeaders extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=ISO-8859-2");
PrintWriter out = response.getWriter();
String title = "Prezentacja nagłówkow żądania";
String docInit ="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +"Transitional//EN\">\n";
// + inicjacja dokumentu html <Body> ><TITLE>Prezentacja nagłówków</TITLE> etc out.println( docInit +"<H1 ALIGN=CENTER>" + title + "</H1>\n" +"<B>Metoda: </B>" +
request.getMethod() + "<BR>\n" +
"<B>Żądane URI: </B>" +
request.getRequestURI() + "<BR>\n" +
"<B>Protokół: </B>" +
request.getProtocol() + "<BR><BR>\n" +
"<TABLE BORDER=1 ALIGN=CENTER>\n" +"<TR BGCOLOR=\"#FFAD00\">\n" +
"<TH>Nazwa nagłówka<TH>Wartość nagłówka");
Enumeration headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()) {
String headerName = (String)headerNames.nextElement();
out.println("<TR><TD>" + headerName);
out.println(" <TD>" + request.getHeader(headerName));
out.println("</TABLE>\n</BODY></HTML>");} }}
18
JAVA – Servlety: Ustawianie nagłówków odpowiedzi przesyłanie skompresowanej zawartości
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.zip.*;
public class CompresResponse extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=ISO-8859-2");
//przeglądarki mogące obsługiwać kompresowaną zawartość // przesyłają nagłówek żądania Accept-Encoding.
String encodings = request.getHeader("Accept-Encoding");
String encodeFlag = request.getParameter("encoding");
PrintWriter out;
String title;
if ((encodings != null) && (encodings.indexOf("gzip") != -1)
&& !"none".equals(encodeFlag))
{ title = "Strona zakodowana algorytmem GZip";
OutputStream out1 = response.getOutputStream();
out = new PrintWriter(new GZIPOutputStream(out1), false); // bez opróżniania bufora response.setHeader("Content-Encoding", "gzip");
} else {
title = "Strona w postaci niezakodowanej";
out = response.getWriter();
}
docInit ="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +"Transitional//EN\">\n";
// + inicjacja dokumentu html <Body> ><TITLE>etc out.println( docType +
String line = "Kodujemy, kodujemy .. " +
for(int i=0; i<10000; i++) { out.println(line); } out.println("</BODY></HTML>");
out.close();
}}
19
JAVA – Servlety: Prosta autoryzacja za pomocą protokołu HTTP Generowanie haseł
import java.util.*;
import java.io.*;
/** Aplikacja zapisująca na dysku prosty plik właściwości
* zawierający nazwy użytkowników oraz odpowiadające im
* hasła.
*/public class PasswordGenerator
{public static void main(String[] args) throws Exception {Properties passwords = new Properties();
// mozna by jeszcze kodować, do wstawienia użyjemy put bo Properties // dziedziczy z Hashtable
passwords.put("krzych", "2003");
passwords.put("duch", "aaaa");
// Miejsce przechowywania pliku powinno być niedostępne // z poziomu WWW.
FileOutputStream out = new FileOutputStream("c:\\plikh");
passwords.store(out, "Passwords");
} }
20
JAVA – Servlety: Prosta autoryzacja za pomocą protokołu HTTP: odczyt danych
import java.io.*; import javax.servlet.*;import javax.servlet.http.*; import java.util.Properties;
import sun.misc.BASE64Decoder;
public class PasswordServlet extends HttpServlet {private Properties hasla; private String passFile;
public void init(ServletConfig config) throws ServletException { super.init(config);
try { passFile = getInitParameter("passwordF");
hasla = new Properties()
; hasla.load(new FileInputStream(passFile));
} catch(IOException ioe) {}
}public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
response.setContentType("text/html; charset=ISO-8859-2");
PrintWriter out = response.getWriter();
String authorization = request.getHeader("Authorization");
if (authorization == null) { askForPassword(response);}
else { String userInfo = authorization.substring(6).trim();
BASE64Decoder decoder = new BASE64Decoder();
String nameAndPassword = new String(decoder.decodeBuffer(userInfo));
int index = nameAndPassword.indexOf(":");
String user = nameAndPassword.substring(0, index);
String password = nameAndPassword.substring(index+1);
String realPassword = hasla.getProperty(user);
if ((realPassword != null) && (realPassword.equals(password))) { String docType =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +"Transitional//EN\">\n";
out.println( docType + "<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H1 ALIGN=CENTER>" + "Witam na chronionej stronie"; + "</H1>\n" + "Gratuluję. Uzyskałeś dostęp do ściśle \n tajnego dokumentu.\n" +
"</BODY></HTML>");
} else {askForPassword(response); } } }
21
JAVA – Servlety: Prosta autoryzacja za pomocą
protokołu HTTP: Żądanie autoryzacji przez ustawienie nagłówka odpowiedzi
private void askForPassword(HttpServletResponse response)
{ response.setStatus(response.SC_UNAUTHORIZED); // Ie 401
response.setHeader("WWW-Authenticate", "BASIC realm=\"privileged-few\"");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}}