1

Ich habe ein merkwürdiges Verhalten beim Lesen von Daten über einen REST-Dienst in meiner App.Die Zeichencodierung mit utf-8 bricht alle Daten, wenn nur ein unzulässiges Zeichen vorhanden ist

Ich kodiere immer meine REST-Dienste mit utf-8. Dies hat sich als eine sichere Wahl erwiesen - bis jetzt. Ich komme aus Dänemark und wir haben eine Handvoll Sonderzeichen, wie: æøå.

Also mit diesem bestimmten Datensatz hat der Benutzer einen Smiley in der App eingegeben - und die Daten wurden mit dem Server synchronisiert. Wenn die Daten anschließend an das Telefon zurückgeschickt werden ALLE Daten in der Anfrage wird "verschlüsselt". Wenn ich die gleiche Anfrage in einem anderen Tool (wie verschiedenen Browsern und z. B. PostMan) versuche, dann sieht alles Ok (Zeichensatz ist utf-8 und nur der Smiley kann nicht angezeigt werden). In meiner App werden jedoch alle nicht-englischen Zeichen verschlüsselt.

Klicken Sie auf here, um die URL mit dem Smiley zu sehen - und here, um die URL ohne den Smiley zu sehen (nur eine andere Zeitabschaltung). Edit: Die Links sind nicht mehr aktiv ....

ich einen kleinen Test-App erstellt haben, das Problem von innen Appcelerator zeigen:

Ausblick:

<Alloy> 
    <Window class="container"> 
     <View> 
      <Button id="label1" class="heading" onClick="reload1">Load with smiley</Button> 
      <Button id="label2" class="heading" onClick="reload2">Load without smiley</Button> 
      <ListView id="nameList" defaultItemTemplate="templateName"> 
       <Templates> 
        <ItemTemplate name="templateName"> 
         <Label bindId="name"/> 
        </ItemTemplate> 
       </Templates> 
       <ListSection> 
        <ListItem/> 
       </ListSection> 
      </ListView> 
     </View> 
    </Window> 
</Alloy> 

Stil:

".container": { 
    top: 20, 
    backgroundColor:"white", 
    orientationModes: [Ti.UI.PORTRAIT] 
} 
"Label": { 
    width: Ti.UI.SIZE, 
    height: Ti.UI.SIZE, 
    backgroundColor: 'transparent', 
    left:10, 
    color: "#000" 
} 

".heading": { top:15, 
    font: { 
     fontSize: '18dp', 
     fontStyle: 'bold' 
    } 
} 

"#label1":{left: 10} 
"#label2":{right: 10} 
"#nameList":{ 
    top:'50dp' 
} 

Controller:

function reload1(){ 
    reload('http://url1'); 
} 
function reload2(){ 
    reload('http://url2'); 
} 

function reload(url){ 
    var list = []; 
    $.nameList.sections[0].items = []; 

    var xhr = Ti.Network.createHTTPClient({ 
       timeout : 20000 
       }); 

    var name = 'speciesName'; 
    xhr.open('GET', url); 
    xhr.onload = function(e) { 
     var responseJSON = {}; 
     Ti.API.info("Response headers: " + this.getAllResponseHeaders()); 
     try { 
      responseJSON = JSON.parse(this.responseText); 
      if(responseJSON.data){ 
       _.each(responseJSON.data,function(rec){ 
        if(rec[name] && rec[name] != ''){ 
         var item = {template: "templateName",name : { text: rec[name] }}; 
         list.push(item); 
        } 
      }); 
      $.nameList.sections[0].items = list; 
      } 
     } catch (e) { 
      Ti.API.error('[REST API] apiCall PARSE ERROR: ' + e.message); 
      Ti.API.error('[REST API] apiCall PARSE ERROR: ' + this.responseText); 
      status = false; 
      error = e.message; 
     } 
    }; 
    // function called when an error occurs, including a timeout 
    xhr.onerror = function(e) { 
     Ti.API.debug(e.error); 
     alert('error'); 
    }; 
    xhr.send(); 
} 

$.index.open(); 
reload1(); 

Wenn Sie die App starten, werden die Daten mit "verschlüsselt" Zeichen zeigen. Dann können Sie mit den Schaltflächen oben zwischen den Datensätzen mit/ohne Smiley wechseln.

Das Problem ist auf iOS und Android konsistent. Ich laufe Ti SDK 5.1.2 - ich traue mich nicht zu upgraden, bis ich ein Update zu meiner "echten" App in Kürze abgegeben habe :-)

Idealerweise möchte ich auch den Smiley auf dem mobilen Gerät zeigen können. Allerdings kann ich damit leben, dass es nicht richtig angezeigt wird - solange es nicht den gesamten Datensatz verderbt.

Alle Gedanken/Ideen/Einsicht wird sehr geschätzt :-)

/John

Antwort

0

Ok Dies stellte sich als ein Problem heraus, das nicht mit Titanium/Appcelerator zusammenhing - abgesehen davon, dass die gesamte Anfrage abgebrochen wurde, wenn nur ein Zeichen nicht in den Zeichensatz passte.

Der Back-End-Server ist ein IBM XWork-Server und es stellte sich heraus, dass der REST-Dienst einen ResponseWriter (Java) verwendet, der Zeichen sendet. Wenn Sie dies so ändern, dass es bei DataOutputStream (Java) zurückgegeben wird, das einen Byte-Stream sendet, wurde das Problem gelöst.

Wenn jemand andere ähnliche Probleme haben, dann habe ich eine blog article about this geschrieben, wo Sie mehr erfahren können. Die Lösung ist für IBM XWork nicht spezifisch - aber gilt für alle Back-End Java verwenden :-)

/John

1

So ist die Saite kommt zurück vom Server als:

"Kommentare": "Huggede unter Træet og gav en helt fantastisk fight. \ nMin stang knikkede og jeg dumpede i åen ??????"

Smiley Emoji wurde als UTF-8-Codeeinheiten gesendet: ed a0 bd ed b8 80

Sie sollten JSON/JS als \uD83D\uDE00 =

entwertet werden Dies ist eine gute Ressource für das Betrachten Codierung Probleme https://r12a.github.io/apps/conversion/

+0

Danke für die Kommentare und Diskussion über TiSlack. Es war eine viel längere Reise zu der Lösung - wie ich als Antwort geschrieben habe :-) –

Verwandte Themen