Systemy operacyjne na platformach mobilnych



Podobne dokumenty
akademia androida Http i AsyncTask część VII

Tworzenie i wykorzystanie usług

Programowanie w języku Java

JAVA I SIECI. MATERIAŁY:

Systemy operacyjne na platformach mobilnych

akademia androida Składowanie danych część VI

Wykorzystywanie parsera DOM w programach Java i PL/SQL

JAVA I XML ZAGADNIENIA: DOM, SAX, JAXB, XMLDecoder i XMLEncoder, ANT.

Platformy Programistyczne Zagadnienia sieciowe i wątki

Komunikacja z użyciem gniazd aplikacje klient-serwer

RESTful Android. Na co zwrócić uwagę przy tworzeniu aplikacji klienckich REST na Androidzie

Programy typu klient serwer. Programowanie w środowisku rozproszonym. Wykład 5.

Java programowanie w sieci. java.net RMI

Wybrane działy Informatyki Stosowanej

Wywoływanie metod zdalnych

Programowanie współbieżne i rozproszone

Remote Method Invocation 17 listopada 2010

Aplikacja wielowątkowa prosty komunikator

Remote Method Invocation 17 listopada Dariusz Wawrzyniak (IIPP) 1

Podejście obiektowe do budowy systemów rozproszonych

Wywoływanie metod zdalnych

SOAP. Autor: Piotr Sobczak

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1

Zaawansowane aplikacje WWW - laboratorium

Przykłady interfejsu TCP i UDP w Javie

Podejście obiektowe do budowy systemów rozproszonych

Java RMI. Dariusz Wawrzyniak 1. Podejście obiektowe do budowy systemów rozproszonych. obiekt. interfejs. kliencka. sieć

Java RMI. Dariusz Wawrzyniak 1. Podejście obiektowe do budowy systemów rozproszonych. obiekt. interfejs. kliencka. sieć

HttpRequest Aplikacja Czat

Remote Method Invocation 17 listopada rozproszonych. Dariusz Wawrzyniak (IIPP) 1

akademia androida Service, BroadcastReceiver, ContentProvider część IV

XML i Java. Technologie zarządzania treścią. dr inż. Robert Perliński rperlinski@icis.pcz.pl

Forum Client - Spring in Swing

Badania poziomu bezpieczeństwa portalu dostępowego do infrastruktury projektu PL-Grid

Aplikacje RMI

Programowanie urządzeń mobilnych. projekt 6 ( )

Obsługa SMS i telefonii

Programowanie obiektowe

Programowanie rozproszone w języku Java

Dzisiejszy wykład. Wzorce projektowe. Visitor Client-Server Factory Singleton

Oprogramowanie i wykorzystanie stacji roboczych. Wykład 4

Aplikacja wielow tkowa prosty komunikator

MeetingHelper. Aplikacja Android ułatwiająca przekazywanie materiałów pomiędzy uczestnikami spotkania. Instrukcja obsługi dla programisty

Wprowadzenie do technologii Web Services: SOAP, WSDL i UDDI

Serwer współbieżny połączeniowy

Java. Wykład. Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ

Programowanie urządzeń mobilnych. dr inż. Andrzej Grosser na podstawie wykładu dr inż. Juliusz Mikoda

JAVA. Strumienie wejścia i wyjścia. Pliki - zapis i odczyt

Proxy (pełnomocnik) Cel: Zastosowanie: Dostarczyć zamiennik pewnego obiektu, pozwalający kontrolować dostęp do niego.

akademia androida Intencje oraz URI część III

Wzorce prezentacji internetowych

Intencje nadawcze. Aktywności mogą rozsyłać komunikaty do wszystkich zainstalowanych aplikacji

Współbieżność w środowisku Java

Podstawy XML-a. Zaawansowane techniki programowania

Język JAVA podstawy. Wykład 6, część 2. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Łukasz Przywarty Wrocław, r. Grupa: WT/N 11:15-14:00. Sprawozdanie z zajęć laboratoryjnych: OpenSSL - API

Narzędzia i aplikacje Java EE. Usługi sieciowe Paweł Czarnul pczarnul@eti.pg.gda.pl

KOMUNIKACJA MIĘDZYPROCESOWA O B S Ł U G A WEJŚCIA/WYJŚCIA

Wątek - definicja. Wykorzystanie kilku rdzeni procesora jednocześnie Zrównoleglenie obliczeń Jednoczesna obsługa ekranu i procesu obliczeniowego

K O M U N I K A C J A MIĘDZYPROCESOWA O B S Ł U G A WEJŚCIA/WYJŚCIA

XML we własnych aplikacjach

Fragmenty są wspierane od Androida 1.6

PHP. Tematyka wykładów: Język PHP PHP i bazy danych Rozszerzenia PHP

Wprowadzenie db4o - podstawy db4o - technikalia Przydatne wiadomości. Wprowadzenie. db4o. Norbert Potocki. 1 czerwca Norbert Potocki db4o

Strumienie i serializacja

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Instrukcja implementacji sterownika wirtualnego portu szeregowego dla systemu Android. Opracowanie: Elzab Soft sp. z o.o.

Projektowanie Aplikacji Internetowych. Wzorce projektowe warstwy usług

Gatesms.eu Mobilne Rozwiązania dla biznesu

Aplikacje RMI Lab4

Programowanie telefonów z Windows Phone 7, cz. 4

Instytut Sterowania i Systemów Informatycznych Uniwersytet Zielonogórski. Zaawansowane Systemy Decyzyjne. Laboratorium

Wieloplatformowe aplikacje sieciowe. dr inż. Juliusz Mikoda mgr inż. Anna Wawszczak

Komponenty sterowane komunikatami

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Realizacja Aplikacji Internetowych 2013 laboratorium cz. 2 K.M. Ocetkiewicz

1. Co będzie wynikiem wykonania poniŝszych instrukcji? g2d.gettransform().scale(1, -1); g2d.gettransform().translate(4, -8); g2d.drawline(4, 0, 4, 4);

Multimedia JAVA. Historia

Aplikacje RMI. Budowa aplikacji rozproszonych. Część 2.

Zadanie 2: transakcyjny protokół SKJ (2015)

Android, wprowadzenie do SDK

PHP 5 język obiektowy

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

Rozproszone systemy internetowe. Wprowadzenie. Koncepcja zdalnego wywołania procedury

Zaawansowane aplikacje internetowe laboratorium REST

Programowanie w Sieci Internet JSP ciąg dalszy. Kraków, 9 stycznia 2015 r. mgr Piotr Rytko Wydział Matematyki i Informatyki

Kurs języka Python Wykład 8. Przetwarzanie tekstu Wyrażenia regularne Biblioteka urllib Parsowanie html'a XML

Java. Programowanie Obiektowe Mateusz Cicheński

Programowanie w Internecie

Architektury Usług Internetowych. Laboratorium 5

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

Dokumentacja techniczna API systemu SimPay.pl

Aplikacje internetowe i rozproszone - laboratorium

Dokumentacja techniczna

Aplikacje Internetowe. Najprostsza aplikacja. Komponenty Javy. Podstawy języka Java

Laboratorium 1. Wzorce oprogramowania lab1, Zofia Kruczkiewicz

PHP: bloki kodu, tablice, obiekty i formularze

Transkrypt:

Systemy operacyjne na platformach mobilnych Wykład 4 Grzegorz Jabłoński, Piotr Perek Katedra Mikroelektroniki i Technik Informatycznych

Zagadnienia wykładu Menadżer połączeń Usługi HTTP Klient HTTP Żądanie Odpowiedź Realizacja żądania (GET/POST) Obsługa wyjątków Klienci Zadania drugoplanowe Obsługa plików XML 2

Menadżer połączeń Klasa ConnnectivityManager służy do zarządzania łączami sieciowymi Podstawowe zadania tej klasy to: Monitorowanie połączeń sieciowych (Wi-Fi, GPRS, UMTS itp.) Wysyłanie intencji broadcastowych, gdy nastąpią zmiany z połączeniami sieciowymi Próba "fail-over" do innej sieci, gdy połączenie z siecią jest stracone Dostarczenie interfejsu API, który pozwoli aplikacjom na sprawdzenie stanu dostępnych sieci 3

Sprawdzenie stanu sieci public void onstart() { super.onstart(); ConnectivityManager cmgr = (ConnectivityManager) this.getsystemservice(context.connectivity_service); NetworkInfo netinfo = cmgr.getactivenetworkinfo(); if(info!= null && info.isconnected()) { return true; 4

Klient HTTP SDK Androida dostarcza zmodyfikowaną wersję klienta HTTP fundacji Apache: org.apache.http.client.httpclient (API podobne do używanego w aplikacjach JEE) Ogólny wzorzec wykorzystania klienta HTTP: utworzenie/uzyskanie instancji HttpClient utworzenie instancji metody HTTP (GetMethod lub PostMethod) ustawienie parametrów HTTP wysłanie żądania HTTP (z użyciem HttpClient) przetworzenie odpowiedzi HTTP 5

AndroidManifest.xml Aby aplikacja mogła uzyskać dostęp do informacji o połączeniach sieciowych należy dodać do pliku AndroidManifest.xml pozwolenie android.permission.access_network_state Korzystanie z Internetu wymaga dodania do pliku AndroidManifest.xml pozwolenia android.permission.internet 6

Gniazdo serwera TCP ServerSocket server = new ServerSocket(PORT, 1); while(true) { Socket client = server.accept(); System.out.println("Client connected"); while(true) { BufferedReader reader = new BufferedReader(new InputStreamReader( client.getinputstream())); System.out.println("Read from client"); String textline = reader.readline() + "\n"; 7

Gniazdo serwera TCP if(textline.equalsignorecase("exit\n")) { System.out.println("EXIT invoked, closing client"); break; BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(client.getOutputStream())); System.out.println("Echo input to client"); writer.write("echo from server: "+ textline,0,textline.length()+18); writer.flush(); client.close(); 8

Gniazdo klienta String output = callsocket( ipaddress.gettext().tostring(), port.gettext().tostring(), socketinput.gettext().tostring() ); private String callsocket(string ip, String port, String socketdata) { Socket socket = null; BufferedWriter writer = null; BufferedReader reader = null; String output = null; try{ socket = new Socket(ip, Integer.parseInt(port)); writer = new BufferedWriter(new OutputStreamWriter( socket.getoutputstream())); 9

Gniazdo klienta reader = new BufferedReader(new InputStreamReader( socket.getinputstream())); String input = socketdata; writer.write(input + "\n", 0, input.length() + 1); writer.flush(); output = reader.readline(); socketoutput.settext(output); // send EXIT and close writer.write("exit\n", 0, 5); writer.flush(); // catches and reader, writer, and socket closes omitted for brevity // oncreate omitted for brevity return output; 10

Proste żądanie HTTP String output = gethttpresponse( www.google.pl ); private String gethttpresponse(string location) { String result = null; URL url = null; try { url = new URL(location); catch(malformedurlexception e) { // log and or handle 11

Proste żądanie HTTP if(url!= null) { try { HttpURLConnection urlconn = (HttpURLConnection)url.openConnection(); BufferedReader in = new BufferedReader( new InputStreamReader(urlConn.getInputStream())); String inputline; int linecount = 0; // limit lines for example while((linecount < 10) && ((inputline = in.readline())!= null)){ linecount++; result += "\n" + inputline; in.close(); urlconn.disconnect(); catch(ioexception e) { /* log and or handle */ else { /* log and or handle */ return result; 12

Klient HTTP Domyślną implementacją interfejsu HttpClient jest klasa org.apache.http.impl.client.defaulthttpclient Utworzenie instancji klienta: HttpClient client = new DefaultHttpClient(); Poprzez konstruktor można także podać: menedżera połączenia org.apache.http.conn.client- ConnectionManager nagłówki HTTP org.apache.http.params.httpparams 13

Żądanie HTTP Żądanie HTTP jest reprezentowane przez interfejs org.apache.http.httprequest Interfejs org.apache.http.client.methods.httpurirequest dziedziczy po interfejsie HttpRequest dostarczając metod użytkowych, m.in.: public String getmethod() //nazwa metody, której używa żądanie public URI geturi() //URI, którego żądanie używa Implementacjami tego interfejsu są m.in. klasy (odpowiadające metodom protokołu HTTP): HttpGet, HttpHead, HttpPost, HttpDelete, HttpPut, HttpTrace, HttpOptions 14

Odpowiedź HTTP Odpowiedź HTTP jest reprezentowana przez interfejs org.apache.http.httpresponse Metoda getentity() umożliwia dostęp do treści odpowiedzi przesłanej przez serwer Obiekt typu HttpResponse jest zwracany jako wynik metody execute() klienta HTTP. 15

Żądanie typu GET Przeznaczone głównie do odbierania danych Parametry żądania podawane jawnie w adresie Długość zapytania ograniczona do 2048 znaków Przykład wysłania żądania typu GET: HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet("http://www.abc.pl/?sub=addd"); HttpResponse response = client.execute(request); 16

Żądanie typu POST Umożliwia przekazywanie danych do serwera zarówno w postaci parametrów tekstowych, jak i plików binarnych Parametry żądania przesyłane w formie niejawnej Brak ograniczeń w długości żądania Przykład wysłania żądania typu POST: HttpClient client = new DefaultHttpClient(); HttpPost request = new HttpPost("http://www.abc.pl/android/"); List<NameValuePair> postparams = new ArrayList<NameValuePair>(); postparams.add(new BasicNameValuePair("param1", "val1")); postparams.add(new BasicNameValuePair("param2", "val2")); UrlEncodedFormEntity formentity = new UrlEncodedFormEntity(postParams); request.setentity(formentity); HttpResponse response = client.execute(request); 17

AndroidHttpClient Klasa android.net.http.androidhttpclient implementuje interfejs HttpClient i ułatwia tworzenie klienta HTTP Klasa dostarcza ustawień domyślnych oraz dodatkowej logiki dostosowanej do aplikacji Androida, m.in.: timeout y (dla connection i socket) ustawione na 20 s domyślny menedżer połączenia: ThreadSafeClient- ConnManager Uzyskanie klienta metodą fabrykującą: AndroidHttpClient httpclient = AndroidHttpClient.newInstance("my-http-agent-string"); 18

Użycie klienta AndroidHttpClient Wywołanie metody execute() musi nastąpić w wątku innym niż wątek główny UI Po zakończeniu połączenia należy na kliencie wywołać metodę close(), w celu poprawnego zwolnienia pamięci Klient dostarcza metody umożliwiające kompresję danych przed ich wysłaniem: static AbstractHttpEntity getcompressedentity(byte[] data, ContentResolver res) static longgetmingzipsize(contentresolver resolver) static InputStream getungzippedcontent(httpentity entity) static void modifyrequesttoacceptgzipresponse(httprequest request) 19

Zadania drugoplanowe Czasochłonne zadania (np. czysto obliczeniowe) należy wykonywać w osobnym wątku można wykorzystać do tego celu klasę Thread To podejście nie sprawdzi się, jeżeli w trakcie lub po zakończeniu zadania trzeba będzie uaktualnić UI Aktualizacja interfejsu użytkownika nie jest bezpieczna wielowątkowo i musi być wykonywana tylko z wątku głównego 20

AsyncTask Abstrakcyjna klasa generyczna android.os.asynctask<params, Progress, Result> ułatwia realizację zadań asynchronicznych poprzez wyraźną separację zadania wykonywanego w tle (w wątku roboczym) i wyników, które aktualizują interfejs użytkownika (w wątku głównym UI) Typy generyczne wykorzystywane w klasie Params typ parametrów przekazywanych do zadania Progress typ wyników pośrednich publikowanych w trakcie pracy w tle Result typ wyniku zadań wykonywanych w tle jeśli dany typ nie jest używany, należy użyć typu void 21

Cykl życia zadań drugoplanowych Cykl życia zadań drugoplanowych jest ściśle związany z wywoływaniem odpowiednich metod klasy AsyncTask protected void onpreexecute(); Wywoływana w wątku głównym UI, bezpośrednio po uruchomieniu zadania Wykorzystywana zwykle do inicjalizacji zadania, np. wyświetlenia paska postępu 22

Cykl życia zadań drugoplanowych protected abstract Result doinbackground(params... params); protected final void publishprogress(progress... values); Metoda doinbackground() jest wywoływana w wątku roboczym, po zakończeniu metody onpreexecute() Wykorzystywana do wykonywania czasochłonnych obliczeń w tle Może przyjąć parametry wejściowe i zwrócić wynik (przekazywany do następnej fazy) W metodzie doinbackground() można wywołać metodę publishprogress() spowoduje to wywołanie zwrotne do UI umożliwiające publikację wyników pośrednich 23

Cykl życia zadań drugoplanowych protected void onprogressupdate(progress... values); Jest wywoływana w wątku głównym UI, w odpowiedzi na wywołanie metody publishprogress() Wykorzystywana do aktualizacji stanu interfejsu użytkownika bez przerywania zadania trwającego w tle Dokładny moment wywołania metody nie jest określony 24

Cykl życia zadań drugoplanowych protected void onpostexecute(result result); Jest wywoływana w wątku głównym UI, po zakończeniu obliczeń w tle Wynik obliczeń jest przekazywany jako parametr 25

Uruchamianie zadań drugoplanowych Instancję zadania (typu AsyncTask) należy utworzyć w wątku głównym UI Metodę execute() trzeba wywołać w wątku głównym UI Nie należy samodzielnie wywoływać metod: onpreexecute(), onpostexecute(), doinbackground(), onprogressupdate() Zadanie można uruchomić tylko raz (kolejne uruchomienie spowoduje zgłoszenie wyjątku) DownloadTask task = new DownloadTask(DownloadActivity.this); String url = urlfield.gettext().tostring(); String filename = filenamefield.gettext().tostring(); task.execute(url, filename, "GET"); 26

Przerywanie zadań drugoplanowych Zadanie może być przerwane w każdym momencie poprzez wywołanie metody cancel() Wywołanie metody cancel() spowoduje wywołanie metody oncancelled() zamiast onpostexecute() po wyjściu z doinbackground() Informację o tym czy została wywołana metoda cancel() i wątek powinien być anulowany można pobrać korzystając z metody iscancelled() Metoda iscancelled() powinna być periodycznie wywoływana z doinbackground() w celu sprawdzenia, czy zadanie ma być zakończone 27

AsyncTask - przykład public class DownloadTask extends AsyncTask<String, Integer, String> { private Context ctx; private ProgressDialog dialog; private TextView message; DownloadTask(Context ctx) { this.ctx = ctx; protected void onpreexecute() { super.onpreexecute(); message = (TextView) ((Activity) ctx).findviewbyid(r.id.result); message.settext(""); dialog = new ProgressDialog(ctx); dialog.setmessage("downloading file..."); dialog.setcancelable(false); dialog.setindeterminate(false); dialog.setmax(100); dialog.setprogressstyle(progressdialog.style_horizontal); dialog.show(); 28

AsyncTask - przykład protected String doinbackground(string... params) { return downloadfile(params); protected void onprogressupdate(integer... values) { super.onprogressupdate(values); dialog.setprogress(values[0]); protected void onpostexecute(string result) { super.onpostexecute(result); dialog.dismiss(); message.settext(result); 29

AsyncTask - przykład public String downloadfile(string... params) { String path = params[0]; String filename = params[1]; String method = params[2]; int count; String result = ""; try{ OutputStream output = new FileOutputStream("/sdcard/" + filename); HttpClient client = new DefaultHttpClient(); HttpResponse response = null; if("get".equals(method)) { HttpGet request = new HttpGet(path + "?file=" + filename); response = client.execute(request); else if("post".equals(method)) { HttpPost request = new HttpPost(path); List<NameValuePair> postparams = new ArrayList<NameValuePair>(); postparams.add(new BasicNameValuePair("file", filename)); UrlEncodedFormEntity formentity = new UrlEncodedFormEntity( postparams); request.setentity(formentity); response = client.execute(request); 30

AsyncTask - przykład HttpEntity entity = response.getentity(); InputStream input = entity.getcontent(); int datalength = (int) entity.getcontentlength(); byte data[] = new byte[1024]; long total = 0; while((count = input.read(data))!= -1) { total += count; int currentprogress = (int) (total * 100 / datalength); publishprogress(currentprogress); output.write(data, 0, count); output.flush(); output.close(); input.close(); result = "Download of " + filename + " finished... \n(" + total + "B of " + datalength + "B)"; catch(exception e) { result = "Download of " + filename + " failed"; return result; ; 31

Obsługa plików XML W Androidzie istnieje kilka różnych parserów dla plików XML np.: XmlPullParser DOM SAX 32

XmlPullParser Rekomendowany jako najwydajniesze rozwiązanie do parsowania plików XML Sposoby tworzenia parsera: xmlpullparser parser = Xml.newPullParser(); XmlPullParserFactory pullparserfactory; try { pullparserfactory = XmlPullParserFactory.newInstance(); XmlPullParser parser = pullparserfactory.newpullparser(); catch (XmlPullParserException e) { e.printstacktrace(); 33

Przykład <?xml version="1.0" encoding="utf-8"?> <products> <product> <productname>jeans</productname> <productcolor>red</productcolor> <productquantity>5</productquantity> </product> <product> <productname>tshirt</productname> <productcolor>blue</productcolor> <productquantity>3</productquantity> </product> <product> <productname>shorts</productname> <productcolor>green</productcolor> <productquantity>4</productquantity> </product> </products> 34

XmlPullParser - parsowanie private void parsexml(xmlpullparser parser) throws XmlPullParserException,IOException { ArrayList<product> products = null; int eventtype = parser.geteventtype(); Product currentproduct = null; while(eventtype!= XmlPullParser.END_DOCUMENT){ String name = null; switch (eventtype){ case XmlPullParser.START_DOCUMENT: products = new ArrayList(); break; 35

XmlPullParser - parsowanie case XmlPullParser.START_TAG: name = parser.getname(); if (name == "product"){ currentproduct = new Product(); else if (currentproduct!= null){ if (name == "productname"){ currentproduct.name = parser.nexttext(); else if (name == "productcolor"){ currentproduct.color = parser.nexttext(); else if (name == "productquantity"){ currentproduct.quantity= parser.nexttext(); break; 36

XmlPullParser - parsowanie case XmlPullParser.END_TAG: name = parser.getname(); if(name.equalsignorecase("product") && currentproduct!= null) { products.add(currentproduct); eventtype = parser.next(); printproducts(products); 37

DOM parser Zgodny z modelem DOM (Document Object Model) Działanie identyczne jak w przypadku Javy Tworzenie parsera: DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newdocumentbuilder(); InputSource is = new InputSource(); is.setcharacterstream(new StringReader(xml)); Document doc = db.parse(is); 38

DOM - parsowanie NodeList nl = doc.getelementsbytagname("product"); // looping through all item nodes <"product"> for (int i = 0; i < nl.getlength(); i++) { currentproduct = new Product(); Element e = (Element) nl.item(i); currentproduct.name = parser.getvalue(e, "productname"); currentproduct.color = parser.getvalue(e, "productcolor"); currentproduct.quantity = parser.getvalue(e, "productquantity"); products.add(currentproduct); 39

DOM - parsowanie public String getvalue(element item, String str) { NodeList n = item.getelementsbytagname(str); return this.getelementvalue(n.item(0)); public final String getelementvalue( Node elem ) { Node child; if( elem!= null){ if (elem.haschildnodes()){ for( child = elem.getfirstchild(); child!= null; child = child.getnextsibling() ){ if( child.getnodetype() == Node.TEXT_NODE ){ return child.getnodevalue(); return ""; 40

SAX parser Implementacja identyczna jak w języku Java Alternatywa dla DOM, działa w oparciu o mechanizm SAX (Simple API for XML) Tworzenie parsera: // create a XMLReader from SAXParser XMLReader xmlreader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); // create a SAXXMLHandler SAXXMLHandler saxhandler = new SAXXMLHandler(); // store handler in XMLReader xmlreader.setcontenthandler(saxhandler); // the process starts xmlreader.parse(new InputSource(is)); 41

SAX Handler public class SAXXMLHandler extends DefaultHandler { private List<Product> products; private String tempval; private Product tempproduct; public SAXXMLHandler() { products = new ArrayList<Product>(); public List<Product> getproducts() { return products; // Event Handlers public void startelement(string uri, String localname, String qname, Attributes attributes) throws SAXException { // reset tempval = ""; if (qname.equalsignorecase( product")) { // create a new instance of product tempproduct = new Product(); 42

SAX Handler public void characters(char[] ch, int start, int length) throws SAXException { tempval = new String(ch, start, length); public void endelement(string uri, String localname, String qname) throws SAXException { if (qname.equalsignorecase("product")) { // add it to the list product.add(tempproduct); else if (qname.equalsignorecase("productname")) { currentproduct.name = tempval; else if (qname.equalsignorecase("productcolor")) { currentproduct.color = tempval; else if (qname.equalsignorecase("productquantity")) { currentproduct.quantity = tempval; 43