XML HTTP post funktioniert nicht

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • XML HTTP post funktioniert nicht

    Hallo zusammen,

    Ich bin dabei eine kleine App zu entwickeln um meine Heizung zu steuern. Dafür möchte ich die von Hersteller entwickelte API benutzen. Hier ist eine Anleitung der API. Bis jetzt kann ich die Daten der Heizung von aus einer XML Datei unter einer URL auslesen. Nun muss ich aber auch die Daten unter der UML ändern können. Dafür versuche ich also ein HTTP Post auszuführen. Mein aktueller Code dafür sieht so aus:


    Quellcode

    1. public class PushData extends AsyncTask{
    2. private final String postUrl = "http://192.168.178.38/data/changes.xml";
    3. private final String postString = " <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
    4. " <Devices>\n" +
    5. " <Device>\n" +
    6. " <ID>EZR0114AF</ID>\n" +
    7. " <HEATAREA nr=\"4\">\n" +
    8. " <T_TARGET>18.7</T_TARGET>\n" +
    9. " </HEATAREA>\n" +
    10. " </Device>\n" +
    11. " </Devices>";
    12. @Override
    13. protected Object doInBackground(Object[] objects) {
    14. try {
    15. URL url = new URL(postUrl);
    16. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    17. conn.setReadTimeout(10000);
    18. conn.setConnectTimeout(15000);
    19. conn.setRequestMethod("POST");
    20. conn.setDoInput(true);
    21. conn.setDoOutput(true);
    22. String body = postString;
    23. OutputStream output = new BufferedOutputStream(conn.getOutputStream());
    24. output.write(body.getBytes());
    25. output.flush();
    26. Log.d("Success", postString);
    27. } catch (ProtocolException e) {
    28. e.printStackTrace();
    29. } catch (IOException e1) {
    30. e1.printStackTrace();
    31. } finally {
    32. }
    33. return null;
    34. }
    35. }
    Alles anzeigen

    Im LogCat wird "Success, ..." ausgegeben deshalb gehe ich davon aus, dass der Code eigentlich stimmen sollt. Jedoch werden, wie ich in der XML Datei unter der Url ablesen kann, die Daten (In diesen Fall die Solltemperatur) nicht geändert. Ich habe leider keine Ahnung woran das liegt, da ich ja keine Exception geworfen bekomme. Liegt es vielleicht an der API, dass diese nicht richtig funktioniert? Wenn Ich die Adresse zu der ich meine Daten senden soll im Firefox öffnen möchte bekomme ich nur eine Fehlermeldung.

    Ich freue mich über jede Meinung/Hilfe!

    Liebe Grüße,

    Jonas
  • Danke für die Antwort. Ich habe jetzt mal auf Grund des Artikels folgende Zeilen Code geändert:


    Quellcode

    1. //OutputStream output = new BufferedOutputStream(conn.getOutputStream());
    2. //output.write(body.getBytes());
    3. //output.flush();
    4. OutputStreamWriter outputStreamWriter = new OutputStreamWriter(conn.getOutputStream());
    5. outputStreamWriter.write(body);
    6. outputStreamWriter.flush();
    Leider scheint es immer noch nicht zu funktionieren. So langsam denke ich echt, dass es wohl an der API liegen muss, nichts was ich versuche funktioniert. Werde dann erstmal den Hersteller anschreiben.
  • Die API wird gehen teste es mit deinem Browser sowie in dem PDF File, oder nutze das win Programm . Ich denke es wird gehen. Es liegt mit sicherheit an der Übertragung zu dem Server vom Handy. An der API kann und will ich nicht glauben das wird der Hersteller getestet haben.
    Denke du musst dich noch etwas mit dem http Protokoll und der httpconnect beschäftigen.

    In deinem Code hast du es auch nicht so gemacht wie in dem Beispiel.
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von jogimuc ()

  • Bin mir auch ziemlich sicher das es in dem String mit "\n" nicht geht .
    Denn das ist eigentlich eine formatanweisung für eine neue zeile die Übersetzt werden muss. Mit sicherheit wird genau "\n" in deinen String und somit auch in deiner übertragennen Datei stehen. Und nicht z.B. ASCII 0x0A oder 0x0C für LF CR.
    Wenn dann Formatiere deinen String mit "format" ,und mit URLEncoder.encode wird er auch in den richtigen Zeichensatz konvertiert.
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von jogimuc ()

  • So also den zwischenschrit mit String.format( ...) brauchst du nicht .
    Die übersetzung mit URLEntcoder ja.
    Ob wirklich der UTF-8 Zeichensatz verwendet werden muss oder ein anderer weiss ich nicht genau dazu müsste ich mir nochmal deine API anschauen.


    String data = URLEncoder.encode(postString, "UTF-8");
    OutputStreamWriter output = new OutputStreamWriter(conn.getOutputStream());
    output.write(data);
    output.flush() ;
    Ein Feedback auf Tipps ist auch schön. :P
  • Du hast recht, mit dem Testprogramm funktioniert es also liegt es wohl doch an meinem Code. Habe mal ein Bild mit der XML Datei angehangen, die das Testprogramm benutzt.

    Ich habe jetzt mal in meinem String "\n" raus gelöscht. Das Problem ist, dass ich version=\"1.0\" mit \ schreiben muss da es sind mit den "-Zeichen Syntaxfehler gibt. Weißt du wie ich das lösen könnte?

    String data = URLEncoder.encode(postString, "UTF-8"); habe ich versucht aber das scheint auch nicht zu klappen, außerdem wird mit im LogCat für data folgendes ausgegeben: +%3CDevices%3E+%3CDevice%3E+%3CID%3EEZR0114AF%3C%2FID%3E+%3CHEATAREA+nr%3D%224%22%3E+%3CT_TARGET%3E18.0%3C%2FT_TARGET%3E+%3C%2FHEATAREA%3E+%3C%2FDevice%3E+%3C%2FDevices%3E

    Das kann ja eigentlich auch nicht richtig sein.

    Denkst du es liegt wirklich an meinem String oder kann es auch trotzdem noch an anderen Stellen in meinem Code liegen.
    Bilder
    • heizung.PNG

      42,52 kB, 1.189×796, 49 mal angesehen
  • Hi dein String so wie er am Anfang war ist schon richtig auch die Zeilenumbrüche "/n" (UTF-8 %0A) stimmen.
    Nur hast du ihn nicht in den Zeichensatz UTF-8 Konvertiert das macht URLEntcoder.
    Dein String vom Anfang sieht bei mir so aus.

    Quellcode

    1. %3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%0A+%3CDevices%3E%0A+%3CDevice%3E%0A+%3CID%3EEZR0114AF%3C%2FID%3E%0A+%3CHEATAREA+nr%3D%224%22%3E%0A+%3CT_TARGET%3E18.7%3C%2FT_TARGET%3E%0A+%3C%2FHEATAREA%3E%0A+%3C%2FDevice%3E%0A+%3C%2FDevices%3E
    in welchen Zeichensatz deine Steuerung es haben will weiss ich nicht.

    im LogCat für data folgendes ausgegeben:
    +%3CDevices%3E+%3CDevice%3E+%3CID%3EEZR0114AF%3C%2FID%3E+%3CHEATAREA+nr%3D%224%22%3E+%3CT_TARGET%3E18.0%3C%2FT_TARGET%3E+%3C%2FHEATAREA%3E+%3C%2FDevice%3E+%3C%2FDevices%3E
    Das kann ja eigentlich auch nicht richtig
    ist schon richtig nur fehlt bei dir die erste Zeile und der Zeilenumbruch.
    Die erste Zeile <?xml version=\"1.0\" encoding=\"UTF-8\"?> wird aber die API brauchen.
    Ein in UTF-8 Kodirter Text sieht nun mal so aus mit den Prozent Zeichen. Schaue dir die Zeichensätze im Internet mal an.
    ASCII hatte immer nur ein Byte pro Zeichen somit sind max 256 Zeichen (Druckbar oder auch nicht Druckbare Zeichen wie 0A 0C) möglich das reichte nicht für alle möglichen Zeichen und Sprachen( Chinesische Schriftzeichen) aus, also erfand man den Unicode der 32 Bit breit ist . Um Speicherplatz und Bandbreite zu sparen wurde der UTF-8 erfunden.


    Der meist für Http benutz wird.

    auch könnte es sinvoll sein die parameter in der URLConnection zu setzen

    con.setRequestProperty( "Content-Type","application/x-www-form-urlencoded" );
    con.setRequestProperty( "charset", "utf-8");
    con.setRequestProperty( "Content-Length", String.valueOf(data.getBytes().length) );

    Mal eine andere Frage die Premission hast du gesetzt oder?
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von jogimuc ()

  • Danke für deine Hilfe!

    Also das ist mein Code zum aktuellen stand:

    Quellcode

    1. public class PushData extends AsyncTask{
    2. private final String postUrl = "http://192.168.178.38/data/changes.xml";
    3. private final String postString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
    4. " <Devices>\n" +
    5. " <Device>\n" +
    6. " <ID>EZR0114AF</ID>\n" +
    7. " <HEATAREA nr=\"4\">\n" +
    8. " <T_TARGET>18.7</T_TARGET>\n" +
    9. " </HEATAREA>\n" +
    10. " </Device>\n" +
    11. " </Devices>";
    12. @Override
    13. protected Object doInBackground(Object[] objects) {
    14. try {
    15. URL url = new URL(postUrl);
    16. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    17. conn.setReadTimeout(10000);
    18. conn.setConnectTimeout(15000);
    19. conn.setRequestMethod("POST");
    20. conn.setDoInput(true);
    21. conn.setDoOutput(true);
    22. String data = URLEncoder.encode(postString, "UTF-8");
    23. conn.setRequestProperty( "Content-Type","application/x-www-form-urlencoded" );
    24. conn.setRequestProperty( "charset", "utf-8");
    25. conn.setRequestProperty( "Content-Length", String.valueOf(data.getBytes().length) );
    26. //OutputStream output = new BufferedOutputStream(conn.getOutputStream());
    27. //output.write(body.getBytes());
    28. //output.flush();
    29. OutputStreamWriter outputStreamWriter = new OutputStreamWriter(conn.getOutputStream());
    30. outputStreamWriter.write(data);
    31. outputStreamWriter.flush();
    32. Log.d("Success", data);
    33. InputStream answerStream = conn.getInputStream();
    34. String answer = getAnswer(answerStream);
    35. Log.d("answer", answer);
    36. } catch (ProtocolException e) {
    37. e.printStackTrace();
    38. } catch (IOException e1) {
    39. e1.printStackTrace();
    40. } finally {
    41. }
    42. return null;
    43. }
    44. public String getAnswer(InputStream is){
    45. BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    46. StringBuilder stringBuilder = new StringBuilder();
    47. String currentLine;
    48. try {
    49. while ((currentLine = reader.readLine()) != null){
    50. stringBuilder.append(currentLine);
    51. stringBuilder.append("\n");
    52. }
    53. } catch (IOException e) {
    54. e.printStackTrace();
    55. }
    56. return stringBuilder.toString().trim();
    57. }
    58. }
    Alles anzeigen



    Habe mir das Video angeguckt aber außer der Fähigkeit die Antwort zu erhalten habe ich nicht viel verändert. Ich bekomme jetzt auch den gleichen String wie du ausgegeben:


    Quellcode

    1. %3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%0A+%3CDevices%3E%0A+%3CDevice%3E%0A+%3CID%3EEZR0114AF%3C%2FID%3E%0A+%3CHEATAREA+nr%3D%224%22%3E%0A+%3CT_TARGET%3E18.7%3C%2FT_TARGET%3E%0A+%3C%2FHEATAREA%3E%0A+%3C%2FDevice%3E%0A+%3C%2FDevices%3E


    Funktionieren tut es leider immer noch nicht.

    Mit Permission meinst du die Internet Berechtigung im manifest?


    Quellcode

    1. <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    Die habe ich natürlich gegeben.
  • Was steht denn im Antwortstring?
    Wird überhaupt eine Verbindung zum Server Steuerung aufgebaut.
    Versuche mal eine Datei vom Server zu lesen.
    Notfalls richte dir einen Server ein auf den du mit dem win Programm Daten sendest als ob es deine Steuerung wäre. Dann kannst du sehen was da geschickt wird.
    Und was dein Handy schickt.

    Ps. Könntest auch einen Http Sniffer benutzen und die Verbindung zum Server Steuerung mit dem Windows Programm aufzeichnen.
    z.B. HTTPNetworkSniffer
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von jogimuc ()

  • Hi habe dir mal das Packet was das windows Proramm an den Server sendet aufgezeichnet.
    Siehe Bild.
    daraus folgt conn.setRequestProperty( "Content-Type","txt/xml" );

    Ausserdem wird der von Windows übliche Zeilenumruch verwendet ( Hex 0x0D 0x0A ) (String "\r\n" )
    Bilder
    • Http.png

      49,63 kB, 1.034×777, 49 mal angesehen
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von jogimuc ()

  • Andy61 wenn du den Artikel vom Anfang an list würst du sehen, das er eine handelsübliche Heizungs Steuerung hat die eben genau diese XML basierende API anbietet. Und die will er benutzen. Was man ihr schicken und was sie antwortet steht eigentlich recht gut beschrieben in der Doku die er im ersten Post zur Verfügung gestellt hat.
    Verbesserungsvorschläge wie Json satt XML kannst du ja mal an den Hersteller schicken.
    Die Steuerung bietet auch ein Web Interface und eine XML API über den Browser. Ebenfalls gibt es eine app. Er hat es sich eben in den kopf gesetz es selber zu machen.
    Scheint aber ein par Schwierigkeiten beim Umgang mit http in Java zu haben.
    Dabei wollte ich ihn helfen.

    Leider hat er noch nicht auf meine Fragen wie was im antwortstring steht geantwortet.
    Denn wenn er eine Antwort bekommt heißt das das zu mindestens erstmal eine Verbindung mit der Steuerung vorhanden ist. Die Fehler Codes kann man auch beim Hersteller im Internet nachschauen.
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von jogimuc ()

  • Andy61 Postman ist keine schlechte Idee, aber das geht glaube ich nur im Browser. Berichtige mich wenn ich falsch liege.
    Da es ein Win Programm (exe) ist und nicht im Browser läuft habe ich einen Sniffer benutzt um zu sehen was das Prog an die Steuerung schickt.

    Bei der Kommunikation über den Browser, wird bestimmt erst eine "Get" Request an den Server geschickt. Denn
    der Brauser schickt ohne extra angaben immer einen Get Request. ( "http://ip/data/changes.xml" ).
    Daraufhin wird der Server eine Html Seite mit einem Formular schicken, wo mann die mit "Post" zusendende Befehlsdatei auswählen und senden kann.
    Bei dieser Kommunikation würde Postman helfen. Da alles im Browser abläuft.

    Wie gesagt will er gleich ein "Post" an den Server schicken so wie es das Windows Programm oder die App auch macht.

    Wie die Komunikation im Browser genau abläuft hat er uns leider noch nicht geschildert.
    Ist aber für sein Vorhaben auch nicht so wichtig.
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von jogimuc ()

  • So habe deinen Code angepasst. Die Übersetzung in den UTF-8 Code braucht man scheinbar nicht.

    Java-Quellcode

    1. public class MainActivity extends AppCompatActivity {
    2. @Override
    3. protected void onCreate(Bundle savedInstanceState) {
    4. super.onCreate(savedInstanceState);
    5. setContentView(R.layout.activity_main);
    6. PushData pushData = new PushData();
    7. pushData.execute("A");
    8. }
    9. public class PushData extends AsyncTask {
    10. private final String postUrl = "http://192.168.0.103/data/changes.xml";
    11. private final String postString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
    12. "<Devices>\r\n" +
    13. " <Device>\r\n" +
    14. " <ID>EZR0114AF</ID>\r\n" +
    15. " <HEATAREA nr=\"4\">\r\n" +
    16. " <T_TARGET>18.7</T_TARGET>\r\n" +
    17. " </HEATAREA>\r\n" +
    18. " </Device>\r\n" +
    19. "</Devices>";
    20. @Override
    21. protected Object doInBackground(Object[] objects) {
    22. try {
    23. URL url = new URL(postUrl);
    24. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    25. conn.setReadTimeout(10000);
    26. conn.setConnectTimeout(15000);
    27. conn.setRequestMethod("POST");
    28. conn.setDoInput(true);
    29. conn.setDoOutput(true);
    30. String data;
    31. //data = URLEncoder.encode(postString, "UTF-8");
    32. data = postString;
    33. conn.setRequestProperty( "Content-Type","text/xml" );
    34. conn.setRequestProperty( "HTTP_CONNECTION","Keep-Alive" );
    35. conn.setRequestProperty( "Content-Length", String.valueOf(data.getBytes().length) );
    36. conn.setRequestProperty( "Exepect","100-continute" );
    37. OutputStreamWriter outputStreamWriter = new OutputStreamWriter(conn.getOutputStream());
    38. outputStreamWriter.write(data);
    39. outputStreamWriter.flush();
    40. Log.d("Success", data);
    41. InputStream answerStream = conn.getInputStream();
    42. String answer = getAnswer(answerStream);
    43. Log.d("answer", answer);
    44. outputStreamWriter.close();
    45. answerStream.hashCode();
    46. conn.disconnect();
    47. } catch (ProtocolException e) {
    48. e.printStackTrace();
    49. } catch (IOException e1) {
    50. e1.printStackTrace();
    51. } finally {
    52. }
    53. return null;
    54. }
    55. public String getAnswer(InputStream is){
    56. BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    57. StringBuilder stringBuilder = new StringBuilder();
    58. String currentLine;
    59. try {
    60. while ((currentLine = reader.readLine()) != null){
    61. stringBuilder.append(currentLine);
    62. stringBuilder.append("\n");
    63. }
    64. } catch (IOException e) {
    65. e.printStackTrace();
    66. }
    67. return stringBuilder.toString().trim();
    68. }
    69. }
    70. }
    Alles anzeigen
    Im Anhang zwei Bilder mit dem Http Frame von dem WinProgramm Alpha2 und von dem was das Handy erzeugt.
    Sind in den wichtigsten sachen gleich. Die IP und ID musst du anpassen.
    Bilder
    • alpha2.png

      127,52 kB, 1.280×1.024, 48 mal angesehen
    • Handy.png

      135,89 kB, 1.280×1.024, 52 mal angesehen
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von jogimuc ()