2013-05-03 8 views
8

Jestem całkiem nowy, więc nie bądź zbyt surowy :)Dlaczego mój ciąg znaków Unicode ulega uszkodzeniu po przejściu z apletu Java do Java Script?

Pytanie (tl; dr)

jestem w obliczu problemu przechodząc unicode String z osadzonym javax.swing.JApplet na stronie internetowej część Java Script. Nie jestem pewien, czy to jest błąd lub nieporozumienie z zaangażowanymi technologiach:

Problem

Chcę przekazać ciąg Unicode z Java aplet Java Script, ale String dostaje pomieszane. O dziwo, problem nie występuje w wersji Internet Explorer 10, ale w Chrome (v26) i Firefox (v20). Nie testowałem jednak innych przeglądarek.

Zwrócony łańcuch wydaje się być w porządku, z wyjątkiem ostatniego znaku Unicode. Wynik w Java Script Debugger i strony internetowej będzie:

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

Ciąg wydaje się uszkodzony w ostatnich bajtów. Jeśli kończy się znakiem ASCII, łańcuch jest w porządku. Ponadto problem nie występuje w każdej kombinacji, a także nie zawsze (nie jest to pewne). Dlatego podejrzewam błąd i obawiam się, że mogę opublikować nieprawidłowe pytanie.

Test Set Up

minimalistyczny set up zawiera aplet zwracającą trochę Unicode (UTF-8) ciągi:

/* 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. 
    } 
} 

Odpowiednia strona internetowa ze skryptu java mógłby wyglądać następująco:

/* 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> 

Środowisko

pracuję na Windows 7 32-bitowy z aktualną wersją Java 1.7.0_21 za pomocą "wtyczki Java nowej generacji 10.21.2 dla przeglądarek Mozilli". Miałem problemy z ustawieniami regionalnymi systemu operacyjnego, ale wypróbowałem kilka ustawień regionalnych (angielski, japoński, chiński).

W przypadku uszkodzonego łańcucha znaków String wyświetlane są nieprawidłowe znaki (np. ). Z drugiej strony, Firefox całkowicie upuszcza napis, jeśli kończy się na .

Eksplorator internetowy udaje się wyświetlić ciągi poprawnie.

Rozwiązania?

mogę sobie wyobrazić kilka obejścia, w tym ucieczce/unescaping i dodanie „ostatecznego char”, który następnie jest usuwany za pomocą skryptu java. Właściwie to zamierzam napisać przeciwko Webkitowi Androida i nie testowałem go tam.

Ponieważ chciałbym kontynuować badania w Chrome (ze względu na technologię Webkit i komfortu) Mam nadzieję, że to banalne rozwiązanie problemu, który mógłbym pominąć.

+2

Jestem zainteresowany tym, jaki jest prawdziwy problem. Jednym z pomysłów, które znalazłem jest: upewnij się, że 'javac' i/lub' jar' używa kodowania UTF8 - jeśli go nie określisz, użyje domyślnej maszyny (która * może * być problemem). – Ian

+1

Dzięki! Spróbuję tego później. Chcę zauważyć, że przepływ danych ze skryptu java do apletu (parametr wywołania) działa zgodnie z oczekiwaniami. Tylko zwrot zostaje zawalony. – Inuniku

+1

Absolutnie. Pokazałeś/wyjaśniłeś, że wszystko działa poprawnie, z wyjątkiem ciągu zwracanego w specjalnych przypadkach (ostatni znak w zwróconym łańcuchu ma znak Unicode). Myślę, że bardzo dobrze wytłumaczyłeś sytuację i wszystko układałeś w bardzo uporządkowany sposób :) – Ian

Odpowiedz

1

Jeśli testujesz w Chrome/Firefox

Proszę wymienić pierwszą linię z tym, a następnie przetestować go,

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

doctype ma znaczną wartość, gdy przeglądarka identyfikuje stronę.

Transitional/luźne to typy można używać z Unicode. Proszę sprawdzić i odpowiedzieć ..

+0

Dziękuję za twój wkład! Próbowałem tego, ale wciąż nie miałem szczęścia. – Inuniku

+0

Czy możesz opublikować html strony po wygenerowaniu strony/łącza strony (jeśli na żywo), które pomogą ci dalej. – MarmiK

1

Proponuję, aby ustawić punkt przerwania na

paragraphNode.innerHTML = text; 

i sprawdzić tekst to w konsoli JavaScript, np z

console.log(escape(text)); 

lub

console.log(encodeURIComponent(text)); 

lub

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)); 
} 

Patrz również

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

https://developer.mozilla.org/en-US/docs/DOM/window.escape (który nie jest częścią każdej Stan dard)

i

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

lub podobnych środków.

Pliki źródłowe mogą nie być w kodowaniu można zakładać (UTF-8).

JavaScript zakłada, UTF-16 struny:

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

Java zakłada również, UTF-16:

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

Komenda Linux lub Cygwin file może pokazać kodowanie plików .

Zobacz

http://linux.die.net/man/1/file (nie znalazłem kernel.org odniesienie MAN)

+0

Dziękuję bardzo za wyczerpującą odpowiedź! Dzięki funkcji 'encodeURI' udało mi się wyprowadzić ostateczne" uszkodzone "bajty w chrome: Wydaje się, że wszystkie kończą się na'% EF% BF% BD% EF% BF% BD% 00'. Nie jestem pewien, czy jest to prawdziwa cecha, ponieważ firefox nie pokazuje w ogóle uszkodzonego ciągu znaków (zwraca w tym przypadku ciąg o długości 0). Właściwie udało mi się rozwiązać problem dla mojego systemu operacyjnego (zobacz moją zawstydzającą odpowiedź). Ale nadal wpływa na inne ustawienia narodowe ... Być może pytanie pozostaje aktualne z modyfikacją. – Inuniku

0

Ok, jestem trochę zakłopotany, bo myślałem, że próbowałem go na tyle: ja rzeczywiście przy nie- latin locale (np.g Chiński (PRC) lub Japoński (Japonia) w systemie Windows locale settings. Po zmianie z powrotem na angielski (USA) lub niemiecki (Niemcy) wszystko działało jak oczekiwano.

Ciągle się zastanawiam, dlaczego wpłynęłoby to na Mozilla w tak dziwny sposób, ponieważ Java i nowoczesne przeglądarki powinny być oparte na Unicode; Więc nie przyjmuję tego jako odpowiedzi! Problem powtarza się po przełączeniu z powrotem na japoński i mam zamiar przetestować go na różnych systemach.

Chciałbym podziękować za wszystkie plakaty za wkład w oświecenie ... i nadal będę starał się rozwiązać to pytanie.

1

Musisz upewnić się, aby dodać następujący argument Java aplet/znacznika embed:

-Dfile.encoding = UTF-8

tj java_arguments = "- Dfile.encoding = UTF-8 "

W przeciwnym razie będzie oczekiwać i potraktować aplet jako tekst ASCII.

Powiązane problemy