Probleme mit HTTP POST

  • 8 Antworten
  • Letztes Antwortdatum
Micka

Micka

Fortgeschrittenes Mitglied
1
Hallo,
ich habe bei meinem aktuellen Projekt leider ein Paar Probleme.
Via HTTP Post möchte ich ein JSON Array vom AndroidGerät zum Server (zum testen momentan lokal xampp) schicken. Ich habe es nun auch soweit hinbekommen das alles läuft, aber nicht zufriedenstellend.
Ich muss dazu sagen PHP ist für mich noch eher Neuland.

ich versuche mal kurz zu beschreiben wie ich dabei vorgegangen bin.

In meiner APP wird ein Asynctask ausgeführt der die Synchronisation übernimmt. Der Task ruft sich selbst die lokalen sowie die auf dem Server gespeicherten Datenbanken ab. Anschließend wird dann Tabellenweise kontrolliert ob die lokale Tabelle auch online existiert. Wenn nicht wird der Name in ein Array Gespeichert. Später wird dann dann der Inhalt der lokalen Tabelle abgerufen und via HTTP zum Server übertragen.

Mein Problem momentan, ich kann nur maximal 60 (bei 69 schlägt es fehl) Zeilen aufeinmal zum Server schicken, andernfalls bekomme ich die Meldung der Header sei zu groß.
Genauer gesagt ist das hier die Antwort vom Server:

Code:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
  <html><head>
  <title>400 Bad Request</title>
  </head><body>
  <h1>Bad Request</h1>
  <p>Your browser sent a request that this server could not understand.<br />
  Size of a request header field exceeds server limit.<br />
  <pre>
  json
  </pre>
  </p>
  <hr>
  <address>Apache/2.4.12 (Win32) OpenSSL/1.0.1m PHP/5.6.11 Server at localhost Port 80</address>
  </body></html>

Ich bin mir nun nicht sicher ob ich das einfach so hinnehmen muss oder ob ich die Daten evtl fasch sende.
Da der gesamte Asynctask ziemlich viel Code beinhaltet (vergleich der Tabellen...) hänge ich diesen als TXT Datei an meinen post an und poste im folgenden nur die Methode, die den Insert auf dem Webserver betrifft.
Code:
private String insertInTable(ArrayList<Data> insert2DataList) throws JSONException
  {
  String insertPhpResponse="";
  // Insert Data to Table
  JSONObject json;
  JSONArray postjson=new JSONArray();
  HttpClient inserthttpclient = new DefaultHttpClient();
  //HttpPost inserthttppost = new HttpPost("http://192.168.192.34/SyncTableToServerBackup.php");
  HttpPost inserthttppost = new HttpPost("http://192.168.192.34/SyncTableToServer.php");
  try
  {
  // JSON data:
  Data data;
  for(int i = 0; i < insert2DataList.size(); i++)
  {
  json = new JSONObject();
  data = insert2DataList.get(i);
  int value1 = Integer.parseInt(data.getvalue1String(), 2);
  int value2 = Integer.parseInt(data.getvalue2(), 2);
  int value3 = Integer.parseInt(data.getvalue3(), 2);
  int value4 = Integer.parseInt(data.getvalue4(), 2);
  int value5 = Integer.parseInt(data.getvalue5String(), 2);
  String DATA = data.getDataHex();

  json.put("value1", value1);
  json.put("value2", value2);
  json.put("value3", value3);
  json.put("value4", value4);
  json.put("value5", value5);
  json.put("data", DATA);
  json.put("tablename", this.tablename);
  postjson.put(i, json);
  }


  // Post the data:
  inserthttppost.setHeader("json",postjson.toString());

  // Execute HTTP Post Request
  HttpResponse response = inserthttpclient.execute(inserthttppost);

  // for JSON:
  /*if(response != null)
  {
  //Log.i(LOGTAG, "SyncTableToServerTask - insertInTable() - postData() - if(response != null) ");
  InputStream is = response.getEntity().getContent();

  BufferedReader reader = new BufferedReader(new InputStreamReader(is));
  StringBuilder sb = new StringBuilder();

  String line = null;
  try
  {
  //Log.i(LOGTAG, "SyncTableToServerTask - insertInTable() - postData() - if(response != null) - try ");
  while ((line = reader.readLine()) != null)
  {
  //Log.i(LOGTAG, "SyncTableToServerTask - insertInTable() - postData() - if(response != null) - try -while");
  sb.append(line + "\n");
  }
  } catch (IOException e)
  {
  //Log.i(LOGTAG, "SyncTableToServerTask - insertInTable() - postData() - if(response != null) - try -catch (IOException e)");
  insertPhpResponse ="EXCEPTION";
  e.printStackTrace();
  } finally
  {
  //Log.i(LOGTAG, "SyncTableToServerTask  - insertInTable() - postData() - if(response != null) - try -finally");
  try
  {
  //Log.i(LOGTAG, "SyncTableToServerTask - insertInTable() - postData() - if(response != null) - try -finally -try");
  is.close();
  } catch (IOException e)
  {
  //Log.i(LOGTAG, "SyncTableToServerTask - insertInTable() - postData() - if(response != null) - try -finally -catch (IOException e)");
  insertPhpResponse ="EXCEPTION";
  e.printStackTrace();
  }
  }
  insertPhpResponse = insertPhpResponse + sb.toString();
  }*/
  }catch (ClientProtocolException e)
  {
  insertPhpResponse ="EXCEPTION";
  // TODO Auto-generated catch block
  } catch (IOException e)
  {
  insertPhpResponse ="EXCEPTION";
  // TODO Auto-generated catch block
  }
  Log.i(LOGTAG, "INSERTINTABLE ENDE");
  return insertPhpResponse;
  }
  }

an folgender Stelle übergebe ich das JSON Array dem HTTPPost, ich glaube da ist was falsch.

// Post the data:
inserthttppost.setHeader("json",postjson.toString());

// Execute HTTP Post Request
HttpResponse response = inserthttpclient.execute(inserthttppost);

Ist es richtig das Array als String in den Header zu packen?
Ich habe es auch mal anders probiert:

// Post the data:
inserthttppost.setHeader("json",json.toString());
inserthttppost.getParams().setParameter("jsonpost",postjson);

// Execute HTTP Post Request
System.out.print(json);
HttpResponse response = httpclient.execute(inserthttppost);

Diese Methode wirft zwar keine Fehler, aber ich habe es so nicht geschafft das JSON Array mittels PHP anzunehmen, evtl mache ich auch da etwas falsch.

Wer bis hierhin gelesen hat verdient alleine dafür schonmal ein fettes Dankeschön. Ich hoffe ihr könnt mir helfen, da die Performance mit 60Zeilen pro http Post doch eher mies ist.
 

Anhänge

  • SyncTableToServerTask.txt
    15,5 KB · Aufrufe: 114
Übertrag den Inhalt (also deine JSON-Zeichenkette) im Body und nicht im Header. Dafür ist der Body doch da.

EDIT: Wenn dir PHP nicht liegt, wieso nutzt du es dann? Gibt es da irgendeinen Zwang?
 
Hallo,
hab nur mal schnell drüber geschaut, bin gerade auf dem Sprung.
"if((serverTables.length-1) == 0)" sieht meiner Meinung nach schonmal nicht gut aus^^
Schaue später aber nochmal...
 
missspelled schrieb:
Hallo,
hab nur mal schnell drüber geschaut, bin gerade auf dem Sprung.
"if((serverTables.length-1) == 0)" sieht meiner Meinung nach schonmal nicht gut aus^^
Schaue später aber nochmal...
das -1 ist weil der Server als letztes Array Element bei der Antwort immer ein "ENDE" ins Array packt.
die Problematik ob das abrufen der Tabellen klappt steht hier aktuell aber auch nur passiv zur Debatte. Im Moment ist mir erstmal wichtig das die Performance besser wird. Danke

die angelegten Tabellen werden momentan eh noch nicht in die dafür vorgesehen Tabelle eingetragen, daher ist die ServerTables antwort aktuell immer ein Array mit nur einem Eintrag.

Thyrion schrieb:
Übertrag den Inhalt (also deine JSON-Zeichenkette) im Body und nicht im Header. Dafür ist der Body doch da.
Da sagst du was....ich weiß leider nicht wie. Ich habe mir ein Tutorial rausgesucht und bin froh das ich das ans laufen bekommen habe.
The Simplest Way to POST Parameters Between Android and PHP (Android SDK) | Fahmi Rahman


Thyrion schrieb:
EDIT: Wenn dir PHP nicht liegt, wieso nutzt du es dann? Gibt es da irgendeinen Zwang?
Ich kenne keine Andere Methode Daten vom Android Smartphone zum Webserver zu synchronisieren. Ich bin für alle Vorschläge offen, lerne gerne neues.
 
Micka schrieb:
Da sagst du was....ich weiß leider nicht wie. Ich habe mir ein Tutorial rausgesucht und bin froh das ich das ans laufen bekommen habe.
The Simplest Way to POST Parameters Between Android and PHP (Android SDK) | Fahmi Rahman

Schau dir mal Retrofit von Square an. Das kann echtes Post und du ersparst dir das JSON parsen/builden.

Ich kenne keine Andere Methode Daten vom Android Smartphone zum Webserver zu synchronisieren. Ich bin für alle Vorschläge offen, lerne gerne neues.

Java, Ruby, ASP, etc.. Da gibt es tausende
Wenn du natürlich keinen Server sondern nur Webspace hast sieht es mau aus mit Alternativen zu PHP. Die Google App Engine ist bis zu einem gewissen Umfang kostenlos. Da kannst du richtige Java WebApps hochladen.
 
  • Danke
Reaktionen: Micka
Momentan habe ich nur einen simplen xampp server zur Verfügung. Wieviel Technik später verfügbar ist weiß ich zum jetzigen Zeitpunkt noch nicht
 
Fürn Anfang schätze ich sind die Daten im Body die beste Methode. Wenn ich wüsste wie

Thyrion wollte ja später nochmal reingucken. Evtl kann er mir ja direkt zeigen wie ich ein Array oder die Arraylist richtig absende und in php wieder annehme
 
Zuletzt bearbeitet:
Ich habe nun ein wenig gegoogelt. Ich schätze ich habe die Daten nun im Body durch folgenden Weg:
Code:
StringEntity se = new StringEntity(postjson.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
inserthttppost.setEntity(se);

darauf zugreifen kann ich nun auch:
Code:
$dataarray = json_decode(file_get_contents('php://input'));
for ($i = 0; $i < count($dataarray); $i++)
    {
        $eigeneid = $dataarray[$i]->eigeneid;
        $ide = $dataarray[$i]->ide;
        $dlc = $dataarray[$i]->dlc;
        $rtr = $dataarray[$i]->rtr;
        $canid = $dataarray[$i]->canid;
        $data = $dataarray[$i]->data;
    }
 
Zuletzt bearbeitet:
Meine Probleme sind dann jetzt erstmal gelöst. Allerdings überlege ich gerade noch wie ich in PHP einen Bulkinsert der Daten bewerkstelligen kann, aber das ist ein anderes Thema.
Falls mal jemand auf diesen Beitrag hier stößt poste ich mal meine aktuelle funktionierende Lösung:

Zuerst der Code der in der App notwendig ist um die Daten loszusenden (Sollte in einem Asynctask oder Service ausgeführt werden wegen NetworkOnMainThreadException):
Code:
JSONObject json = new JSONObject();
JSONArray postjson = new JSONArray();
HttpClient inserthttpclient = new DefaultHttpClient();
HttpPost inserthttppost = new HttpPost("URL DER PHPH  DATEI");
//Daten in ein JSON Array packen
for(.....)
{
   json.put("value1", value1);
   json.put("value2", value2);
   json.put("value3", value3);
   json.put("value4", value4);
   json.put("value5", value5);
   json.put("value6", value6);
   json.put("tablename", tablename);
   postjson.put(i, json);
}
// Post the data:
StringEntity se = new StringEntity(postjson.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
inserthttppost.setEntity(se);

// Execute HTTP Post Request
HttpResponse response = inserthttpclient.execute(inserthttppost);

//Die Antwort kann man noch auswerten
String insertPhpResponse ="";
if(response != null)
{
    try
    {
       is = response.getEntity().getContent();
    } catch (IOException e)
    {
       e.printStackTrace();
    }
   BufferedReader reader = new BufferedReader(new InputStreamReader(is));
   StringBuilder sb = new StringBuilder();
   String line = null;
   try
   {
      while ((line = reader.readLine()) != null)
      {
         sb.append(line + "\n");
      }
   } catch (IOException e)
   {
       insertPhpResponse ="EXCEPTION";
       e.printStackTrace();
    } finally
   {
       try
      {
        is.close();
      } catch (IOException e)
    {
      insertPhpResponse ="EXCEPTION";
      e.printStackTrace();
    }
  }
insertPhpResponse = insertPhpResponse + sb.toString();

Und hier noch die dazu passende PHP Datei:

Code:
<?php
    $json = $_SERVER['HTTP_JSON'];
    $dataarray = json_decode(file_get_contents('php://input'));     
    $servername = "localhost";
    $username = "testuser";
    $passwd = "testpw";
    $dbname = "db";
    $tablename = $dataarray[0]->tablename;
  
    $conn = mysql_connect($servername, $username, $passwd, $dbname);
       if(!$conn)
      {
        die("Connection failed" . mysql_error());
      }

      mysql_select_db($dbname);
      $result = mysql_query("CREATE TABLE  IF NOT EXISTS $tablename (VALUE1 INT, VALUE2 INT, VALUE3 INT, VALUE4 INT, VALUE5 INT, VALUE6 VARCHAR(100));") or die(mysql_error());
    if($result != 1)
    {
        echo "\n"." CREATE RESULT : "."\n".$result."\n"."\n";
    }
   for ($i = 0; $i < count($dataarray); $i++)
    {
        $value1 = $dataarray[$i]->value1;
        $value2 = $dataarray[$i]->value2;
        $value3 = $dataarray[$i]->value3;
        $value4 = $dataarray[$i]->value4;
        $value5 = $dataarray[$i]->value5;
        $value6 = $dataarray[$i]->value6;
        $result = mysql_query("INSERT INTO $tablename (VALUE1, VALUE2, VALUE3, VALUE4, VALUE5, VALUE6) VALUES($value1, $value2, $value3, $value4, $value5, '$value6' )") or die(mysql_error());
        if($result != 1)
        {
            echo "\n"." INSERT RESULT : "."\n".$result."\n"."\n";
        }
    }  
?>

um das ganze in einer Transaktion auszuführen reicht eine kleine Änderung der PHP Datei:
Vor der Zählschleife einfach
Code:
$result = mysql_query("BEGIN") or die (mysql_error());
einfügen und nachher
Code:
mysql_query("COMMIT") or die (mysql_error());
.
 
Zuletzt bearbeitet:
Zurück
Oben Unten