# Server Antwort enthält JSON Objekt/Array



## Axigan (25. Sep 2013)

Hi,

ich wollte mal als Übung ein Programm schreiben, dass sich auf einer Seite einloggt.
Nachdem ich das erste Paket übermittelt habe, bekomme ich vom Server als Antwort folgendes Paket:

```
HTTP/1.1 200 OK
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"
Content-type: application/json
Content-Encoding: gzip
Vary: Accept-Encoding
Transfer-Encoding: chunked
Date: Wed, 25 Sep 2013 14:42:16 GMT
Server: lighttpd/1.4.28

*komische Zeichenfolge*
```

Nun weiss ich, dass die Zeichenfolge ein JSON Objekt ist, weiss aber nicht, wie ich gezielt diesen teil umwandeln kann, so dass dieser lesbar wird.

Der zuständige Code sieht so aus:


```
private static String leseNachricht(java.net.Socket socket) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		char[] buffer = new char[1000];
		int anzahlZeichen = reader.read(buffer, 0, 1000);
		String nachricht = new String(buffer, 0, anzahlZeichen);
		return nachricht;
		
		
		//Diese Methode unglaublich langsam?
//		StringBuffer buffer = new StringBuffer();
//		for (String line = null; (line = reader.readLine()) != null;) {
//			buffer.append(line).append("\n");
//		}
//		return buffer.toString();
		

		//JSONTokener tokener = new JSONTokener(buffer.toString());
		//JSONArray finalResult = new JSONArray(tokener);

	}
```


Wie man sieht habe ich für die Umwandlung diese API versucht: org.json

Wie gesagt, die ganze Nachricht umzuwandeln wäre kein Problem, aber wie erkenne ich gezielt welcher Teil in JSON ist?


----------



## games647 (25. Sep 2013)

Die gesendete Daten werden mit dem Konservierungsverfahren gzip zu dir gesendet. Du musst natürlich erst den Datenstrom dekodieren bevor die ihn als normalen Text lesen kannst.


----------



## Axigan (25. Sep 2013)

Ah ok, das macht Sinn, dann ist es unlesbar, nicht weil es in JSON ist, sondern weil es in gzip gepackt ist, hätte ich eigentlich sehen sollen.

Und jetzt fällt mir ein, dass es einfach sein sollte die Nachricht in Header/Data zu trennen, da der Header ja mit einem doppelten carriage return endet, und ich das ja gezielt suchen kann. Ich werde es so mal ausprobieren.


----------



## games647 (25. Sep 2013)

Hat es einen Grund warum du nicht einfach HttpUrlConnection verwendest? Sie ist viel einfacher aufgebaut, so zum Beispiel auch das trennen des Headers und des Contens.


----------



## Axigan (25. Sep 2013)

games647 hat gesagt.:


> Hat es einen Grund warum du nicht einfach HttpUrlConnection verwendest? Sie ist viel einfacher aufgebaut, so zum Beispiel auch das trennen des Headers und des Contens.



Wie gesagt, dachte ich das als Übung zu programmieren, ich kenn mich da nicht so gut aus und kannte HttpUrlConnection noch nicht.
Ich werde es mir mal anschauen. Aber wird dadurch auch das gzip Problem einfacher lösbar?

Und brauche ich da noch Sockets, oder überhaupt nicht mehr?


----------



## ARadauer (25. Sep 2013)

Ok als Übung.. ich denke body und header trennen eine Leerzeile. Aber auf Hypertext Transfer Protocol ? Wikipedia ist das sehr gut beschrieben


----------



## games647 (26. Sep 2013)

Nein Sockets brauchst du dann nicht mehr. Das macht Java dann im Hintergrund. Ich rate dir nur bei solchen Verbindungen lieber eine HTTPUrlConnection zu verwenden. Es ist kein muss. Du kannst es genauso mit dem InputStream bei Sockets anwenden. Du müsstest nur bedenken, dass nur der Content komprimiert ist. 


```
private InputStream getDecrompressedStream(HttpURLConnection urlConnection)
            throws IOException {
        final String encoding = urlConnection.getContentEncoding();
        InputStream inputStream = urlConnection.getInputStream();
        if (("gzip".equals(encoding)) || ("x-gzip".equals(encoding))) {
            inputStream = new GZIPInputStream(inputStream);
        } else if (("deflate".equals(encoding)) || ("x-deflate".equals(encoding))) {
            inputStream = new InflaterInputStream(inputStream, new Inflater(true));
        }

        return inputStream; //Return the default inputstream if the didn't send the content compressed
    }
```


----------



## Axigan (26. Sep 2013)

Ok, es scheint wirklich besser zu sein HttpUrlConnection zu verwenden, aber mir schien jetzt, beim rumsuchen, dass das versenden von Nachrichten, irgendwie komplizierter aussieht, kann man da auch wie mit sockets einfach das ganze packet (header + Content) als grossen String versenden, so in der Art:


```
private void schreibeNachricht(java.net.Socket socket, String nachricht)
			throws IOException {
		PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(
				socket.getOutputStream()));
		printWriter.print(nachricht);
		printWriter.flush();
	}
```


Ich habe mir die Socket Methode angeschaut und bin soweit gekommen:


```
private String leseNachricht(java.net.Socket socket) throws IOException {
		InputStream in = socket.getInputStream();
		BufferedReader reader = new BufferedReader(new InputStreamReader(in));

		GZIPInputStream gzIn = new GZIPInputStream(in);
		BufferedReader gzReader = new BufferedReader(new InputStreamReader(gzIn));

		StringBuffer buffer = new StringBuffer();
		StringBuffer gzBuffer = new StringBuffer();
		String line;
		while ((line = reader.readLine()) != null) {
			buffer.append(line).append("\n");

			// Ende des Headers
			if (line.isEmpty()) {
				// hier müsste der komprimierte Teil anfangen
				// while ((line = gzReader.readLine()) != null) {
				// gzBuffer.append(line).append("\n");
				// }
				break;
			}
		}

		String header = buffer.toString();
		String content = gzBuffer.toString();

		return header;
	}
```


Leider wird folgende Exception ausgespuckt. Müsste ich für den content einen extra InputStream erstellen? Hab schon einiges versucht, am besten mache ich mich an was anderes, dass nicht gezippt ist :S


```
java.util.zip.ZipException: Not in GZIP format
	at java.util.zip.GZIPInputStream.readHeader(Unknown Source)
	at java.util.zip.GZIPInputStream.<init>(Unknown Source)
	at java.util.zip.GZIPInputStream.<init>(Unknown Source)
	at SimpleClient.leseNachricht(SimpleClient.java:65)
```


----------



## Axigan (27. Sep 2013)

Ich kan irgendwie grad den letzten post nicht editieren, deshalb verzeiht mir den doppelpost...

Ich habe nun alles mit HttpUrlConnection eingerichtet und wie es aussieht, braucht man damit nicht mal den gepackten teil zu entpacken, bevor man ihn lesen kann, sondern er ist schon entpackt und lesbar
(in diesem Fall kommt also direkt das JSON Array als antwort: 


```
[1,"http:\/\/****.de\/logw.php?unr=***&token=a6dasdfawer45234r8qu3dfjq2348rjqdwfq9234c208db93097eb74e85dcdb30cfa07b2bfe6eb4f5245469d7f6a9cf7f91332b0&ref=&retid="]
```


----------

