• Wie man aus Java mit einem PHP-Script kommuniziert

    Java ist bekanntlich bestens dafür geeignet Webanwendungen, sogenannte Applets, zu schreiben. Diese Applets werden innerhalb des Browserfensters ausgeführt und laufen innerhalb der JVM (Java-Virtuellen-Maschine).
    Dies bedeutet auch, dass die Daten des Applets von der Webseite heruntergeladen und lokal auf dem Rechner ausgeführt werden, völlig getrennt von dem Server von dem sie stammen.
    Die meisten Webspace-Anbieter bieten heute bereits Datenbanken mit ihren Paketen an. Dummerweise nützen die für Applets in den meisten Fällen gar nichts. Da das Applet auf dem lokalen Computer ausgeführt wird müßte das Applet auf die Datenbank des Servers verbinden können. In der Regel wird das durch den Anbieter aus Sicherheitsgründen aus gutem Grund nicht erlaubt und technisch unterbunden.
    In solchen Fällen bietet der Anbieter mit Sicherheit PHP in seinem Paket an. PHP wird im Gegensatz zu Java auf dem Server interpretiert und ausgeführt. Eine Verbindung von "Außen" zur Datenbank ist also nicht nötig da das PHP-Script auf dem Server läuft ist es nur eine lokale Verbindung.
    Java kommt als moderne Programmiersprache mit allen Voraussetzungen daher die man braucht um mit einer Webseite zu kommunizieren. Warum sollte man diese Möglichkeit nicht nutzen um doch an die Datenbank des Anbieters zu gelangen um zum Beispiel die Highscore eines Spiels zu speichern?


    Der Ansatz
    Damit die Java<->PHP Schnittstelle funktioniert muss auf der PHP-Seite natürlich ein entsprechendes Script verfügbar sein. Das soll aber nicht Thema dieses Tutorials sein.
    Auf der Java-Seite der Schnittstelle muss es natürlich die Möglichkeit geben mit einer Webseite zu Kommunizieren.
    Dafür stellt Java die Klasse java.net.URLConnection bereit. Eine Instanz dieser Klasse verschafft man sich sehr leicht über ein Objekt der Klasse java.net.URL mit der Methode openConnection().
    Ein kleiner Beispielcode:
    [highlight=java]
    java.net.URL url = new java.net.URL("http://localhost/test.html");
    java.net.URLConnection urlcon = url.openConnection();
    [/highlight]

    Lesen und schreiben
    java.net.URLConnection stellt die beiden Methoden getInputStream() und getOutputStream() zur Verfügung. Mit ihrer Hilfe erhählt man eine Instanz der entsprechenden Streams und kann diese lesen bzw. darauf schreiben.
    Hierbei ist aber unbedingt zu beachten, dass der Verbindung erst explizit erlaubt werden muss Daten zu versenden. Dies geschieht mit der Methode java.net.URLConnection.setDoOutput(boolean). Vorher ist zwar das lesen eingehender Daten über den InputStream möglich, nicht jedoch das senden von Daten über den OutputStream. Diese Daten kommen dann via "POST" im PHP-Script an.
    Das senden der Daten über den OutputStream sollte als String erfolgen, und zwar so wie man es von Daten versendet die via Post übermittelt werden, also in dem folgenden Format:
    Code:
    keyname1=value1&keyname2=value2&keyname3[....]
    
    Über den InputStream kommen die Daten "rein" die das PHP-Script ausgibt, in der Regel durch den Befehl "echo".
    Somit hier also eine erweiterung unseres obrigen Beispielcodes:
    [highlight=java]
    java.net.URL url = new java.net.URL("http://localhost/test.html");
    java.net.URLConnection urlcon = url.openConnection();
    java.io.OutputStream out = urlcon.getOutputStream();
    java.io.InputStream in = urlcon.getInputStream();
    urlcon.setDoOutput(true);
    [/highlight]

    Besonderheiten
    Es liegt in der Natur von Internetseiten, dass sie in einem statischen Zustand vom Server an den Client ausgeliefert werden. Das gilt auch für Webseiten die mit PHP generiert werden. Das was von dem Java-Programm empfangen wird ist das was normalerweise auch als Webseite ausgeliefert wird. Es macht also Sinn erst Daten zu senden und anschließen Daten zu empfangen. Somit hat das PHP-Script Zeit auf die eingehenden Daten zu reagieren.
    Beispiel: Java fragt: Die 10 besten Scores für Spiel sowieso, das PHP-Script antwortet mit den entsprechenden Daten.
    Die Verbindung unterscheidet sich also von einer Verbindung über Sockets.

    Ist der Seitenname nicht korrekt funktioniert zwar das Senden der Daten (wobei die dann wahrscheinlich ins Datennirvana flattern), das Lesen der Daten schlägt aber mit einer java.io.FileNotFoundException fehl.


    Beispiel:


    So, und hier das ganze Mal praktisch angewand.
    Zuerst mal ein PHP-Script für den Server, es tut nichts weiter als die empfangen Daten direkt wieder mit echo auszugeben.
    Das Script stammt von Ben und ist leicht abgewandelt:
    PHP-Code:
    <?php

        
    if(strtolower($_SERVER['REQUEST_METHOD']) == 'post') {
            foreach(
    $_POST as $key => $value) {
                echo 
    'key:' $key '=' $value ' ';
            }
        } 

    ?>
    Hier eine Java-Klasse die alle Schreib- und Lesevorgänge mit dem Script regelt:
    [highlight=java]
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URL;
    import java.net.URLConnection;

    /**
    * PhpPostConnect.java
    * This class can represant a connection to an PHP-Site
    * to send the side data via "POST" and get Data from
    * the side which will be written by side with "echo"
    * @author sparrow
    */
    public class PhpPostConnect {

    /** Contains the URL to the PHP-Script */
    private URL sitepath;
    /** The Connection to the URL */
    private URLConnection con;

    /**
    * Empty construct, you must set the URL of the
    * target before you start to send and read data
    */
    public PhpPostConnect() {

    }

    /**
    * Construct which also define the targed URL
    * @param sitepath The URL to the target PHP-Script
    */
    public PhpPostConnect(URL sitepath) {
    this.sitepath = sitepath;
    }

    /**
    * Set the URL to the target PHP-Script
    * @param sitepath The URL to the target PHP-Script
    */
    public void setSitePath(URL sitepath) {
    this.sitepath = sitepath;
    }

    /**
    * To get the target-URL
    * @return The URL to the target PHP-Script
    */
    public URL getSitePath() {
    return this.sitepath;
    }

    /**
    * Sending data to the target-URL
    * @param data The data which should be send
    * @throws IOException
    */
    public void send(String data) throws IOException {
    if (con == null) {
    con = sitepath.openConnection();
    }
    if (con.getDoOutput() == false) {
    con.setDoOutput(true);
    }
    OutputStream out = con.getOutputStream();
    out.write(data.getBytes());
    out.flush();
    }

    /**
    * Reading incoming data from the target-URL
    * @return The incoming data
    * @throws IOException
    */
    public String read() throws IOException {
    if (con == null) {
    con = sitepath.openConnection();
    }
    InputStream in = con.getInputStream();
    int c = 0;
    StringBuffer incoming = new StringBuffer();
    while (c >= 0) {
    c = in.read();
    incoming.append((char) c);
    }
    return incoming.toString();
    }

    }
    [/highlight]

    Und zuletzt die Klasse mit der wir den Test starten.
    Wir gehen davon aus, dass das Script unter der URL http://localhost/contest.php erreichbar ist.
    Hier wird die Schnittstelle zum PHP-Script instanziert, Testdaten gesendet und das Ergebnis empfangen:
    [highlight=java]
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;

    public class Test {

    public static void main(String[] args) {
    try {
    URL url = new URL("http://localhost/contest.php");
    PhpPostConnect con = new PhpPostConnect(url);
    try {
    con.send("foo1=bar&foo2=bar2");
    System.out.println(con.read());
    } catch (IOException e) {
    e.printStackTrace();
    }
    } catch (MalformedURLException e) {
    e.printStackTrace();
    }
    }

    }
    [/highlight]

    Wenn alles klappt ist folgendes in der Konsole abzulesen:
    Code:
    key:foo1=bar key:foo2=bar2
    
    Was beweist: wir haben erfolgreich Daten an das PHP-Script versand und anschließend wieder empfangen.
    Zur Klarstellung: Wir empfangen die Daten auch wieder im Java-Programm. Das PHP-Script gibt sie nicht in einem Browser aus. Das Java-Programm empfängt die Daten des Scripts wie sie sonst von einem Browser empfangen werden würden.


    Sollten Fragen oder Ungklarheiten betreffen des Tutorials bestehen, postet bitte in dem entsprechendem Forum. Danke.
  • Neue Blog-Einträge

    Adventure-PHP-Framework 1.12 erschienen

    Ich bin bisher nicht dazu gekommen - und wollte eigentlich die beiden links nennen: :arrow: http://www.golem.de/1008/77097.html :arrow:...

    20.08.2010 16:09

    Britische Regierung hält am IE6 fest

    Man könnte auch sagen "Tot erhoffte leben länger" :arrow: http://www.golem.de/1008/77035.html Leider sind halt in vielen Unternehmen speziell an den IE angepasste Programme im Einsatz, die es...

    20.08.2010 16:12

    Hosting-Dienst GitHub erreicht Millionen-Marke

    Während ich persönlich noch immer gerne SVN einsetze, ist git gerade voll im Trend. GitHub hatte die Tage zu vermelden, dass es mehr als eine Million Softwareprojekte "unter seinem Dach" hat....

    20.08.2010 16:15

    Screenshot unter Windows vom aktiven Fenster erstellen

    Der Trend, nicht nur einen Bildschirm bei der Arbeit am PC zu verwenden ist imho vorhanden. Wer - wie ich - gerne zwischendurch einen screenshot macht, der dürfte sich ggf. manches Mal geärgert...

    20.08.2010 16:20

    ListView-Spalten Automatisch ausrichten

    Listviews begegnen uns eigentlich jeden Tag aufs neue bei der täglichen Arbeit. Genauso oft nervt es, wenn man z.b. im Explorer Spalten verschieben muss, um einen Dateinamen einer Datei vollständig...

    24.08.2010 13:10
  • Neue Beiträge

    Sekundentakt

    Hi,

    ich weiß nicht genau, wie Deine Subselects aussehen. Aber falls die sich so ähnlich formulieren lassen:

    Code:
    SELECT something
    

    CONCAT_WS mit LEFT JOIN

    Sekundentakt 01.09.2010 15:30 Gehe zum letzten Beitrag
    DasMööp

    *ohje ... Antwort: Subselect *rolleye, damit fällt dann der JOIN weg.

    CONCAT_WS mit LEFT JOIN

    DasMööp 31.08.2010 13:29 Gehe zum letzten Beitrag
    DasMööp

    Hallo,

    bei einer Abfrage von zwei Tabellen ist in einer in zwei Spalten je die ID der einen hinterlegt und diese brauche ich in der CONCAT.

    CONCAT_WS mit LEFT JOIN

    DasMööp 31.08.2010 12:17 Gehe zum letzten Beitrag
    floppy

    Hallo DEVWinC, Hallo Spezialisten,

    ich stehe zur Zeit auf dem gleichen Problem, bei mir gibts beim BartPE (XP) nur einen BlueScreen nach

    [Booten] ISO-Images mit Bootloader starten & BartPE

    floppy 31.08.2010 10:48 Gehe zum letzten Beitrag

Impressum · Tutorials · Nutzungsbedingungen · thematisch sortierte Linklisten · Spendenaufruf · Team · Partnerprojekte

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48