Fejlett Programozási Technikák 2. 14/4
A mai előadás tartalma: Szerver Oldali Programozás SSI CGI NSAPI/ISAPI FastCGI Perl Python
Szerver oldali Programozás Adatbázisok integrálása (JTS, JDBC, ODBC, EJavaBeans) Transaction Processing monitor Háttérrendszerek integrálása (LDAP, NDS, …) Elosztott, hibatűrő rendszerek (RMI, JMS, Servlet) Skálázhatóság (Többszálú, komponensekből áll, RMI, JMS,) A munkafolyamatok leképezése (EJavaBeans) Csoportmunka támogatás (struktúrálatlan adat, hosszú folyamatok, szabályok, utak, feladatok) Adatbányászat
Szerver oldali Programozás I Szkript nyelvek: Python Perl Web orientált szkript nyelvek: PHP ASP XSP JSP
Szerver oldali Programozás II. Előre fordított nyelvek: C C++ Java VisualBasic
SSI (Server Side Includes) A webszerver értelmezi a HTML fájlt .shtml kiterjesztés Egyszerű megvalósítani Erőforrásigényes Biztonsági problémákat vet fel
SSI példa <HTML> <HEAD> <TITLE>Hali!</TITLE> <BODY> <H1>A szerver neve: <!--#echo var="SERVER_NAME"-->...</H1> <HR> A te géped címe <!--#echo var="REMOTE_HOST"-->, A dátum:<!--#echo var="DATE_LOCAL"--> </BODY></HTML>
SSI parancsok sizefmt echo var config include errmsg File virtual fsize file flastmod exec cmd Cgi config errmsg sizefmt timefmt
CGI (Common Gateway Interface) HTTP (GET/POST) 1 HTTP (GET/POST) Új process 2 Új process CGI 1 CGI 1 Szabványos bemenet Szabványos bemenet Feldolgozás Feldolgozás Szabványos kimenet Szabványos kimenet
CGI Szabványos felület Gyakorlatilag bármely programozási nyelvet használhatjuk Minden szkript saját környezeti változókkal rendelkezik A környezeti változókon keresztül történik a kommunikáció Érdemes a webszerverek nyújtotta lehetőségeket kihasználni : mod_perl
Szerver specifikus változók GATEWAY_INTERFACE - a CGI verziója SERVER_NAME - a szerver IP címe vagy neve SERVER_PORT - az a port amelyen a szerver a HTTP kérést kapta. (álatlában 80-as) SERVER_PROTOCOL - a kérés kezelő protokoll neve és verziója (pl.: HTTP 1.1) SERVER_SOFTWARE - A szerver szoftver neve és verziója
Kérés specifikus környezeti változók AUTH_TYPE - az azonosítás típus ha nincs azonosítás akkor a NULL értéket veszi fel. CONTENT_FILE - az adatkat tároló fájl neve, elérési útvonala CONTENT_LENGTH - az STDIN bemenetre érkező adat hossza CONTENT_TYPE - az adat típusa OUTPUT_FILE - a kimenetet fogadó fájl (csak windows estében) PATH_INFO - relatív útvonal melyet a kérés karakterlánc elé kell illeszteni PATH_TRANSLATED - ugyanaz mint az előző csak a relatív útvonal helyett itt abszolút útvonalat használunk. QUERY_STRING - az adat mely az URL-ben a '?' karakter után következett REMOTE_ADDR - a felhasználó IP címe REMOTE_USER - a felhasználó neve ha volt azonosítás REQUEST_LINE} - a teljes HTTP kérés REQUEST_METHOD - a HTTP kérés típusa SCRIPT_NAME - a CGI neve
CGI előnyei/hátrányai egyszerű nyelv független a process-ek izolálva vannak nyitott szabvány architektúra független Hátrányai: erőforrás igény nagy állapotmentes
ISAPI/NSAPI Microsoft/Netscape dll új szálakat indít a web szerver process-en belül ISAPI szűrők alkalmazása globális változókat kerülni kell ha egy szál behal az egész web szervert újra kell indítani
Internet Information Server Az ISAPI felépítése Internet database connector perl.dll ActiveX Server applications Application APIs Perl scripts Internet Information Server CGI Simple applications Filter APIs ActiveX Server filters Web browser
ISAPI hátrányai komplex nyelvfüggő nincs process elkülönítés hozzá van kötve a web szerverhez (többszálú vagy sem)
FastCGI a process-ek állandóak egy vagy több process, több szál socket-en keresztül kommunikál a web szerverrel egyedi azonosítók az egyes kéréseknek
Fast CGI csomagok FCGI_PARAMS A név/érték párok elküldésére használják (CGI állapot változók) a web szervertől az alkalmazás felé. FCGI_STDIN A szabványos bementet küldi el a web szerver. FCGI_DATA A szűrő adatokat küldi el. FCGI_STDOUT Szabványos kimenet a webszerverhez. FCGI_STDERR Hibajelentés. FCGI_END_REQUEST Befejzés.
Szkript nyelvek Magas szintű nyelvek Interpreter szükséges Könnyű fejleszteni, módosítani Lassúak: interprter futtatás fordítá futtatás
Perl Practical Extraction and Report Language Lary Wall: Rendszer adminisztrációs feladatok megkönnyítése Szövegfájlok kezelésére optimalizált A C, awk, sed, sh legjobb tulajdonságait ötvözi A legtöbb elemet a C-ből veszi át Nem limitálja az adatok méretét (egy fájlt be tud olvasni egy karakterlácba) A rekurzió elvileg végtelen mélységű lehet Asszociatív tömböket használhatunk Fejlett mintaillesztő eszközökkel rendelkezik Bináris adatokat is tud kezelni Objektum orientált (az 5.0-ás verziótól)
A szkript futtatása: Unix esetén: Windows esetén: #!/usr/local/bin/perl print "Hello World!!!\n"; perl programnév perl –e print ”Ez már az” Windows esetén:
Alapvető szabályok A szóköz nem számít Minden utsítást ”;”-vel zárunk A megjegyzések a # karaterrel kezdődnek melynek a sor elején kell lennie Nincs blokk megjegyzés
Idézőjelek dupla idézőjel ”” – karakterláncot adunk meg melyet a perl kiértékel egyszeres idézőjel ‘’ – karakterláncot adunk meg melyet a perl nem értékel ki vissza idézőjel `` - végrehajtja az idézőjelben lévő utasítást
Példák $a = 'Alap karakterlánc $d\n'; $b = "Itt már szerepleni fog $a is\n" ; $e =`dir`; print $a; print $b; print $e; Kimenet: Alap karakterlánc $d\nItt már szerepleni fog Alap karakterlánc $d\n is A meghajtóban (F) lévő kötet User. A kötet sorozatszáma: 3C2E-080A F:\temp tartalma: 2002.02.27. 11:43 <DIR> . 2002.02.27. 11:43 <DIR> .. 2002.02.21. 18:39 <DIR> $wc
Változók A következő változótípusok vannak: Skalárok $ számok karaterek hivatkozás Tömbök @ skalárok Asszociatív tömbök % Automatikus konverzió, futás közben értékeli ki a típust.
Példa $napok= "Kedd"; # egyszerű skalár $szam = 100; $napok[3]; # napok nevű tömb negyedik eleme @napok; # az egész tömb ($napok[0], .. ,$napok[$#napok]) $napok{'Kedd'}; # napok nevű asszociatív tömb egy eleme %napok; # az egész asszociatív tömb (kulcs, érték párok) $# napok; # napok tömb utolsó indexe
Tömbök használata: @t1 = (10,24,39); @t2 = ('monitor', 'egér', "port"); $a = 1; $b = 2; $c = '3'; @t3 = ($a, $b, $c); @AoA = ( [ "fred", "barney" ], [ "george", "jane", "elroy" ], [ "homer", "marge", "bart" ], ); $AoA[0][0] = "Fred";
Asszociatív tömbök %subscripts = ( 'bmp', 'Bitmap',"cpp", "C++ Source", "txt", 'Text file' ); $bm = 'asc'; $subscripts{$bm} = 'Ascii File'; print "\n ==================== \n"; print %subscripts; print "\n =========== foreach ========= \n"; foreach $key (keys (%subscripts)) { $value = $subscripts{$key}; print "Key = $key, Value = $value \n";} print "\n === foreach sort ========= \n"; foreach $key (sort keys (%subscripts)) { print "\n =========== each() ========= \n"; while (($key,$value) = each(%subscripts)) { print "Key = $key, Value = $value \n"; }
Eredmény ==================== bmpBitmaptxtText filecppC++ SourceascAscii File =========== foreach ========= Key = bmp, Value = Bitmap Key = txt, Value = Text file Key = cpp, Value = C++ Source Key = asc, Value = Ascii File === foreach sort ========= =========== each() =========
Tömbök asszociatív tömbje %HoA = ( flintstones => [ "fred", "barney" ], jetsons => [ "george", "jane", "elroy" ], simpsons => [ "homer", "marge", "bart" ], ); foreach $family ( keys %HoA ) { print "family: "; foreach $i ( 0 .. $#{ $HoA{$family} } ) { print " $i = $HoA{$family}[$i]"; } print "\n";
Vezérlő szerkezetek I Kód blokkokat használhatunk : { utasítások } while(feltétel) { ... végrehajtja a kódot ha a feltétel igaz; until(feltétel) { … a while ellentéte ... végrehajtja a kódot amíg feltétel hamis; do { ... végrehajtja ezt legalább egyszer ... ... megáll ha feltétel igaz ... } while(feltétel);
Vezérlő szerkezetek II do { ... végrehajtja ezt legalább egyszer ... ... megáll ha feltétel hamis ... } until(feltétel); if (feltétel1) { feltétel1_kód igaz; } else { ... nincs igaz a feltétel1 és feltételN között; }
Vezérlő szerkezetek III if (feltétel1) { ... feltétel1_kód igaz; } elsif (feltétel2) { feltétel2_kód igaz; .... } elsif (feltételN) \{ feltételN_kód igaz; } else { ... nincs a feltételek között igaz; } unless (feltétel1) { ellentéte az "if" kapcsolónak. ... ha hamis akkor ezt végrehajtja;
Alprogramok bárhol deklarálhatunk függvényt az argumentumokat egy helyi tömbben kezeli (@_) visszatérési értéke a legutoljára kiértékelt kifejezés használhatjuk a return utasítást is
Példa: sub max { my $max = shift(@_); foreach $i (@_) { $max = $i if $max < $i; } return $max; $legnagyobb = max(1,2,3,4); print "A legnagyobb: $legnagyobb "
Láthatóság A blokkokban definiált változók globálisak my – helyi változókat hoz létre hívásonként melyek teljesen rejtettek a zárójeleken kívül esők számára my($a,@tomb) local - nem hoz létre új változót csak a golbális változónak ad új ideiglenes értéket
Fájltesztelés Néhány teszt operátor: -r olvasható -x futatható -e létezik -d könyvtár -t tty -T szövegfájl if ( -e "c:/teszt") { print "van"; } else { print "nincs"; }
Fájlkezelés open(kezelő,"fájl név") - megnyitja a fájlt olvasásra open(elsof,">teszt.dat") -megnyitja a fájlt írásra, ha még nem létezett létrehozza, ha már létezett megsemmisíti és létrehozza open(elsof,">>teszt.dat") – megnyitja a fájlt írásra, ha még nem létezett létrehozza, ha már létezett hozzáfűzi open(elsof,"+>teszt.dat") - megnyitja a fájlt írásra, olvasásra ha még nem létezett létrehozza
Példa: open(elsof,">test.dat"); open(masodikf,">test1.dat"); select elsof; print "Ez az elsof fájlba kerül"; select masodikf; print "Ez az masodikf fájlba kerül";
Szöveg kezelés I. $_='Us ? The bus usually waits for us, unless the driver forgets us.'; print "$_\n"; s/Us/them/; # $valami=~s/Us/them/; Us ? The bus usually waits for us, unless the driver forgets us. them ? The bus usually waits for us, unless the driver forgets us. s/Us/them/g; mindet kicserélné de case-sensitive s/Us/them/ig; mindet kicseréli azokat amelyek a szavakon belül vannak s/ us[. ,]/ them/g; azokat cseréli melyek elején szóköz a végén pont, szóköz vagy vessző van
Szöveg kezelés II. s/ us[^a-z]/ them/g; azokat cseréli amelyek elején szóköz a végén pedig nem kisbetű áll s/ us[^\w]/ them/g; csak azokat cseréli le melyek végén nem ez áll: a-zA-Z_0-9 és szóközzel kezdődnek. s/\bus\W/ them/g; ugyanaz mint az előző s/\b([Uu])s(\W)/chr(ord($1)-1).hem.$2/eg; A tökéletes megoldás Us ? The bus usually waits for us, unless the driver forgets us. Them ? The bus usually waits for them, unless the driver forgets them.
Modulok különböző láthatósági körök hordozható kód ”package” Main package A változók nevei egy asszociatív tömbben vannak tárolva ez a szombólumtábla A csomagok közötti váltás = szimbólumtábla csere csomage_neve::valtozo_neve A modulokat a @INC által megadott könyvtárakban keresi
Objektumok objektum -> referencia mely tudja, hogy melyik osztályhoz tartozik osztály -> csomag amely tudja az objektum hivatkozásokat kezelni metódus -> egy alprogram melynek első paramétere a csomag vagy osztály csak metódust lehet örökölni az öröklődés az @ISA tömbön keresztül történik amely a modulok neveit tartalmazza menet közben változtathatjuk a tömböt azaz menet közben módosíthatjuk az ősöket
Példa package A; sub new { my $self = {}; $self->{'a'} = 42; bless $self; } package B; @ISA = qw( A ); # A a B ősosztálya my $self = A->new; $self->{'b'} = 11; package main; $c = B->new; print "a = ", $c->{'a'}, "\n"; print "b = ", $c->{'b'}, "\n";
Metódusok I statikus - Az elsô paraméterében az osztály nevét kapja meg package ValamiUj; sub holvagyok { my ($neve) = @_; print "holvagyok: $neve \n"; } package main; ValamiUj->holvagyok();
Metódusok II. rendes metódus - Az elsô paraméterében egy referenciát vár package ValamiUj; sub new { my $self = {}; bless $self; $self->{elso} = 1; # ez {"elso"}-vel egyenértékü $self->{ize} = 42; return $self; } sub kiir { my $self = shift; my @keys = @_ ? @_ : sort(keys(%$self)); foreach $key (@keys) { print "\t$key => $self->{$key}\n"; use ValamiUj; $obj = ValamiUj::new(); $obj->kiir(); # C++ stílus kiir obj "elso"; # "print" stílus
Egy példa CGI kód #!/usr/bin/perl print "Content-type:text/html\n\n"; read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; } print "<html><head><title>Form Output</title></head><body>"; print "<h2>Results from FORM post</h2>\n"; foreach $key (keys(%FORM)) { print "$key = $FORM{$key}<br>"; } print "</body></html>";
Grafika megjelenítése Tőzsdei jelentés Egyedi számáló Bonyolult grafika A megoldás a dinamikusan előállított szerver oldali kép.
Dinamikus kép Dinamikus mód Nem dinamikus mód Akkor generálja le amikor a képet kéri a kliens Nem dinamikus mód Akkor generálja le amikor a képet tartalmazó oldalt kéri le a kliens <IMG SRC="/cgi-bin/calendar.pl?month=11/1995&draw_imagemap">
Kód use GD; $image = new GD::Image (100, 100); $black = $image->colorAllocate (0, 0, 0); $red = $image->colorAllocate (255, 0, 0); $month_title=”március”; $month_point = (100-(length ($month_title)*16)) / 2; $image->string (gdLargeFont, $month_point,15, $month_title, $red); print "Content-type: image/gif", "\n"; print "Pragma: no-cache", "\n\n"; print $image->gif;
Hálózatkezelés #!/usr/bin/perl -w use IO::Socket; $remote = IO::Socket::INET->new( Proto => "tcp", PeerAddr => "localhost", PeerPort => "daytime(13)", ) or die "cannot connect to daytime port at localhost"; while ( <$remote> ) { print }
Web kliens #!/usr/bin/perl -w use IO::Socket; unless (@ARGV > 1) { die "usage: $0 host document ..." } $host = shift(@ARGV); $EOL = "\015\012"; $BLANK = $EOL x 2; foreach $document ( @ARGV ) { $remote = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host, PeerPort => "http(80)", ); unless ($remote) { die "cannot connect to http daemon on $host" } $remote->autoflush(1); print $remote "GET $document HTTP/1.0" . $BLANK; while ( <$remote> ) { print } close $remote; }
Python Guido van Rossum 1989 C nyelvből származik Objektum orientált Nagy könyvtárkészlet Futtatható parancssorból és szkriptként is
Bevezető A változókat nem kell megjelölni Minden objektum identitás típus érték Az identitás és a típus nem változtatható Objektumok: mutábilis nem mutábilis Konténer típus: referenciát tartalmaz másik objektumra (lista, vektor, …)
Változók (számok) Szám egész lebegőpontos komplex >>> 1j * 1J (-1+0j) >>> 1j * complex(0,1) >>> 3+1j*3 (3+3j) >>>(3+1j)*3 (9+3j) >>> a=1.5+0.5j >>> a.real 1.5 >>> a.imag 0.5
Változók (Sorozat) Sorozat (Sequence) -- Véges természetes számokkal indexelt rendezett halmazok reprezentációja >>> a = [66.6, 333, 333, 1, 1234.5] >>> a[1:3] [333, 333] >>> a.sort() >>> a [1, 66.599999999999994, 333, 333, 1234.5]
Változók (String ) String (nem módosítható) Létrehozás után az objektum nem változhat. >>> s = "valami" >>> s= "más" >>> s 'm\xe1s' >>> s[1] '\xe1' >>> s[1]="2" Traceback (most recent call last): File "<pyshell#17>", line 1, in ? s[1]="2" TypeError: object doesn't support item assignment
Változók (Vektor ) Vektor (nem módosítható) Egy vektor elemei tetszőleges Python objektumok lehetnek. >>> vektor ='a','w','23',34 >>> vektor[3] 34 >>> vektor[1:114] ('w', '23', 34) >>> vektor2=1,2,3,4,'sasda' >>> vektor,vektor2=vektor2,vektor >>> vektor (1, 2, 3, 4, 'sasda')
Változók (Lista ) >>> lista=[1,"123",[1,2,3,"elem"]] >>> lista [1, "123", [1, 2, 3, "elem"]] >>> 1 in lista 1 >>> for a in lista: print a 123 [1, 2, 3, "elem"] >>> a = [1, 2, 3] >>> b = [4, 5, 6] >>> c = a + b >>> print c [1, 2, 3, 4, 5, 6] >>> lista[1]="3234234" >>> del lista[2] [1, '3234234'] Egy lista elemei tetszőleges Python objektumok lehetnek. Módosítható.
Leképezések (Szótár ) Kulcsként csak olyan típusértékek jöhetnek szóba, melyek objektum identitás alapján hasonlítódnak össze és nem érték alapján (nem módosíthatóak). A szótár módosítható (mutable) >>> szotar={"egy":"one","ketto":"two","harom":"three"} >>> szotar {'egy': 'one', 'harom': 'three', 'ketto': 'two'} >>> szotar["ketto"] 'two' >>> szotar.keys() ['egy', 'harom', 'ketto'] >>> szotar.values() ['one', 'three', 'two'] >>> szotar.items() [('egy', 'one'), ('harom', 'three'), ('ketto', 'two')]
Vezérlő szerkezetek While: while kifejezés : utasítás For: if feltétel: utasítás ha igaz else: utasítás ha hamis if 1feltétel: ha 1feltétel igaz elif 2feltétel: ha 2feltétel igaz, 1feltétel hamis elif 3feltétel: ha 3feltétel igaz,2feltétel,1feltétel hamis ha 3feltétel,2feltétel,1feltétel hamis While: while kifejezés : utasítás For: for 1kifejezés in 2kifejezés : parancs
Fájlkezelés open(fájlnév,mód) read(méret) r- olvasásra nyitja meg a fájlt w- írásra nyitja meg a fájlt, ha már létezik a fájl akkor törlődik a- hozzáfűzére nyitja meg a fájlt, az adatok automatikusan a végére íródnak r+ - írásra, olvasásra nyitja meg a fájlt read(méret) readline() – sorokat olvas be readlines() - beolvassa a fájl sorait egy listába write(karakterlánc) close()
Példa >>> f=open("pelda.dat","w") >>> f.write("1. sor \n") >>> f.write("2. sor \n") >>> f.close() >>> f=open("pelda.dat","r") >>> a=f.readlines() >>> a ['1. sor \n', '2. sor \n']
Függvények def név paraméterlista törzs A változók egy új szimbólumtáblába lesznek eltárolva return
Példa def fib(n): a,b=0,1 while b<n: print b, a,b=b,a+b 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
Modulok, csomagok Logikailag összefüggő részek A modul neve a tartalmazó fájl neve import - teljes modult importál from ”modul” import ”mit”- csak a kért függvényt improtálja PYTHONPATH környezeti változó
Példa: Az előző példa el lett mentve a fibo.py fájlba import fibo >>> fibo.fib(100) 1 1 2 3 5 8 13 21 34 55 89
Objektum orientált programozás Többszörös öröklés Metódus felülírás Nincs konstruktor Nincs destruktor A vezérlésnek előbb rá kell futnia az osztálydefinícióra Az osztálydefiníció végén automatikusan létrejön az osztály objektum Az adat atribútumok az első használatukkor jönnek létre
Példa: class Pelda: a=0 def f(x) print "--A metódus—” x = Pelda x.ujv = 1 while x.ujv < 10: x.ujv = x.ujv * 2 print x.ujv del x.ujv
Példa class SzOsztaly(mname.Base1,mname.Base2,...) ha egy hivatkozást nem talál base1-ben akkor az őseiben kezdi keresni ha ott sem akkor base2 …