Некоторый псевдокод:
String a = "A bunch of text"; //UTF-16
saveTextInDb(a); //Write to Oracle VARCHAR(15) column
String b = readTextFromDb(); //UTF-16
out.write(b); //Write to http response
Когда Вы сохраняете Java String
(UTF-16) к Oracle VARCHAR (15) Oracle также хранит это как UTF-16? Длина VARCHAR Oracle относятся к количеству символов Unicode (и не числу байтов)?
Когда мы пишем b
к ServletResponse
это записало как UTF-16 или является нами преобразованием значения по умолчанию в другое кодирование как UTF-8?
Вместо UTF-16 подумайте "внутреннего представления" вашей строки. Строка в Java - это своего рода символы, вам все равно, какая кодировка используется внутри. Кодирование становится актуальным, если вы взаимодействуете с внешним миром программы. В вашем примере saveTextInDb, readTextFromDb и write делают это. Каждый раз, когда вы обмениваетесь строками с внешним миром, используется кодировка для преобразования. saveTextInDb (и читать) выглядят как самодельные методы, по крайней мере, я их не знаю. Поэтому вам следует посмотреть, какая кодировка используется для этих методов. Метод write модуля записи всегда создает байты, которые представляют кодировку, связанную с модулем записи. Если вы получаете свой Writer из HttpServletResponse, связанная кодировка используется для вывода ответа (который будет отправлен в заголовках).
response.setEncoding("UTF-8");
Writer out = response.getWriter();
Этот код возвращается без Writer, который переводит строки в кодировку UTF-8. Аналогично, если вы пишете в файл:
Writer fileout = new OutputStreamWriter(new FileOutputStream(myfile), "ISO8859-1");
Если вы обращаетесь к базе данных, используемая вами структура должна обеспечивать согласованный обмен строками с базой данных.
ServletResponse
по умолчанию будет использовать ISO 8859-1 (Latin 1). UTF-8 - это наиболее распространенная кодировка, используемая для HTTP-ответов, требующих Unicode, но вы должны установить эту кодировку специально.
Согласно этот документ Oracle может поддерживать UTF-8 или UTF-16 в базе данных. Ваши методы, которые читают / записывают Oracle, должны будут использовать соответствующую кодировку, которая соответствует настройке базы данных, и переводить ее во внутреннее представление Java или из него.
Возможность Oracle сохранять (и позже извлекать) текст Unicode из базы данных зависит только от набора символов базы данных (обычно указывается при создании базы данных) . Выбор AL32UTF8 в качестве набора символов рекомендуется для хранения текста Unicode в типах данных CHAR (включая VARCHAR / VARCHAR2), поскольку это позволит вам получить доступ ко всем кодовым точкам Unicode, не занимая много места для хранения по сравнению с другими кодировками, такими как AL16UTF16 / AL32UTF32.
Если это сделано, то именно драйвер Oracle JDBC отвечает за преобразование данных в кодировке UTF-16 в AL32UTF8.Это «автоматическое» преобразование между кодировками также происходит при чтении данных из базы данных. Чтобы ответить на запрос о длине байта VARCHAR, определение столбца VARCHAR2 в Oracle включает семантику байтов - VARCHAR2 (n) используется для определения столбца, который может хранить n байтов (это поведение по умолчанию, как указано параметром NLS_LENGTH_SEMANTICS базы данных); если вам нужно определить размер на основе символов, следует использовать VARCHAR2 (n CHAR).
Кодировка данных, записываемых в объект ServletResponse, зависит от кодировки символов по умолчанию, если это не указано через ServletResponse.setCharacterEncoding () или ServletResponse.setContentType () Вызовы API. В общем, для полного решения Unicode, включающего базу данных Oracle, необходимо знать
ServletRequest.getParameter
или аналогичные методы, которые будут обрабатывать поток и возвращать объекты String. В результате декодирования будут созданы символы в кодировке платформы (это UTF-16). Кодирование данных, считываемых из потоков, в отличие от данных, созданных с помощью JVM. Это очень важно, поскольку кодировку данных, считываемых из потоков, изменить нельзя. Однако существует процесс декодирования, который преобразует символы в поддерживаемых кодировках в символы UTF-16 всякий раз, когда к таким данным обращаются как к символьному примитиву или как к строке. С другой стороны, новые объекты String могут быть созданы с определенной кодировкой. Это имеет значение, когда вы записываете содержимое потока в другой поток (например, выходной поток объекта HttpServletResponse). Если содержимое входного потока обрабатывается как последовательность байтов, а не как символы или строки, тогда JVM не будет выполнять никаких операций декодирования. Это означало бы, что байты, записанные в выходной поток, не должны изменяться, если не созданы промежуточный символ или объекты String. В противном случае вполне возможно, что содержимое выходного потока будет искажено и неправильно проанализировано соответствующим декодером.Проще говоря,
resultSet.getString ()
, драйвер JDBC возвращает строку с символами UTF-16. Обратное верно, когда вы также отправляете данные в базу данных. Если используется другой набор символов базы данных, дополнительный уровень преобразования (из UTF-16 в UTF-8 в набор символов базы данных) выполняется прозрачно драйвером JDBC.