Fejlett Programozási Technikák 2.

Slides:



Advertisements
Hasonló előadás
4. alkalom – Hálózat Kezelés
Advertisements

Osztály leszármaztatás
© Kozsik Tamás Adatbáziskezelés •Relációs adatbáziskezelők •Noha a Java objektum-elvű, egyelőre nem az objektum-elvű adatbáziskezelőket támogatja.
Programozás III STRING-XML.
Felhasználói felületek és üzleti logika Bollobás Dávid ASP.NET
Adatbázisok SQL. TARTALOM Szijártó M.2 Témakörök  Az SQL tulajdonságai  A műveletek fajtái  Objektum-műveletek  Lekérdezések Tulajdonságok és műveletek.
Felhasználói felületek és üzleti logika Bollobás Dávid ASP.NET
© Kozsik Tamás Szervletek „Kis szerverprogram” Kliens-szerver architektúrát feltételezünk Szerveroldalon futó kisalkalmazás Mint ahogy az applet.
Adatbányászati technikák (VISZM185)
© Kozsik Tamás Beágyazott osztályok A blokkstrukturáltság támogatása –Eddig: egymásba ágyazható blokk utasítások Osztálydefiníciók is egymásba.
Bevezetés a Java programozásba
Fájlkezelés, IO Kivételkezelés Belső osztályok
1 Fejlett Programozási Technikák 2. 15/9. Fejlett Programozási Technológiák 2. 2 Az előző mai előadás tartalma: Számítógépes biztonság Jáva és a biztonság.
Programozás II. 3. Gyakorlat C++ alapok.
1 Fejlett Programozási Technikák 2. 15/7. Fejlett Programozási Technológiák 2. 2 Az előző előadás tartalma: JFC és Swing  Múlt  Felépítés  Java Bean.
Fejlett Programozási Technológiák II. Világos Zsolt 1. gyakorlat.
Fejlett Programozási Technológiák II. Világos Zsolt 7. gyakorlat.
Tömbök ismétlés Osztályok Java-ban Garbage collection
A CLIPS keretrendszer CLIPS "C" Language Integration Production System.
Készítette: Sárközi Anikó
A Java programozási nyelvSoós Sándor 1/20 Java programozási nyelv 11. rész – Adatbázis-programozás Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai.
Adatbázis-kezelés ACCESS program:
WEB Technológiák Dr. Pance Miklós – Kolcza Gábor Miskolci Egyetem.
C# tagfüggvények.
JSP és JavaBean JavaServer Pages és Java Beans Fabók Zsolt Általános Informatikai Tanszék Miskolci Egyetem.
C# tagfüggvények.
Szombathely Dinamikus WEB programozás: PHP és JSP.
SOAP alapismeretek A SOAP egy egyszerű XML alapú protokoll, ami lehetővé teszi, hogy az alkalmazások információt cseréljenek a HTTP-én keresztül. Forrás:
WEB Technológiák ISAPI ME Általános Informatikai Tsz. dr. Kovács László.
WEB MES (webes gyártásirányító rendszer)
PHP I. Alapok. Mi a PHP? PHP Hypertext Preprocessor Szkriptnyelv –Egyszerű, gyors fejlesztés –Nincs fordítás (csak értelmező) Alkalmazási lehetőségek:
Appletek és Servletek Demeter Lehel 641-es csoport.
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
Felhasználók és jogosultságok
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
Készítette: Lipp Marcell
APEX BMF, II. félév.
3. előadás.  Apache szerver tudnivalók  Az index.php .htaccess – web-szerverünk beállításai  Konfigurációs állományok  Adatbázis kapcsolódás beállítása.
Web Architecture. Development of Computing Architectures Monolithic mainframe programming Client Server Real Client Server Web Programming.
Java programozási nyelv Filekezelés
Java programozási nyelv Metódusok
Komoróczy Tamás 1 Java programozási nyelv A nyelv alapjai.
A gyakorlatok munkakörnyezete
Web fejlesztés V. Illés Zoltán ELTE Informatikai Kar
Java web programozás 11..
Webprogramozó tanfolyam
Automatizálási folyamatok az SQL 2012-ben
Webprogramozó tanfolyam
A Visual Basic nyelvi elemei
HTML ÉS PHP (Nagyon) rövid áttekintés. ADATBÁZISRENDSZEREK MŰKÖDÉSI SÉMÁJA Felh. interakció DB Connector MySQL ? A gyakorlaton:
Illés Zoltán ELTE Informatikai Kar
Java web programozás 7-8..
Webes MES keretrendszer fejlesztése Kiss Miklós Dániel G-5S8 Tervezésvezető: Dr. Hornyák Olivér.
Java web programozás 5..
Java web programozás 6..
Opencms modul fejlesztés Krizsán Zoltán. Modulok fajtái Nincs előírás, csak tipikus tennivalók: –Content type: új típus(oka)t vezet be. –Template: új.
TÁMOP /1-2F JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam Osztályok, objektumok definiálása és alkalmazása. Saját.
Programozás III JPA.
Miskolci Egyetem Alkalmazott Informatikai Tanszék 2007
JDBC.
Párhuzamos programozás
Alkalmazásfejlesztés gyakorlat
Adatbázis használat a webszervernél
A CLIPS keretrendszer
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
Fejlett Programozási Technikák 2.
Fejlett Programozási Technikák 2.
Előadás másolata:

Fejlett Programozási Technikák 2. 14/9

A mai előadás tartalma: Java Applet Felépítése Tulajdonságai Paraméterátadás JDBC Java Servlet Környezet Tomcat 4.0 server.xml web.xml

Java Applet Kliens oldalon fut Beágyazható a HTML-be Az APPLET elemmel lehet beágyazni Akkor célszerű használni, ha nincs egyszerűbb megoldás (titkosítás, táblázat, nyomtatás) Korlátozottabb mint a Java alklamazás

Alapok Az Applet osztályból származtatandó amennyiben AWT elemeket szeretnénk használni A JApplet osztályból származtatandó amennyiben Swing elemeket is szeretnénk használni

Példa import javax.swing.*; import java.awt.*; public class HelloWorld extends JApplet { JLabel label; String szoveg; public void start() { szoveg = szoveg + " - " + "Start"; label.setText(szoveg); } public void stop() { szoveg = szoveg + " - " + "Stop"; public void destroy() { szoveg = szoveg + " - " + "Destroy"; public void init() { szoveg = new String("Init"); label = new JLabel(szoveg); label.setHorizontalAlignment(JLabel.CENTER); label.setBorder(BorderFactory.createMatteBorder(1,1,2,2,Color.black)); getContentPane().add(label, BorderLayout.CENTER); <HTML> <HEAD> <TITLE> Teszt </TITLE> </HEAD> <BODY> <APPLET CODE="HelloWorld.class" WIDTH="150" HEIGHT="25"> </APPLET> </BODY> </HTML> Példa

Rajz példa import javax.swing.JApplet; import java.awt.Graphics; public class Rajz extends JApplet { public void paint(Graphics g) { g.drawLine(15,10,210,10); g.drawLine(15,30,210,30); g.drawString(”Szöveg”,25,25); }

Metódusok init - inicializálja az appletet minden újraindítás, újratöltés után start – az applet inicializálása után fut le, amikor egy oldalról elmegyünk és visszatérünk akkor csak ez és a stop metódus fut le stop – az applet leállítása esetén fut le destroy - az applet újraindítása valamint kilépés esetén fut le paint – AWT használata esetén érdekes, segítségével viszonylag egyszerűen rajzolhatunk

Az appletek korlátai a biztonságos működés érdekében a következő korlátok léteznek: nem definiálhatunk natív metódusokat a futtató gépen nem írhat, olvashat fájlokat nem hozhat létre hálózati kapcsolatokat (a szervert kivéve) nem futtathat programokat a kliensen nem olvashatja a rendszer tulajdonságok egy részét a megjelenő ablakokban figyelmeztet arra, hogy azok Java Applet ablakok digitálisan aláírt appletekre a fentiek nem feltétlenül vonatkoznak (policy fájl) (http://developer.java.sun.com/developer/technicalArticles/Security/Signed/)

Amit Applettel meg lehet valósítani szinte minden Swing és AWT elem használható a szerverrel hálózati kapcsolatot tud kiépíteni az azonos oldalon lévő appletek publikus metódusait meghívhatjuk (böngésző függő) a helyi erőforrásról betöltött appletek nem rendelkeznek a hálózatról letöltött appletek korlátaival

Appletek létrehozása Forras.java javac Forras.java a legtöbb böngésző az oldal frissítésével nem frissíti az appleteket (shift, ctrl + refresh) végső megoldás: kiüríteni a böngésző gyorstárát, kilépni a böngészőből, belépni a böngészőbe érdemes appletviewer-t használni a tesztelésre appletviewer forras.html figyeljünk arra, hogy a helyi elérési útvonal ne tartalmazzon szóközöket

Appletek használata A showStatus(); metódussal írhatunk a státusz sorba másik applet metódushívás public class Sender extends Applet implements ActionListener { . . receiver = getAppletContext().getApplet(receiverName); ((Receiver)receiver).processRequestFrom(myName); } . . . public class Receiver extends Applet { public void processRequestFrom(String senderName) { label.setText("Received message from " + senderName + "!"); repaint(); Enumeration e = getAppletContext().getApplets(); Applet applet = (Applet)e.nextElement();

Paraméterek <PARAM NAME=”nev” VALUE=”vili”> String nev = getParameter("nev") <APPLET CODEBASE=”URL”>

Szálak sok böngésző az appleteket külön szálakban futtatja gyakran külön szál csoportban Párhuzamos feladatok végrehajtására szálakat használhatunk Runnable interfészt kell megvalósítani

Kommunikáció a szerverrel HTML (PARAM) java.net (servlet listerner) RMI CORBA JDBC

SQL, ODBC SQL (Sturctured Query Language) adatbázis, tábla, sor , oszlop relációs adatbázis lekérdezés módosító lekérdezés nézet ODBC (Open Database Connectivity) X/Open SQL CLI C nyelven alapuló interfész egységes felületet biztosít az adatbázisokhoz a gyártók saját meghajtókat írnak PC szabvány (csaknem ipari szabvány)

JDBC A Java platform legfontosabb összetevője Platform és szállító független Egy egyszerű Java API a programozók számára JDBC meghajtó menedzser Gyártó specifikus meghajtók mellyel az egyes gyártók optimalizálhatják a kapcsolatot Hasonló megoldás mint a Microsoft igen sikeres ODBC megoldása (C nyelv) Az adatok titkosítása az szállító meghajtó feladata

JDBC JDBC 1.0 JDBC 2.0 JDBC 3.0 SQL 92 egyszerű hívásszintű interfész sokkal összetettebb funkciók, alkalmazásszerverek connection pooling distributed transaction JDBC 3.0 SQL 99

JDBC meghajtók JDBC-ODBC bridge plus ODBC driver JDBC-t ODBC-re alakítja az ODBC meghajtó kommunikál az adatbázissal JDBC/ODBC bridge nem támogatja a JDBC2-t az ODBC-t kell beállítanunk nem ajánlott a haszálata Native-API partly-Java driver a meghajtó részben Java nyelven részben más nyelven íródott platform specifikus JDBC-Net pure Java driver egyszerű Java kliens könyvtár mely adatbázis független hálózati protokollon keresztül kommunikál egy szerver komponenssel mely ezt továbbítja az adatbázisnak Native-protocol pure Java driver egyszerű Java könyvtár mely közvetlenül az adatbázissal kommunikál

Miért nem ODBC Bonyolult Kevés utasítás, bonyolult szintaxis C specifikus, Pointer függő Kevésbé biztonságos, nehezebben telepíthető mint a JDBC

Használata Használható Java alkalmazásokban Applet-ekben csak a szerverrel tud kapcsolatot létesíteni Három, vagy több rétegű alkalmazásokban http, RMI, … Adatbázis Szever Kliens Középső réteg (Servlet, EJBean) JDBC

Three-tier Model

JDBC installálása PostgreSQL CLASSPATH windows: pgjdbc2.jar ->…\lib\ext postmaster –i pg_hba.conf CLASSPATH windows: http://www.ejip.net/faq/postgresql_win_setup_faq.jsp

JDBC kapcsolat felépítés I. Meghajtó betöltése: try { Class.forName("org.postgresql.Driver"); } catch(java.lang.ClassNotFoundException e) { System.err.print("ClassNotFoundException: "); System.err.println(e.getMessage()); } java -Djdbc.drivers=org.postgresql.Driver Teszt Adatbázis címzése: jdbc:<alprotokoll>:<adatbázis hivatkozás> jdbc:odbc://teszt.com:5000;UID=scott;PWD=tiger jdbc:postgresql://160.114.36.248/teszt

JDBC kapcsolat felépítés II. Kapcsolat objektum: Connection con; con = DriverManager.getConnection(url, "Rendszergazda", ”x"); Kifejezés: Statement stmt; stmt = con.createStatement(); stmt.close(); con.close(); kilépéskor le kell zárnunk minden kapcsolatot !! (a szemétgyűjtő nem tudja megtenni helyettünk a statemenet-et igen)

Példa: import java.sql.*; public class Teszt { public static void main(String args[]) { String url = "jdbc:postgresql://160.114.36.248/teszt"; Connection con; String createString; createString = "create table Teszt1 (COF_NAME VARCHAR(32), " + "SUP_ID INTEGER, PRICE FLOAT, SALES INTEGER, " + "TOTAL INTEGER)"; Statement stmt; try {Class.forName("org.postgresql.Driver");} catch(java.lang.ClassNotFoundException e) { System.err.print("ClassNotFoundException: "); System.err.println(e.getMessage());} try { con = DriverManager.getConnection(url, "Rendszergazda", "Alert"); stmt = con.createStatement(); stmt.executeUpdate(createString); stmt.close(); con.close(); } catch(SQLException ex) { System.err.println("SQLException: " + ex.getMessage());} } Példa:

JDBC objektumok

Connection Egy kapcsolatot jelent az adatbázissal Egy alkalmazásnak egy-vagy több kapcsolat objektuma lehet, egy-vagy több adatbázissal Connection.getMetaData DatabaseMetaData, információ az adatbázisról DriverManager.getConnection(URL) a DriverManager megpróbál egy megfelelő meghajtót keresni az URL-ben szereplő adatbázishoz

Metadata DatabaseMetaData dbmd = con.getMetaData(); kb. 150 metódust használhatunk a legtöbb resultset objektumot ad vissza sok metódus bonyolult névvel rendelkezik, célszerű olyan metódusokat használni melyek ezeket megadják

Statement paraméter nélküli kifejezések egyszerű SQL kifejezések létrehozására használandó executeQuery ( egyszerű lekérdezés Select * from t executeUpdate INSERT UPDATE DELETE CREATE TABLE DROP TABLE a visszatérési értéke egy integer mely az érintett sorok számát adja meg egyébként 0 execute olyan esetekben használják amikor több mint egy válasz érkezik Connection con = DriverManager.getConnection(url, "sunny", ""); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table2");

Prepared Statement a Statement alosztálya előre fordított SQL kifejezések egy-vagy több paramétere lehet (IN) több metódust használhatunk az IN paraméterek beállítására sokkal hatékonyabb lehet mint a Statement objektum (előre fordított) gyakran használt kifejezések létrehozására használandó többször futtatható, a beállított paraméterek megmaradnak

Példa Connection con = DriverManager.getConnection( "jdbc:my_subprotocol:my_subname"); con.setTransactionIsolation(TRANSACTION_READ_COMMITTED); PreparedStatement pstmt = con.prepareStatement( "SELECT EMP_NO, SALARY FROM EMPLOYEES WHERE EMP_NO = ?", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); pstmt.setFetchSize(25); pstmt.setString(1, "1000010"); ResultSet rs3 = pstmt.executeQuery(); pstmt.setString(1, "Hi"); for (int i = 0; i < 10; i++) { pstmt.setInt(2, i); int rowCount = pstmt.executeUpdate(); } setNull

Callable Statement segítségével SQL tárolt eljárásokat futathatunk supportsStoredProcedures() getProcedures() getProcedureTerm() {? = call procedure_name[(?, ?, ...)]} IN paraméterek OUT paraméterek regisztrálni kell nincs külön lehetőség nagy adatok kezelésére INOUT paraméterek

Példa IN CallableStatement cstmt = con.prepareCall( "{call updatePrices(?, ?)}"); cstmt.setString(1, "Colombian"); cstmt.setFloat(2, 8.49f); cstmt.addBatch(); cstmt.setString(1, "Colombian_Decaf"); cstmt.setFloat(2, 9.49f); int [] updateCounts = cstmt.executeBatch();

Példa OUT CallableStatement cstmt = con.prepareCall( "{call getTestData(?, ?)}"); cstmt.registerOutParameter(1, java.sql.Types.TINYINT); cstmt.registerOutParameter(2, java.sql.Types.DECIMAL, 3); ResultSet rs = cstmt.executeQuery(); // . . . byte x = cstmt.getByte(1); java.math.BigDecimal n = cstmt.getBigDecimal(2);

Példa INOUT CallableStatement cstmt = con.prepareCall("{call reviseTotal(?)}"); cstmt.setByte(1, (byte)25); cstmt.registerOutParameter(1, java.sql.Types.TINYINT); cstmt.executeUpdate(); byte x = cstmt.getByte(1);

Result Set Az előző három objektum eredménye Alapesetben nem írható és nem görgethető (csak egyszer lehet rajta végigmenni) A JDBC 2.0 API ezeket lehetővé teszi Nem minden meghajtó képes erre (pl.: postgresql) getXXX(név vagy sorszám) metódusok (select a, select * ) getMetaData updateRow(), insertRow(), deleteRow(), refreshRow() JDBC 2.0 previous first last absolute relative afterLast beforeFirst

Result set (JDBC 2.0) Kurzor: TYPE_FORWARD_ONLY TYPE_SCROLL_INSENSITIVE TYPE_SCROLL_SENSITIVE CONCUR_READ_ONLY CONCUR_UPDATABLE

Result set updateXXX CONCUR_UPDATABLE SQL parancsok nélül módosíthatjuk a rekordokat akkor működnek ha : van elsődleges kulcs a lekérdezés nem tartalmaz JOIN ill. GROUP BY kifejezést int n = rs.getInt(3); // n=5 . . . rs.updateInt(3, 88); int n = rs.getInt(3); // n = 88 rs.absolute(4); rs.updateString(2, "321 Kasten"); rs.updateFloat(3, 10101.0f); rs.updateRow();

Result set insert, delete rs.first(); rs.deleteRow(); rs.moveToInsertRow(); rs.updateObject(1, myArray); rs.updateInt(2, 3857); rs.updateString(3, "Mysteries"); rs.insertRow();

Példa java.sql.Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1"); while (rs.next()) { int i = rs.getInt("a"); String s = rs.getString("b"); float f = rs.getFloat("c"); System.out.println("ROW = " + i + " " + s + " " + f); }

2. Példa rs.beforeFirst(); while (rs.next()) { System.out.println(rs.getString("EMP_NO") + " " + rs.getFloat("SALARY"); } ----------------------------------------------------------------- rs.afterLast(); while (rs.previous()) { ResultSet rs = stmt.executeQuery( "SELECT LAST_NAME, FIRST_NAME FROM EMPLOYEES"); rs.last(); int numberOfRows = rs.getRow(); System.out.println("XYZ, Inc. has " + numberOfRows + " employees"); while (next()) { . . . 2. Példa

Tranzakciók bankbetét átutalás A helyen csökken B helyen növekszik egy tranzakció egy vagy több kifejezést tartalmaz melyek csak együtt hajtódnak végre (egyébként visszaállítja az eredeti állapotot - rollback) a kapcsolat objektum auto-commit módban van azaz minden egyes kifejezést külön külön hajt végre ha ez le van tiltva akkor a tranzakció addig nem ér véget amíg a commit vagy rollback metódusokat meg nem hívják a tranzakció kezdete az auto-commit mód letiltásával kezdődik a JDBC 2.0 API segítségével elosztott tranzakciókat is végrehajthatunk JDBC 3.0 SavePoint

A tranzakciók elkülönítése piszkos olvasás (dirty read) a tranzakció írásai a commit esemény előtt is olvashatóak azaz valaki olvashatja azt az adatot amit esetleg később visszavonnak (rollback) a többi tranzakció nem konzisztens adatok alapján működhet megismételhetetlen olvasás (nonrepeatable read) A tranzakció olvas egy sort B tranzakció megváltoztatja A tranzakció újra olvassa ugyanazt a megváltozott sort fantom olvasás (phantom read) A tranzakció olvassa az összes sort amely a WHERE feltételben van B tranzakció beilleszt egy sort amely ugyanennek a feltételnek fele meg A tranzakció újraértékeli a kifejezést és beveszi a fantom sort is

A tranzakciók elkülönítési szintjei TRANSACTION_NONE nincs tranzakció kezelés TRANSACTION_READ_UNCOMMITTED a nem végleges módosítások láthatóak (dirty read, …) TRANSACTION_READ_COMMITTED csak a végleges adatok olvashatóak (nincs dirty read, de van másik kettő) TRANSACTION_REPEATABLE_READ a másik tranzakció nem is írhatja az A tranzakció által érintett sorokat (phantom) TRANSACTION_SERIALIZABLE minden problémát kiküszöböl con.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED); magasabb elkülönítés lassabb működés (sok zárolás, egymásra várnak …) a fentiek természetesen adatbázis-kezelő függőek (MySQL – nincs tranzakció kezelés)

con.setAutoCommit( false ); bError = false; try { for( ... ) if( bError ) break; } stmt.executeUpdate( ... ); if( bError ) { con.rollback(); } else { con.commit(); } } / catch ( SQLException SQLe) { con.rollback(); ... } // end catch catch ( Exception e)

Optimalizálás fetch size setFetchDirection(); Statement.setFetchSize ResultSet.setFetchSize setFetchDirection(); FETCH_FORWARD FETCH_REVERSE FETCH_UNKNOWN

Nagy adatmennyiség JDBC 2.0 SQL 3 JDBC 1.0 BLOB (Binary Large Object) CLOB (Character Large Object) getCharacterStream JDBC 1.0 LONGVARBINARY LONGVARCHAR getBinaryStream getAsciiStream getUnicodeStream locator

Példa java.sql.Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT x FROM Table2"); // Now retrieve the column 1 results in 4 K chunks: byte [] buff = new byte[4096]; while (rs.next()) { java.io.InputStream fin = rs.getAsciiStream(1); for (;;) { int size = fin.read(buff); if (size == -1) { break; } output.write(buff, 0, size);

Nagy méretű adatok írása Kicsi adagokban küldi át setAsciiStream setBinaryStream setUnicodeStream setCharacterStream (JDBC 2.0)

Példa java.io.File file = new java.io.File("/tmp/data"); int fileLength = file.length(); java.io.InputStream fin = new java.io.FileInputStream(file); java.sql.PreparedStatement pstmt = con.prepareStatement( "UPDATE Table5 SET stuff = ? WHERE index = 4"); pstmt.setBinaryStream (1, fin, fileLength); pstmt.executeUpdate();

NULL érték típustól függően kezeli int n = rs.getInt(3); null - karakterekre 0 - számokra false - boolean int n = rs.getInt(3); boolean b = rs.wasNull();

Kötegelt utasítások növeli a teljesítményt addBatch() PreparedStatement pstmt = con.prepareStatement( "UPDATE Table4 SET History = ? WHERE ID = ?"); pstmt.setClob(1, clob1); pstmt.setLong(2, 350985839); pstmt.addBatch(); pstmt.setClob(1, clob2); pstmt.setLong(2, 350985840); int [] updateCounts = pstmt.executeBatch();

Függvények használata getNumericFunctions() getStringFunctions() getSystemFunctions() getTimeDateFunctions() supportsConvert() getXXXFunctions() UPDATE myTable SET circularVal = squared * { fn PI() } ...

Webes szolgáltatások Java WSDP fejlesztői csomag Tomcat + JSDK JSP Java Servlet Java XML pack Tomcat Ant Tomcat + JSDK

Java Servlet Java technológiára épülő web komponens platform független, bytecode dinamikusan betölthető dinamikus tartalom előállítására alkalmas egy tároló menedzseli (servlet engine) a web szerver vagy az alkalmazásszerver része, vagy önálló alkalmazás saját web szerverrel (Tomcat) biztosítja azt a környezetet amelyen keresztül a kérések és a válaszok (requset, response) lekezelhetőek tartalmazza és menedzseli a servlet-eket egész életfolyamatuk alatt

Példa A kliens kapcsolatba lép a web szerverrel és elküld egy HTTP kérést A kérést a web szerver átadja a servlet tárolónak amely futhat ugyanabban a process-ben ugyanazon a gépen másik process-ben másik gépen A servlet tároló a kérés paraméterei alapján meghívja a megfelelő servlet-et A servlet a kérés paraméterei alapján megállapítja mit szeretne a kliens ennek megfelelően végrehajtja a megfelelő műveleteket. Válaszol a kliensnek a válasz objektum segítségével Miután a servlet tároló megállapította, hogy a servlet befejezte a feladatot átadja a vezérlést a web szervernek

A servlet-ek előnyei hatékony kényelmes platform független biztonságos hagyományos CGI: n hívás n process kényelmes hatékony eszköztár a HTML űrlap adatok értelmezésére (http fejléc, süti, viszony) platform független biztonságos nem általános shell program környezetben fut (itt ki kell szűrni a speciális karaktereket …) buffer túlcsordulás nem léphet fel olcsó Tomcat - ingyenes

leggyakrabban használtak A servlet interfész a servlet interfész megvalósítása vagy öröklése teszi a servlet-et servlet-té GenericServlet ,HttpServlet HttpServletRequest HttpServletResponse kérés kezelő metódusok: service minden kérésnél meghívódik HTTP specifikus kérés kezelő metódusok: doGet doPost doPut doDelete doHead doOptions doTrace leggyakrabban használtak

Példa import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWWW extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"; out.println(docType +"<HTML>\n<HEAD><TITLE>Hello</TITLE></HEAD>\n" + "<BODY>\n<H1>Hello WWW</H1>\n</BODY></HTML>"); }

Servlet-ek csomagolása többen is fejleszthetnek egy web portált egy könyvtár használata nem célszerű külön könyvtárat célszerű használni csomagok használata (package) csomagnév.servlet

A servlet életciklusa betöltés, példányosítás a tároló indításakor amikor szükség van az adott servlet-re inicializálás – csak a betöltéskor init metódus argumentum nélküli – nem olvas semmilyen beállítást ServletConfig object – az első sorban kötelező meghívnia super.init(config) metódust betöltéskor pl.: JDBC kapcsolat felépítése kérés feldolgozás – minden egyes kérésre új szál service meghívja a megfelelő doXXX metódust nem célszerű ezt felülírni (használjuk a megfelelő doXXX metódusokat) doXXX a szolgáltatás befejezése – régóta nem aktív, server leálítása . destroy – adatbázis kapcsolat bezárása, háttérszálak leállítása, …

1. rész import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ShowMessage extends HttpServlet { private String message; private String defaultMessage = "No message."; private int repeats = 1; public void init(ServletConfig config) throws ServletException { super.init(config); message = config.getInitParameter("message"); if (message == null) { message = defaultMessage; } try { String repeatString = config.getInitParameter("repeats"); repeats = Integer.parseInt(repeatString); } catch(NumberFormatException nfe) {}

public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "The ShowMessage Servlet"; out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>"); for(int i=0; i<repeats; i++) { out.println(message + "<BR>"); } out.println("</BODY></HTML>"); 2. rész

Egy-szál modell alap esetben a servlet egy példánya található meg a memóriában minden egyes kérés teljesítésére egy új szál indul figyelnünk kell a párhuzamos futásra, a megfelelő erőforrások zárolására megakadályozható a párhuzamos futtatás a SingleThreadModel interfész megvalósításával ekkor egyszerre csak egy szál fut (a kérések egy várakozási sorban figyelnek ) ezzel a megoldással nagyon lelassíthatjuk rendszerünk működését !

A HTML űrlap által küldött adatok kezelése GET metódus esetén az URL-ben kódolva jelennek meg az adatok: http://host/path?user=Marty+Hall&origin=bwi&dest=lax POST metódus esetén a fejlécben vagy a törzsben helyezkednek el getParameter metódussal mindkettő kezelhető ! karakterlánc (string) a visszatérési érték üres karakterlánc, ha nincs értéke a paraméternek NULL, ha nincs ilyen paraméter getParameterValues – egy karaterlánc tömböt ad vissza (ekkor egy paraméternek több értéke lehet pl.: checkbox) a paraméter nevek érzékenyek a kis és a nagy betűre getParameterNames - a használható paraméterek listáját adja vissza (Enumeration)

Példa: (HTML) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>Collecting Three Parameters</TITLE> </HEAD> <BODY BGCOLOR="#FDF5E6"> <H1 ALIGN="CENTER">Collecting Three Parameters</H1> <FORM ACTION="servlet/ThreeParams"> First Parameter: <INPUT TYPE="TEXT" NAME="param1"><BR> Second Parameter: <INPUT TYPE="TEXT" NAME="param2"><BR> Third Parameter: <INPUT TYPE="TEXT" NAME="param3"><BR> <CENTER> <INPUT TYPE="SUBMIT"> </CENTER> </FORM> </BODY> </HTML>

Példa (Servlet) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ThreeParams extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Reading Three Request Parameters"; out.println(ServletUtilities.headWithTitle(title) +"<BODY BGCOLOR=\"#FDF5E6\">\n<H1 ALIGN=CENTER>" + title + "</H1>\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); } }

A HTTP paraméterek kezelése getHeader(”paraméter”) string – ha volt ilyen paramtér NULL – ha nem volt ilyen paraméter ezzel elvileg minden típus olvasható azonban vannak az egyes speciális paraméterekre külön metódusok: getCookies – egy cookie tömböt kapunk getAuthType, getRemoteUser getContentLength getContentType getDateHeader ,getIntHeader getHeaderNames – minden fejléc név egy Enumeration objektumban getHeaders – ha egy fejléc többször is szerepel akkor is visszaadja a fenti módon getMethod getRequestURI getProtocol

Minden fejléc kiíratása import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; public class ShowRequestHeaders extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Servlet Example: Showing Request Headers"; out.println( … 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>"); public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response);} Minden paraméter kiíratása Minden fejléc kiíratása

Weboldalak tömörítése … import java.util.zip.*; public class EncodedPage extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); 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 = "Page Encoded with GZip"; OutputStream out1 = response.getOutputStream(); out = new PrintWriter(new GZIPOutputStream(out1), false); response.setHeader("Content-Encoding", "gzip"); } else { title = "Unencoded Page"; out = response.getWriter(); } out.println( "<head></head><BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n"); String line = "Blah, blah, blah, blah, blah. " + "Yadda, yadda, yadda, yadda."; for(int i=0; i<10000; i++) { out.println(line); } out.println("</BODY></HTML>"); out.close();}} Weboldalak tömörítése Tömörített oldal

Válasz objektum magában foglal minden információt a kliens számára használhatunk buffer-t getBufferSize setBufferSize isCommitted reset resetBuffer – a fejrészet és a státusz kódot nem törli flushBuffer

Státusz kezelése response.setStatus(int), public void sendError(int code, String message) public void sendRedirect(String url) response.sendRedirect(response.encodeURL(url))

Képek létrehozása Kép létrehozása: Rajzoljunk a képbe: Frame f = new Frame(); f.addNotify(); // nem kell az ablakot megnyitni csak egy ilyen objektumot hozunk létre Image img = f.createImage(width, height);, Rajzoljunk a képbe: Graphics g = img.getGraphics(); g.fillRect(...); g.drawString(...); A Content-Type válasz fejléc beállítása response.setContentType("image/gif"); Egy válasz stream-et nyitunk OutputStream out = response.getOutputStream(); Küldjük el képünket GIF formátumban, itt egy kódolót kell használnunk. Ilyent a http://www.acme.com/java/ címen tudunk elérni. try {new GifEncoder(img, out).encode();} catch(IOException ioe) {}

Példa alkalmazás

Eredmény

Viszony követés a HTTP állapotmentes fontos az állapotkövetés: bevásárló kosár … három megoldás: sütik URL átírás rejtett HTML mezők

Sütik (Cookies) rövid szöveges információk melyeket a web szerver küld a kliensnek segítségével azonosíthatjuk a felhasználót egy e-commerce viszony alatt (bevásárló kosár) elkerülhető a felhasználói név és a jelszó (alacsony biztonsági szint) személyre szabható az oldal a felhasználói információ értékes (célozott reklámok)

Problémák 4 kbyte, 20 cookie/site, 300 süti összesen az emberek nem szeretik, ha a kereső gépek megjegyzik mit szeretnek keresni a sütikben tárolt információ nem biztonságos (más is használhatja a gépet, lemásolható a süti) a fenti okok miatt a felhasználók gyakran kikapcsolják a sütiket

Sütik használata new Cookie(name, value) cookie.setXxx response.addCookie(cookie) request.getCookies – egy tömböt ad vissza melynek Cookie objektum elemei vannak, NULL ha nincs süti cookie.getXxx

Sütik létrehozása sem a neve sem az értéke nem tartalmazhatja a következő karaktereket: [ ] ( ) = , " / ? @ : ; a következő metódusoknak meg van a getXxx párja is setComment() – megjegyzést adhatunk a sütihez setDomain() – segítségével beállíthatjuk a sütihez tartozó tartományt (a böngésző többek között ez alapján állapítja meg kinek mit adhat vissza) setMaxAge() – a süti érvényességének időtartamát állíthatjuk be másodpercben (-1 csak a jelenlegi viszonyban érvényes) setName() – a süti nevét állítja be setPath() – a tartományon belüli érvényességet adja meg setSecure() – csak titkosított kapcsolaton keresztül vihető át setValue() – az értékét adhatjuk meg

Sütik létrehozása import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class SetCookies extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { for(int i=0; i<3; i++) { Cookie cookie = new Cookie("Session-Cookie " + i,"Cookie-Value-S" + i); response.addCookie(cookie); cookie = new Cookie("Persistent-Cookie " + i,"Cookie-Value-P" + i); cookie.setMaxAge(3600); } response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Setting Cookies"; out.println (”<head></head><BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=\"CENTER\">" + title + "</H1>\n" + "</BODY></HTML>"); Sütik létrehozása

Sütik kiolvasása import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ShowCookies extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Active Cookies"; out.println(ServletUtilities.headWithTitle(title) + … Cookie[] cookies = request.getCookies(); Cookie cookie; for(int i=0; i<cookies.length; i++) { cookie = cookies[i]; out.println("<TR>\n" + " <TD>" + cookie.getName() + "\n" + " <TD>" + cookie.getValue()); } out.println("</TABLE></BODY></HTML>"); Sütik kiolvasása

URL átírás http://host/path/file.html;jsessionid=1234, nem tiltható le

HTML rejtett mező <INPUT TYPE="HIDDEN" NAME="session" VALUE="..."> csak akkor működik ha minden oldal dinamikusan generált

Egy teljesebb megoldás HttpSession API magas szintű intefész mely sütiken vagy URL átíráson alapul sütit használ ha lehetséges, amennyiben nem akkor átvált URL átírásra az alsó részeivel nem kell foglalkoznunk

Létrehozása HttpSession session = request.getSession(true); létrehoz egy viszony objektumot amennyiben már volt egy (valamikor régen, vagy most) akkor azt nyitja meg (true) a HttpSession objektum a szerveren tárolódik komoly adatstruktúrával rendelkezhet melyet mi adhatunk meg

Példa: HttpSession session = request.getSession(true); ShoppingCart cart = (ShoppingCart)session.getValue("shoppingCart"); if (cart == null) { cart = new ShoppingCart(); session.putValue("shoppingCart", cart); } doSomethingWith(cart);

Metódusok set/getAttribute() removeAttribute() getAttributeNames() – enumeration getId() – a viszony azonosítót adja vissza isNew() – true ha a kilens még nem látta a viszonyt getCreationTime() getLastAccessedTime() getMaxInactiveInterval() invalidate()

Servlet futási környezet ServletContext interfész ilyennek látja a servlet a környezetét a tárolónak kell megvalósítania az interfészt ServletConfig config = getServletConfig(); a ServletContext objektum segítségével a servlet eseményeket menthet el (log) megállapíthatja az egyes források URL címét elmenthet és kiolvashat olyan értékeket a környezetben melyet más, a környezetben futó servlet-ek olvashatnak

Hasznos metódusok inicializáló paraméterek: környezeti paraméterek: getInitParameter getInitParameterNames környezeti paraméterek: setAttribute getAttribute getAttributeNames removeAttribute erőforrások (HTML, GIF,JPEG) (nem alkalmasak dinamikus tartalom kezelésére pl.: index.jsp): getResource getResourceAsStream

A kérés továbbadása RequestDispatcher interfész a ServletContext objektumból tudjuk előállítani: getRequestDispatcher – a servlet elérési útvonalát adhatjuk meg (a futási környezeten belül /-el kezdődik) getNamedDispatcher – a servlet ServletContext-ben ismert nevét adhatjuk meg továbbítás: include – nem módosíthatja a válsz objektum fejléc mezőit, forward – csak akkor használhatjuk, ha még nem válaszoltunk a kliensnek (nincs adat a bufferben, ezt előbb törölni kell) az esetleges paraméterek elsőbbséget élveznek

Példa String path = “/raisons.jsp?orderno=5”; RequestDispatcher rd = context.getRequestDispatcher(path); rd.include(request, response);

Tomcat könyvtár hierarchia bin -> itt helyezkednek el az indító, leállító szkriptek fájlok log -> log fájlok lib -> jar fájlok conf -> server.xml itt tudunk új környezetet létrehozni webapps -> webes alkalmazások könyvtára

server.xml server elem – egy lehet belőle service elem – egy vagy több connector elem lehet benne de egy engine elem connector – HTTP1.1 vagy Warp itt tudjuk például a port-ot beállítani engine – a Tomcat szolgáltatási pontja, ezen belül tudjuk létrehozni például a virtuális címeket host – itt tudjuk megadni a hozzá tartozó URL-t és a gyökér könyvtárat contex – az egyes alkalmazások környezetéet definiálja a host-on belül.

Példa <Server port="8005" shutdown="SHUTDOWN" debug="0"> <Service name="Tomcat-Standalone"> <Connector className="org.apache.catalina.connector.http.HttpConnector" port="8080" minProcessors="5" maxProcessors="75" enableLookups="true" redirectPort="8443" acceptCount="10" debug="0" connectionTimeout="60000"/> <Engine name="Standalone" defaultHost="localhost" debug="0"> <Logger className="org.apache.catalina.logger.FileLogger" prefix="catalina_log." suffix=".txt" timestamp="true"/> <Realm className="org.apache.catalina.realm.MemoryRealm" /> <Host name="localhost" debug="0" appBase="webapps" unpackWARs="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="common"/> directory="logs" prefix="localhost_log." suffix=".txt" <Context path="/teszt" docBase="teszt" debug="0" privileged="true"> prefix="localhost_examples_log." suffix=".txt" </Context> </Host> </Engine> </Service> </Server> Példa

Alkalmazás környezet html, jsp, … WEB-INF classes – itt helyezkednek el a class fájlaink (jó esetben csomagokban) com.mycompany.mypackage.MyServlet /WEB-INF/classes/com/mycompany/mypackage/MyServlet.class web.xml – leírja az általunk használt servlet-eket, …, újra kell indítani a Tomcat-et, hogy újra értelmezze lib – az általunk használt jar fájlokat helyezhetjük el itt pl.: jdbc fájlok

web.xml URL-ek testreszabása URL-ek kikapcsolása Servler-ek inicializálása Servler-ek betöltése előre Szűrők definiálása Hiba, és köszöntő oldalak definiálása

URL-ek testreszabása a leggyakrabban használt szolgáltatása servlet elem servlet-name servlet-class, jsp-file (/ !!!!) servlet-mapping elem url-pattern (/valami, /*.asp)

Példa <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- ... --> <servlet> <servlet-name>Test</servlet-name> <servlet-class>moreservlets.TestServlet</servlet-class> </servlet> <servlet-mapping> <url-pattern>/UrlTest</url-pattern> </servlet-mapping> </web-app>

Servlet meghívó letiltása amennyiben egy másik URL-en keresztül érjük el akkor az inicializálás végrehajtódik ha erre számítunk akkor az alapértelmezett URL letiltására két módunk van: a /servlet/ útvonal átirányítása az Invoker servlet globális kikapcsolása install_dir/conf/web.xml <!-- <servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping> -->

Példa <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>Sorry</servlet-name> <servlet-class>moreservlets.SorryServlet</servlet-class> </servlet> <!-- ... --> <servlet-mapping> <url-pattern>/servlet/*</url-pattern> </servlet-mapping> </web-app>

Servlet-ek inicializálása init-param elem param-name ,param-value public void init() { ServletConfig config = getServletConfig(); firstName = config.getInitParameter("firstName"); emailAddress = config.getInitParameter("emailAddress"); } alkalmazás szintű kezdeti paraméterek context-param elem param-name, paramvalue

Példa <context-param> <param-name>support-email</param-name> <param-value>blackhole@mycompany.com</param-value> </context-param> <servlet> <servlet-name>InitTest</servlet-name> <servlet-class>myPackage.InitServlet</servlet-class> <init-param> <param-name>param1</param-name> <param-value>Value 1</param-value> </init-param> <param-name>param2</param-name> <param-value>2</param-value> </servlet>

Servlet-ek betöltése servlet elem <servlet> load-on-startup <servlet> <servlet-name>Search</servlet-name> <servlet-class>myPackage.SearchServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-name>Results</servlet-name> <jsp-file>/results/index.jsp</jsp-file> <load-on-startup>2</load-on-startup>

Szűrők definiálása a szűrők módosíthatják a kérés és válasz objektumot mielőtt egy JSP vagy servlet oldal a kérés objektumhoz jutna az első szűrő doFilter metódusa lefut itt kell meghívni a FilterChain objektum doFilter metódusát amely továbbadja a kérés objektumot vagy egy másik szűrőnek vagy a megfelelő servlet-nek

Szűrő példa import java.io.*; import javax.servlet.*; Szűrő import javax.servlet.http.*; import java.util.*; public class ReportFilter implements Filter { public void doFilter(ServletRequest request,ServletResponse response, FilterChain chain) throws ServletException, IOException { HttpServletRequest req = (HttpServletRequest)request; System.out.println(req.getRemoteHost() + " tried to access " + req.getRequestURL() +" on " + new Date() + "."); chain.doFilter(request,response); } public void init(FilterConfig config) throws ServletException { public void destroy() {} Szűrő Szűrő példa

Szűrő definiálása a web.xml fájlban a servlet elemek előtt kell lennie filter elem filter-name, filter-class filter-mapping filter-name servlet-name

Példa <filter> <filter-name>Reporter</filter-name> <filter-class>moreservlets.ReportFilter</filter-class> </filter> <filter-mapping> <servlet-name>SomeServletName</servlet-name> </filter-mapping> <url-pattern>/*</url-pattern> <servlet> <jsp-file>/TestPage.jsp</jsp-file> </servlet>

Üdvözlő oldalak beállítása akkor fontos amikor a kliens nem egy pontos útvonalat, hanem csak egy könyvtárat ad meg welcome-file-list elem welcome-file <welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> </welcome-file-list>

Hiba oldalak error-page elem <error-page> error-code, exception-type <error-page> <error-code>404</error-code> <location>/NotFound.jsp</location> </error-page> <exception-type>packageName.className</exception-type> <location>/SomeURL</location>