# REST mit java client und php server



## Jigga (28. Sep 2011)

Hallo Community,

mir wurde für mein Vorhaben hier die Webservice Technologie ans Herz gelegt, auf die ich mich auch gleich gestürzt habe. Dabei wollte ich REST verwenden, jedoch bildeten sich bei mir nach einigen Tagen einige Gedanken-Knoten, die ich einfach nicht mehr entknoten kann. 

Mein Vorhaben: Eine MySQL DB liegt auf einem kostenlosen Webserver. Ich habe eine Anwedung welche auf die DB zugreifen soll. Ein direkter externer Zugriff ist nicht möglich, deswegen die Idee ein PHP-Script zu verwenden. Hier soll dann der Webservice zum Einsatz kommen. 
Ich interessiere mich besonders für das Abrufen von Daten aus der DB und die Darstellung/Verarbeitung dieser in meiner Anwedung.

Nach unzähligen Tutorials und anderen Seiten bezüglich des Themas bin ich mehr als nur verwirrt, vorallem weil ich nicht genau weiß, ob ich das ganze richtig verstanden habe.

Verständnisprobleme: 
1) In meiner Java Klasse rufe ich eine PHP-Datei via 

```
URL url = new URL("URL der PHP-Datei");
URLConnection urlC = url.openConnection();
```
auf, die zB. eine SELECT-Abfrage auf meiner DB ausführt, aber wie sieht die Antwort aus? Irgendwie muss die PHP-Datei ja meiner Anwedung sagen " Hier hast du das Paket mit den Daten"?
2) Wie verarbeite ich die die angekommen Daten?Sind diese einfach nur ein String in dem alle Informationen drin stehen, oder wie sieht die Antwort und dessen Verarbeitung aus?
3) In der PHP-Datei müssten ja die Zugangsdaten zur DB stehen: Was passiert, wenn jemand die URL zu der Datei herausfindet(sniffing?) und diese mit einem Editor öffnet und die Zugangsdaten einfach ausliest?

Randinfos: Diese Jersey-Geschichte würde bei mir nicht funktionieren, weil der Webserver keine Servlets betreiben kann. Deswegen "...PHP Server".


Für Hilfestellung und "Entknotung" wäre ich euch sehr dankbar.

MfG


----------



## TheDarkRose (28. Sep 2011)

Andere Frage. PHP-Grundlagen vorhanden?


----------



## Jigga (28. Sep 2011)

TheDarkRose hat gesagt.:


> Andere Frage. PHP-Grundlagen vorhanden?



nicht wirklich. habe mir hier und da mal was angeschaut, wobei mir aufgefallen ist, dass sich das ganze teilweise gut auf java abbilden lässt,sprich dann teilweise selbsterklärend ist.
eine PHP, die prepared statements ausführt habe ich auf dieser basis bereits erfolgreich erstellen können.


----------



## TheDarkRose (28. Sep 2011)

Ok. Hoffe du verstehst wie REST arbeitet. Um eine Anfrage an eine REST-API zu stellen rufst du einfach eine normale URL mit Parametern auf, wie z.B. 
	
	
	
	





```
http://www.example.com/api/showbla.php?param1=foo&param2=bar
```
. In dieser showbla.php kannst du diese GET-Paramet mit der 
	
	
	
	





```
$_GET['paramx']
```
 einfach verarbeiten. Die Antwort erhält der Client einfach durch Ausgeben der Ergebnisse. Natürlich muss man sich auf ein Format einigen. Oft ist es XML oder auch JSON. Also anstatt das du eine HTML-Seite generierst, gibst du formatiertes XML oder JSON aus. Ist natürlich dann nicht zum anschauen im Browser, aber dazu ist ja eine REST Schnittstelle nicht gedacht. Im Java Client kannst du diese XML oder JSON Ausgabe dann gemütlich weiterverarbeiten.

Thema Datenbankzugriff. Du schreibst die Zugriffsdaten in eine config.inc.php. Die Endung .php ist wichtig, da dadurch bei direkten Aufruf durch jemand Fremden, die Datei durch den PHP-Parser gejagt wird anstatt alles offenzulegen.

```
<?php
define('MYSQL_HOST', 'localhost');
define('MYSQL_USER', 'myuser');
define('MYSQL_PASSWD', 'mypassword');
?>
```
Diese bindest du dann einfach in jede Seite ein und kannst die Konstanten in deinem mysql_connect verwenden. Ich habe bewusst Konstanten anstatt Variablen genommen, da Konstanten nicht durch Fehlerhafte Scripts verändert werden können.

```
<?php
require_once('config.inc.php');

$con = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWD);

// TODO
?>
```


----------



## Jigga (28. Sep 2011)

na das ist doch mal was. mit dem aufruf war ich bereits soweit. (gibt es für die Variable-Übergabe mittels der URL eigentlich eine Anzahl-Begrenzung oder ähnliches?)
das mit der db-connection auslagerung ist super,ich danke dir 

Stellt sich für mich aber immer noch die Frage, wie ich in java die Antwort "empfange".
Seitens PHP: meinst du mit "Die Antwort erhält der Client einfach durch Ausgeben der Ergebnisse" die "echo" funktion?


----------



## TheDarkRose (28. Sep 2011)

Zu java. Ja einfach mit einem HttpReader oder so. Wie wenn du ne normale Webseite einliest, nur bekommst du halt XML oder JSON Daten geliefert anstatt HTML.

Zu PHP: Ja ganz normale echo Ausgaben. Aber eben entsprechend formatiert

Achja, hier ein Link zu einer REST-API wie das ausschauen könnte: diverses:carrot_api:manual_v10 [Carrot Wiki] Nicht von den URL's verwirren lassen, hier hängt halt kein PHP sondern was andere dahinter ^^


----------



## nillehammer (28. Sep 2011)

Jigga hat gesagt.:
			
		

> (gibt es für die Variable-Übergabe mittels der URL eigentlich eine Anzahl-Begrenzung oder ähnliches?)


Nicht wirklich. Tomcat ist aber z.B. so eingestellt, dass die Request-URL inkl. Parametern 2000 Bytes nicht übersteigen darf. Und einige Web-(Firewalls) begrenzen die Anzahl der Parameter auf 100.


----------



## Jigga (29. Sep 2011)

ich kriege gerade eine

```
[Fatal Error] :1:1: Content is not allowed in prolog.
 org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
```
Und verstehe nicht ganz warum. Code:

```
URL url = new URL("...insert.php");
URLConnection uc = url.openConnection();
uc.setDoOutput(true);
OutputStream out = uc.getOutputStream();
String data = "variable";
out.write(data.getBytes());
out.flush();
DocumentBuilderFactory docFac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuild = docFac.newDocumentBuilder();
Document doc = docBuild.parse(uc.getInputStream());
```

Wenn ich die Antwort aber mit folgender Methode behandle, kriege ich die werte so wieder, wie ich sie im echo definiert habe:

```
public String read() throws IOException {
		InputStream in = urlCon.getInputStream();
		int c = 0;
		StringBuffer incoming = new StringBuffer();
		while (c >= 0) {
			c = in.read();
			incoming.append((char) c);
		}
		return incoming.toString();
	}
```

Muss ich etwa in meiner php mit dem echo eine XML nachbauen? oO


----------



## TheDarkRose (29. Sep 2011)

Ja klar muss deine PHP gültigen XML Code erzeugen.


----------



## Jigga (29. Sep 2011)

oh,dann hatte ich da wohl etwas falsch verstanden 
gut,dann versuche ich mal eine XML nachzubauen.


----------



## Jigga (29. Sep 2011)

ich stehe gerade irgendwie auf dem schlauch,weil mein XML parser gibt mir die ganze zeit "null" ausgibt....
hier mal die .php für alle fälle (ja ist nicht sonderlich elegant,aber anders hat er mir die ganze zeit fehler um die ihren geworfen -.-)

```
<?php
	$name = $_POST["name"];
	$mysqli = new mysqli();
	if ($stmt = $mysqli->prepare("SELECT * FROM test WHERE Name=?")) {
		$stmt->bind_param("s", $name);
		$stmt->execute();		
		$stmt->bind_result($guy, $reporter, $link, $section);
		while($stmt->fetch()) {
			$newxml = '<?xml version="1.0"?>';
			$newxml .= "<request>
			<name>$guy</name>
      <reporter>$reporter</reporter>
      <link>$link</link>
      <section>$section</section>
      </request> ";
			echo $newxml;
		}
		$stmt->close();
	}
	$mysqli->close();
?>
```

meine methode zum abfragen der daten:


```
try {
			URL url = new URL(
					"insert.php");
			URLConnection uc = url.openConnection();
			uc.setDoOutput(true);
			OutputStream out = uc.getOutputStream();
			String data = "name=banGuy";
			out.write(data.getBytes());
			out.flush();
			InputStream is = uc.getInputStream();
			Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
			Element e = d.getDocumentElement();
			System.out.print( e );
		} catch (NullPointerException e) {
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
```
was mache ich falsch? :/


EDIT: habe gerade das XML aus einem String generieren lassen,sprich erst die empfangenen Daten in String umgewandelt und dann xml daras gemacht.aber an die werte komme ich immer noch nicht dran ....


EDIT2: ok mit folgendem anhang an die XML-lese-Methode kann ich an die Werte rankommen:


```
XPathFactory factory = XPathFactory.newInstance();
			XPath xpath = factory.newXPath();
			XPathExpression expr = xpath
					.compile("/request/af");
			String name = (String) expr.evaluate(doc, XPathConstants.STRING);
			System.out.println(name);
```

nur stellt sich mir jetzt die Frage,warum ich im echo der PHP nicht einfach sowas mache wie "var1=key1;var2=key2;var3=key3;..."
und dies mit einem strinktokenizer oder sowas auseinander pflücke?sehe gerade den vorteil der XML geschichte nicht ???:L


----------



## TheDarkRose (29. Sep 2011)

Jigga hat gesagt.:


> nur stellt sich mir jetzt die Frage,warum ich im echo der PHP nicht einfach sowas mache wie "var1=key1;var2=key2;var3=key3;..."
> und dies mit einem strinktokenizer oder sowas auseinander pflücke?sehe gerade den vorteil der XML geschichte nicht ???:L



Naja, weil sowas total unschön ist und keiner Konvention im Endeffekt folgt. Aber du könntest auch JSON verwenden.


----------



## tuxedo (11. Okt 2011)

"Lustig"... Sowas ähnliches hab ich vor langer Zeit auch mal gemacht. Nur hab ich kein REST benutzt und die Kommuniktation auf das nötigste runtergestrippt. Auf Java-Seite spricht das Teil JDBC (zumindest den wichtigsten Teil davon). War sogar ziemlich schnell (abhängig von der Internetanbindung).

Projekt-Wiki: jPMdbc - Wiki - root1.de - Software Engineering
Source: jPMdbc - /trunk - Repository - root1.de - Software Engineering bzw. jpmdbc - Revision 2: /trunk


----------



## Jigga (11. Okt 2011)

Interessantes Projekt. So eins, oder auch evtl genau dieses hatte ich bereits im Netz gefunden.
Der Nachteil dabei ist aber, dass die DB Zugangsdaten im Quellcode stehen..


----------



## TheDarkRose (11. Okt 2011)

UND das wieder die komplette Logik im Client sein muss.


----------



## tuxedo (11. Okt 2011)

Wo ist das Problem? Hat man mit JDBC eigentlich immer.

Passwort kannst du in der PHP File hardcodieren wenn du unbedingt willst. Ist ja OpenSource 

Gruß
Alex


----------



## TheDarkRose (11. Okt 2011)

tuxedo, auf was war das jz bezogen?


----------



## Jigga (12. Okt 2011)

So wie ich es verstehe, meint er damit die DB-Zugangangsdaten: Diese in einer PHP-Datei speichern, aber den DB-Zugang ansich beim Client realisieren. 
Stellt sich aber mir jetzt die Frage, inwiefern das sinnvoll ist. Da man ja auf die PHP-Datei, wenn man deren Verlinkung aus dem Quellcode erst hat, frei zugreifen kann. Damit wäre ein voller Zugriff auf die DB möglich??

Generelle Frage: Wie sicher ist denn meine DB vor Angriffen Dritter auf einem kostenlosen Webspace? Ich habe derzeit nur PHP-Dateien die etwas in die DB schreiben bzw Zeilen ändern (prepared statements). Die Zugangsdaten sind in einer seperaten PHP ausgelagert.
Prinzipiell geht es mir darum, dass meine Daten nicht gelöscht werden können.


----------



## TheDarkRose (12. Okt 2011)

Solange du die Logik in den PHP Webservice hast und der Client i.E. dumm ist, eigentlich relativ sicher. Was noch angebracht wäre ist eben Zugriffsschutz. OAuth z.b.


----------



## tuxedo (12. Okt 2011)

Jigga hat gesagt.:


> So wie ich es verstehe, meint er damit die DB-Zugangangsdaten: Diese in einer PHP-Datei speichern, aber den DB-Zugang ansich beim Client realisieren.
> Stellt sich aber mir jetzt die Frage, inwiefern das sinnvoll ist. Da man ja auf die PHP-Datei, wenn man deren Verlinkung aus dem Quellcode erst hat, frei zugreifen kann. Damit wäre ein voller Zugriff auf die DB möglich??



An die PHP Datei mit den Zugangsdaten kommst du als aussenstehender nur dann wenn:

* Du Zugriff auf die PHP Datei vor der Evaluierung durch den PHP-Interpreter hast
* Das Passwort irgendwohin übertragen, und diese Übertragung abgefangen wird

Beides wäre mit meinem Ansatz nicht der Fall.
Und wenn einem das noch zu unsicher ist: jPMdbc kann auch https.

Aber den REST Ansatz finde ich eigentlich auch ganz interessant. Ist halt mehr SOA als mein JDBC Ansatz.

- Alex


----------



## Jigga (12. Okt 2011)

Die logik ansich ist nur in den PHP-Dateien, sprich auf dem Server. Mich würde noch interessieren wie das ganze in Wireshark aussieht. Lässt sich da die Ziel-URL rauslesen?Oder generell, falls jemand meine exe/jar entpackt und an die URLs zu den PHPs gelangt: kann er dann irgendwie an die Zugangsdaten der DB kommen? (wie erwähnt sind diese in einer externen PHP)


----------



## TheDarkRose (12. Okt 2011)

Das was mich an jPMdbc ist, das die Logik wieder komplett im Client sein muss. Was beim SOA Ansatz nicht der Fall ist. Dort ist die Logik komplett im Webservice selbst. Der Client ruft dann nur mehr die entsprechenden Webservice Methoden auf, ist aber sonst nur dumm, bzw. für die GUI Darstellung zuständig. Bringt auch unter anderem weitere Vorteile, das man nicht auf einen Client beschränkt ist, sondern auch Android/iOS Apps einfach anbinden kann, oder auch die API Drittanbietern zur Verfügung stellen kann, ohne die Logik mehrfach implementieren zu müssen.


----------



## TheDarkRose (12. Okt 2011)

Jigga hat gesagt.:


> Die logik ansich ist nur in den PHP-Dateien, sprich auf dem Server. Mich würde noch interessieren wie das ganze in Wireshark aussieht. Lässt sich da die Ziel-URL rauslesen?Oder generell, falls jemand meine exe/jar entpackt und an die URLs zu den PHPs gelangt: kann er dann irgendwie an die Zugangsdaten der DB kommen? (wie erwähnt sind diese in einer externen PHP)



Nein, alles was in den PHP Dateien steht, darauf hat keiner Zugriff. Solange halt alles durch den Intepreter selbst gejagt wird. auf die Ausgaben, sofern keine Zugriffsschutz erfolgt hat halt jeder Zugriff. Also sowas wie OAuth solltest du schon implementieren. und HTTPS wäre eigentlich Pflicht, das schon mal keiner mitschneiden kann.


----------

