PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : NullPointer bei alter Android Version


MartinB
2012-02-03, 21:27:09
Folgende Situation: Meine App parst eine Website. Um dazu Zugriff zu bekommen muss die App sich erstmal anmelden, das Cookie speichern und dann auf einer Unterseite mit diesem Cookie eine neue Verbindung herstellen.
Folgender Code funktioniert unter Android 2.3 einwandfrei, aber unter 2.2 und älter funktioniert er nicht:


URL url = new URL("https://myloginform");
trustAllHosts(); //because the certificate is not singed
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(DO_NOT_VERIFY);
conn.setInstanceFollowRedirects(false);
conn.setDoOutput(true);

//Connect to login-page and send login data
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
wr.close();

//get cookies THIS WORKS ONLY ON ANDROID 2.3 AND ABOVE
List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
conn.disconnect();

//connect to overview page
url = new URL("https://mynextpage");
trustAllHosts();
conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(DO_NOT_VERIFY);
conn.setInstanceFollowRedirects(false);

//Send cookies for identification - THIS WILL THROW A NULLPOINTER EXCEPTION
for (String cookie : cookies) {
conn.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
}

// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(
conn.getInputStream()));

while (!(line2.contains("</html>"))) {
line = rd.readLine();
line2 += line;
}
// wr.close();
rd.close();

Die beiden fettmarkierten Codeteile sind die Stellen an denen ich Probleme vermute. Bei
for (String cookie : cookies) {conn.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
bekomme ich auch ne NullPointerException


Hat jemand eine Idee warum?

Berni
2012-02-03, 21:45:41
Wie siehts denn mit
String Cookie = conn.getHeaderField("Set-Cookie");
aus? Möglicherweise gibts ja auch Probleme mit Groß-/Kleinschreibung? Debug doch mal was bei getHeaderFields() zurückgeliefert wird.

Tiamat
2012-02-03, 21:48:12
Schau doch mal im Debugger, was da los ist.
Benötigt nur ein paar Klicks.

MartinB
2012-02-03, 23:26:13
Manchmal sieht man den Wald vor lauter Bäumen nicht.

Ja, es lag an dem "Set-Cookie", dieser Wert ist in Android 2.2 und älter nämlich "set-cookie". Darauf muss man aber erstmal kommen...

Berni
2012-02-04, 01:44:22
Eine Anmerkung habe ich noch: Generell solltest du alle Eventualitäten abfangen wenn du externe Seiten parsed (oder aber auch mit Userinput arbeitest). Es kann sich da immer mal was ändern und dann sollte die App nicht gleich abstürzen sondern halt eine Fehlermeldung bringen.

MartinB
2012-02-04, 09:15:34
Ja, da ist auch ein Try-Catch-Block um das ganze Server Zeugs. Das Problem dabei ist, dass man sich dann selber um den Stacktrace kümmern muss, wenn man die Exception abfängt. Tut man dies nämlich nicht, können User den Bugreport direkt ins Developer Panel schicken. Das ist eigentlich recht nützlich für den Programmierer, aber natürlich unschön für den Benutzer.

Berni
2012-02-04, 13:47:38
Einfach einen großen try/Catch-Block um das Ganze zu machen war auch nicht mein Gedanken sondern die tatsächlichen Fehler abzufangen ;)

Coda
2012-02-04, 14:45:49
Die korrekte Lösung ist das natürlich das ganze case insensitive zu machen.

MartinB
2012-02-04, 18:21:16
Und wie?

Ich das jetzt so
List<String> cookies = conn.getHeaderFields().get("Set-Cookie");
if (cookies==null )cookies = conn.getHeaderFields().get("set-cookie");

Das das nicht der Weisheit letzter Schluss ist, ist mir klar ;)

Coda
2012-02-04, 18:33:02
Indem du beispielsweise über die Keys loopst und mittels equalsIgnoreCase nach dem richtigen suchst anstatt get() zu verwenden.