2013-05-03 10 views
8

Sono abbastanza nuovo, in modo da non essere troppo duro :)Perché la mia stringa Unicode viene danneggiata, quando viene passata dall'applet Java allo script Java?

domanda (tl; dr)

Sto affrontando un problema che passa un unicode String da un incorporato javax.swing.JApplet in una pagina web per la parte di Java Script. Io non sono sicuro che questo è se un bug o un fraintendimento delle tecnologie coinvolte:

Problema

voglio passare una stringa unicode da un applet Java a Java Script, ma l'String Ottiene incasinato. Stranamente, il problema non si verifica in Internet Explorer 10 ma in Chrome (v26) e Firefox (v20). Non ho ancora provato altri browser.

La stringa restituita sembra essere a posto, tranne per l'ultimo carattere Unicode. Il risultato nel Java Script Debugger e pagina Web potrebbe essere:

  • abc → abc
  • 表示 → 表
  • ま → ま
  • ウ ォ ッ チ リ ス ト → ウ ォ ッ チ リ ス
  • ア ッ プ ロ ー ド→ ア ッ プ ロ ー
  • ホ →
  • ホ → ホ (non deterministica)
  • ア ッ プ ロ ー ド abc → ア ッ プ ロ ー ド abc

La stringa sembra avere corrotto alle ultime byte. Se termina con un carattere ASCII, la stringa è ok. Inoltre il problema non si verifica all'interno di ogni combinazione e anche non ogni volta (non sono sicuro su questo). Pertanto sospetto un bug e temo di pubblicare una domanda non valida.

Test Set Up

Un insieme minimalista up include un applet che restituisce un po 'di unicode stringhe (UTF-8):

/* TestApplet.java */ 
import javax.swing.*; 

public class TestApplet extends JApplet { 

private String[] testStrings = { 
      "abc", // OK (because ASCII only) 
      "表示", // Error on last Character 
      "表示", // Error on last Character 
      "ホーム ", // OK (because of *space* after ム) 
      "アップロード", ... }; 
    public TestApplet() {...};  // Applet specific stuff 

    ... 

    public int getLength() { return testStrings.length;}; 

    String getTestString(int i) { 
     return testStrings[i]; // Build-in array functionality because of IE. 
    } 
} 

La pagina Web corrispondente con java script potrebbe essere la seguente:

/* test.html */ 
<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
    </head> 
    <body> 
     <span id="output"/> 
     <applet id='output' archive='test.jar' code=testApplet/> 
    </body> 

    <script type="text/javascript" charset="utf-8"> 
     var applet = document.getElementById('output'); 
     var node = document.getElementById("1"); 
     for(var i = 0; i < applet.getLength(); i++) { 
      var text = applet.getTestString(i); 
     var paragraphNode = document.createElement("p"); 
     paragraphNode.innerHTML = text; 
     node.appendChild(paragraphNode); 
     } 
    </script> 
</html> 

Ambiente

sto lavorando su Windows 7 a 32 bit con l'attuale versione Java 1.7.0_21 utilizzando il "Plug-in Java di prossima generazione 10.21.2 per i browser Mozilla". Ho avuto alcuni problemi con il mio sistema operativo locale, ma ho provato diverse impostazioni regionali (inglese, giapponese, cinese).

In caso di stringa corrotta, chrome mostra caratteri non validi (ad es. ). Firefox, d'altra parte, rilascia la stringa completamente, se dovesse terminare con .

Internet Explorer riesce a visualizzare correttamente le stringhe.

Soluzioni?

Sono in grado di immaginare diverse soluzioni, tra cui l'escaping/unescaping e l'aggiunta di un "carattere finale" che viene rimosso tramite lo script java. In realtà sto pensando di scrivere contro il Webkit di Android, e non l'ho testato lì.

Poiché vorrei continuare i test su Chrome, (a causa della tecnologia e del comfort di Webkit), spero che ci sia una soluzione banale al problema, che potrei aver trascurato.

+2

Sono interessato a quale sia il vero problema. Un'idea che ho trovato è: assicurati che 'javac' e/o' jar' utilizzino la codifica UTF8 - se non lo specifichi, usa l'impostazione predefinita della macchina (che * potrebbe * essere un problema) – Ian

+1

Grazie! Ci proverò più tardi. Voglio sottolineare che il flusso di dati dallo script java all'applet (parametro di chiamata) funziona come previsto. Solo il ritorno viene incasinato. – Inuniku

+1

Assolutamente. Hai mostrato/spiegato che funziona tutto bene, tranne che per la stringa restituita in casi speciali (l'ultimo carattere nella stringa restituita ha un carattere unicode). Penso che tu abbia spiegato la situazione molto bene e abbia disposto tutto in modo molto organizzato :) – Ian

risposta

1

Se si sta testando in Chrome/Firefox

Si prega di sostituire prima linea con questo e poi testarlo,

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 

DOCTYPE ha un valore significativo, mentre il browser identifica la pagina.

Transitional/loose it i tipi che è possibile utilizzare con Unicode. Si prega di verificare e rispondere ..

+0

Grazie per il vostro contributo! Ho provato questo, ma ancora senza fortuna. – Inuniku

+0

Puoi pubblicare html della pagina dopo la generazione della pagina/link della pagina (se live), che ti aiuterà ulteriormente. – MarmiK

1

suggerisco di impostare un punto di interruzione

paragraphNode.innerHTML = text; 

e controllare il testo nella console JavaScript, per esempio con

console.log(escape(text)); 

o

console.log(encodeURIComponent(text)); 

o

for (i=0; i < text.length; i++) { 
    console.log("i = "+i); 
    console.log("text.charAt(i) = "+text.charAt(i) 
    +", text.charCodeAt(i) = "+text.charCodeAt(i)); 
} 

Vedi anche

http://www.fileformat.info/info/unicode/char/30a6/index.htm

https://developer.mozilla.org/en-US/docs/DOM/window.escape (che non è parte di alcuna stan Dard)

e

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURIComponent

o risorse simili.

I file sorgente potrebbero non essere nella codifica presunta (UTF-8).

JavaScript assume UTF-16 stringhe:

http://www.ecma-international.org/ecma-262/5.1/#sec-4.3.16

Java assume anche UTF-16:

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html

Il comando Linux o Cygwin file in grado di mostrare la codifica dei file .

Vedi

http://linux.die.net/man/1/file (non hanno trovato un punto di riferimento uomo kernel.org)

+0

Grazie mille per la tua risposta elaborata! Con la funzione 'encodeURI' sono stato in grado di generare i byte" corrotti "finali in chrome: Sembrano tutti finire con'% EF% BF% BD% EF% BF% BD% 00'. Non sono sicuro se sia la vera caratteristica, perché firefox non mostra affatto una stringa corrotta (restituisce una stringa con una lunghezza pari a 0 in questo caso). In realtà sono stato in grado di risolvere il problema per il mio sistema operativo (vedi la mia risposta imbarazzante). Ma influenza ancora altre impostazioni locali ... Forse la domanda rimane valida con le modifiche. – Inuniku

0

Va bene, io sono un po 'imbarazzato, perché ho pensato ho provato a sufficienza: in realtà stavo usando non locale latino (e.g cinese (PRC) o giapponese (Giappone) nel sistema Windows locale settings. Quando ho cambiato di nuovo a inglese (USA) o tedesco (Germania) tutto ha funzionato come previsto.

Mi chiedo ancora, perché potrebbe influire su Chrome & Mozilla in un modo così strano, perché i browser Java e moderni dovrebbero essere basati su unicode; Quindi non accetterò questo come risposta! Il problema si ripresenta passando al giapponese e lo testerò su diversi sistemi.

Voglio ringraziare tutti i poster per l'input illuminante ... e mi impegnerò ancora a risolvere questa domanda.

1

È necessario assicurarsi di aggiungere il seguente argomento Java per il tag applet/embed:

-Dfile.encoding = utf-8

cioè java_arguments = "- Dfile.encoding = utf-8 "

Altrimenti ci si aspetta e tratta l'applet come testo ASCII.